use crate::parser::AttributeMap;
use roxmltree::Node;
use rustc_hash::FxHashMap;
pub type Styles = FxHashMap<String, StyleMap>;
pub type StyleMap = FxHashMap<String, String>;
pub fn parse_styles(root: &Node) -> Styles {
let mut styles = FxHashMap::with_capacity_and_hasher(1, Default::default());
for child in root.children().filter(|n| n.is_element()) {
debug_assert!(
child.has_tag_name("Style"),
"Every node inside <Styles></Styles> must be a <Style> element"
);
let name = child
.attribute("name")
.expect("<Style> element must have a name attribute")
.to_string();
styles.insert(name, parse_style(&child));
}
styles
}
pub fn parse_style(node: &Node) -> StyleMap {
let mut attrs = StyleMap::with_capacity_and_hasher(1, Default::default());
for attr in node.attributes() {
attrs.insert(attr.name().to_string(), attr.value().to_string());
}
attrs
}
pub fn fetch_style_attrs(node: &Node, styles: &Styles) -> Result<AttributeMap, String> {
if let Some(names) = node.attribute("styles").map(|s| s.split(" ")) {
let mut attrs = AttributeMap::with_capacity_and_hasher(1, Default::default());
for name in names {
let style = styles
.get(name)
.ok_or_else(|| format!("Style '{}' not found", name))?;
attrs.extend(style.clone());
}
Ok(attrs)
} else {
Ok(AttributeMap::default())
}
}