//! 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 {
pub(crate) inner: BTreeMap>,
}
/// The value type internally used by the [`AttributeMap`].
/// Not part of the public API.
#[derive(Debug, Eq, PartialEq)]
pub(crate) struct AttrInternal {
pub value: String,
pub name_span: Range,
pub value_span: Range,
}
/// An HTML attribute borrowed from an [`AttributeMap`].
#[derive(Debug, Eq, PartialEq)]
pub struct Attribute<'a, O> {
name: &'a str,
map_val: &'a AttrInternal,
}
/// An owned HTML attribute.
#[derive(Debug, PartialEq, Eq)]
pub struct AttributeOwned {
/// The attribute name.
pub name: String,
/// The attribute value.
pub value: String,
/// The start offset of the attribute name.
pub name_offset: O,
/// The start offset of the attribute value.
pub value_offset: O, // TODO: wrap this in an Option once we can recognize the empty attribute syntax
}
impl AttributeMap {
/// Returns the attribute with the given name.
pub fn get(&self, name: &str) -> Option> {
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.
pub fn name(&self) -> &'a str {
self.name
}
/// Returns the attribute value.
pub fn value(&self) -> &'a str {
&self.map_val.value
}
/// Returns the span of the attribute name.
pub fn name_span(&self) -> Range {
self.map_val.name_span.clone()
}
/// Returns the span of the attribute value.
pub fn value_span(&self) -> Range {
self.map_val.value_span.clone()
}
}
// We cannot impl Index