aboutsummaryrefslogtreecommitdiff
path: root/src/attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/attr.rs')
-rw-r--r--src/attr.rs208
1 files changed, 0 insertions, 208 deletions
diff --git a/src/attr.rs b/src/attr.rs
deleted file mode 100644
index 096235e..0000000
--- a/src/attr.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-//! Types for HTML attributes.
-
-use std::collections::{btree_map, BTreeMap};
-use std::iter::FromIterator;
-use std::ops::{Index, Range};
-
-use crate::offset::Offset;
-
-/// A map of HTML attributes.
-///
-/// Does not preserve the order of attributes.
-/// Iterating always yields attributes in order by name.
-///
-/// # Example
-///
-/// ```
-/// # use html5tokenizer::attr::AttributeMap;
-/// let attrs: AttributeMap<()> = vec![("href".into(), "http://example.com".into())]
-/// .into_iter()
-/// .collect();
-/// assert_eq!(&attrs["href"], "http://example.com");
-/// ```
-#[derive(Debug, Default, PartialEq, Eq)]
-pub struct AttributeMap<O> {
- pub(crate) inner: BTreeMap<String, AttrInternal<O>>,
-}
-
-/// The value type internally used by the [`AttributeMap`].
-/// Not part of the public API.
-#[derive(Debug, Eq, PartialEq)]
-pub(crate) struct AttrInternal<O> {
- pub value: String,
- /// The span of the attribute name.
- pub name_span: Range<O>,
- /// The span of the attribute value.
- /// For the empty attribute syntax this is just `O::default()..O::default()`.
- /// We intentionally don't use `Option<Range<O>>` here to spare us a byte (and padding) per attribute.
- pub value_span: Range<O>,
- pub value_syntax: Option<AttrValueSyntax>,
-}
-
-/// The syntax of the attribute value.
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum AttrValueSyntax {
- /// An unquoted attribute value, e.g. `id=foo`.
- Unquoted,
- /// A single-quoted attribute value, e.g. `id='foo'`.
- SingleQuoted,
- /// A double-quoted attribute value, e.g. `id="foo"`.
- DoubleQuoted,
-}
-
-/// An HTML attribute borrowed from an [`AttributeMap`].
-#[derive(Debug, Eq, PartialEq)]
-pub struct Attribute<'a, O> {
- name: &'a str,
- map_val: &'a AttrInternal<O>,
-}
-
-/// An owned HTML attribute.
-#[derive(Debug, PartialEq, Eq)]
-pub struct AttributeOwned<O> {
- /// The attribute name.
- /// Uppercase ASCII characters (A-Z) have been converted to lowercase.
- pub name: String,
- /// The attribute value. Character references have been resolved.
- pub value: String,
- /// The span of the attribute name.
- pub name_span: Range<O>,
- /// The span of the attribute value.
- /// `None` in case of the empty attribute syntax (e.g. `disabled` in `<input disabled>`).
- pub value_span: Option<Range<O>>,
- /// The syntax of the attribute value.
- /// `None` indicates the empty attribute syntax (e.g. `disabled` in `<input disabled>`).
- pub value_syntax: Option<AttrValueSyntax>,
-}
-
-impl<O> AttributeMap<O> {
- /// Returns the attribute with the given name.
- ///
- /// The name must not contain any uppercase ASCII character (A-Z)
- /// or the method will always return `None`.
- pub fn get(&self, name: &str) -> Option<Attribute<O>> {
- self.inner
- .get_key_value(name)
- .map(|(name, map_val)| Attribute { name, map_val })
- }
-}
-
-impl<'a, O: Offset> Attribute<'a, O> {
- /// Returns the attribute name.
- /// Uppercase ASCII characters (A-Z) have been converted to lowercase.
- pub fn name(&self) -> &'a str {
- self.name
- }
-
- /// Returns the attribute value. Character references have been resolved.
- pub fn value(&self) -> &'a str {
- &self.map_val.value
- }
-
- /// Returns the span of the attribute name.
- pub fn name_span(&self) -> Range<O> {
- self.map_val.name_span.clone()
- }
-
- /// For explicitly defined values returns the span of the attribute value.
- ///
- /// Returns `None` for attributes using the empty attribute syntax (e.g. `disabled` in `<input disabled>`).
- pub fn value_span(&self) -> Option<Range<O>> {
- if self.map_val.value_syntax.is_none() {
- return None;
- }
- Some(self.map_val.value_span.clone())
- }
-
- /// Returns the attribute value syntax in case the value is explicitly defined.
- ///
- /// Returns `None` for attributes using the empty attribute syntax (e.g. `disabled` in `<input disabled>`).
- pub fn value_syntax(&self) -> Option<AttrValueSyntax> {
- self.map_val.value_syntax
- }
-}
-
-// We cannot impl Index<Output=Attribute> because Index::index returns a reference of
-// the Output type (and you cannot return a value referencing a temporary value).
-impl<O> Index<&str> for AttributeMap<O> {
- type Output = str;
-
- /// Returns the attribute value with the given name.
- ///
- /// The name must not contain any uppercase ASCII character (A-Z)
- /// or the method will always panic.
- fn index(&self, name: &str) -> &Self::Output {
- &self.inner[name].value
- }
-}
-
-impl<O> IntoIterator for AttributeMap<O> {
- type Item = AttributeOwned<O>;
-
- type IntoIter = AttrIntoIter<O>;
-
- fn into_iter(self) -> Self::IntoIter {
- AttrIntoIter(self.inner.into_iter())
- }
-}
-
-/// A consuming iterator over the attributes of an [`AttributeMap`].
-pub struct AttrIntoIter<O>(btree_map::IntoIter<String, AttrInternal<O>>);
-
-impl<O> Iterator for AttrIntoIter<O> {
- type Item = AttributeOwned<O>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let (name, map_val) = self.0.next()?;
- Some(AttributeOwned {
- name,
- value: map_val.value,
- name_span: map_val.name_span,
- value_span: map_val.value_syntax.is_some().then_some(map_val.value_span),
- value_syntax: map_val.value_syntax,
- })
- }
-}
-
-impl<'a, O> IntoIterator for &'a AttributeMap<O> {
- type Item = Attribute<'a, O>;
-
- type IntoIter = AttrIter<'a, O>;
-
- fn into_iter(self) -> Self::IntoIter {
- AttrIter(self.inner.iter())
- }
-}
-
-/// A borrowed iterator over the attributes of an [`AttributeMap`].
-pub struct AttrIter<'a, S>(btree_map::Iter<'a, String, AttrInternal<S>>);
-
-impl<'a, S> Iterator for AttrIter<'a, S> {
- type Item = Attribute<'a, S>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let (name, map_val) = self.0.next()?;
- Some(Attribute { name, map_val })
- }
-}
-
-impl<O: Default> FromIterator<(String, String)> for AttributeMap<O> {
- fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
- Self {
- inner: iter
- .into_iter()
- .map(|(name, value)| {
- (
- name,
- AttrInternal {
- value,
- name_span: O::default()..O::default(),
- value_span: O::default()..O::default(),
- value_syntax: Some(AttrValueSyntax::DoubleQuoted),
- },
- )
- })
- .collect(),
- }
- }
-}