use html5ever::{LocalName, Namespace, Prefix}; use indexmap::{map::Entry, IndexMap}; /// Convenience wrapper around a indexmap that adds method for attributes in the null namespace. #[derive(Debug, PartialEq, Clone)] pub struct Attributes { /// A map of attributes whose name can have namespaces. pub map: IndexMap, } /// #[derive(Debug, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] pub struct ExpandedName { /// Namespace URL pub ns: Namespace, /// "Local" part of the name pub local: LocalName, } impl ExpandedName { /// Trivial constructor pub fn new, L: Into>(ns: N, local: L) -> Self { ExpandedName { ns: ns.into(), local: local.into(), } } } /// The non-identifying parts of an attribute #[derive(Debug, PartialEq, Clone)] pub struct Attribute { /// The namespace prefix, if any pub prefix: Option, /// The attribute value pub value: String, } impl Attributes { /// Like IndexMap::contains pub fn contains>(&self, local_name: A) -> bool { self.map.contains_key(&ExpandedName::new(ns!(), local_name)) } /// Like IndexMap::get pub fn get>(&self, local_name: A) -> Option<&str> { self.map .get(&ExpandedName::new(ns!(), local_name)) .map(|attr| &*attr.value) } /// Like IndexMap::get_mut pub fn get_mut>(&mut self, local_name: A) -> Option<&mut String> { self.map .get_mut(&ExpandedName::new(ns!(), local_name)) .map(|attr| &mut attr.value) } /// Like IndexMap::entry pub fn entry>(&mut self, local_name: A) -> Entry { self.map.entry(ExpandedName::new(ns!(), local_name)) } /// Like IndexMap::insert pub fn insert>( &mut self, local_name: A, value: String, ) -> Option { self.map.insert( ExpandedName::new(ns!(), local_name), Attribute { prefix: None, value, }, ) } /// Like IndexMap::remove pub fn remove>(&mut self, local_name: A) -> Option { self.map.remove(&ExpandedName::new(ns!(), local_name)) } }