use crate::xmlvalue::{Attribute, Value, ValueCategory};
use crate::{NameId, Node, Xot};
use super::core::{category_predicate, MutableNodeMap, NodeMap, ValueAdapter};
pub struct AttributeAdapter {}
impl ValueAdapter<NameId, String> for AttributeAdapter {
fn matches(value: &Value) -> bool {
matches!(value, Value::Attribute(_))
}
fn children(xot: &Xot, node: Node) -> impl Iterator<Item = Node> + '_ {
xot.all_children(node)
.skip_while(category_predicate(xot, ValueCategory::Namespace))
.take_while(category_predicate(xot, ValueCategory::Attribute))
}
fn insertion_point(xot: &Xot, node: Node) -> Option<Node> {
let last_child = Self::children(xot, node).last();
if let Some(last_child) = last_child {
return Some(last_child);
}
let namespaces = xot
.all_children(node)
.take_while(category_predicate(xot, ValueCategory::Namespace));
if let Some(last_namespace) = namespaces.last() {
return Some(last_namespace);
}
None
}
fn key(value: &Value) -> NameId {
match value {
Value::Attribute(Attribute { name_id, .. }) => *name_id,
_ => unreachable!(),
}
}
fn value(value: &Value) -> &String {
match value {
Value::Attribute(Attribute { value, .. }) => value,
_ => unreachable!(),
}
}
fn value_mut(value: &mut Value) -> &mut String {
match value {
Value::Attribute(Attribute { value, .. }) => value,
_ => unreachable!(),
}
}
fn create(key: NameId, value: String) -> Value {
Value::Attribute(Attribute {
name_id: key,
value,
})
}
fn update(value: &mut Value, new_value: String) -> Option<String> {
match value {
Value::Attribute(Attribute {
value: old_value, ..
}) => {
let old_value = std::mem::replace(old_value, new_value);
Some(old_value)
}
_ => unreachable!(),
}
}
}
pub type Attributes<'a> = NodeMap<'a, NameId, String, AttributeAdapter>;
pub type MutableAttributes<'a> = MutableNodeMap<'a, NameId, String, AttributeAdapter>;