use crate::node::{Attribute, Node};
use alloc::vec;
use alloc::vec::Vec;
use core::fmt::Debug;
#[derive(Clone, Debug, PartialEq, Default)]
pub struct Element<Ns, Tag, Leaf, Att, Val>
where
Ns: PartialEq + Clone + Debug,
Tag: PartialEq + Debug,
Leaf: PartialEq + Clone + Debug,
Att: PartialEq + Clone + Debug,
Val: PartialEq + Clone + Debug,
{
pub namespace: Option<Ns>,
pub tag: Tag,
pub attrs: Vec<Attribute<Ns, Att, Val>>,
pub children: Vec<Node<Ns, Tag, Leaf, Att, Val>>,
pub self_closing: bool,
}
impl<Ns, Tag, Leaf, Att, Val> Element<Ns, Tag, Leaf, Att, Val>
where
Ns: PartialEq + Clone + Debug,
Tag: PartialEq + Debug,
Leaf: PartialEq + Clone + Debug,
Att: PartialEq + Clone + Debug,
Val: PartialEq + Clone + Debug,
{
pub fn new(
namespace: Option<Ns>,
tag: Tag,
attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
self_closing: bool,
) -> Self {
let children = children
.into_iter()
.flat_map(|child| match child {
Node::NodeList(node_list) => node_list,
_ => vec![child],
})
.collect();
Self {
namespace,
tag,
attrs: attrs.into_iter().collect(),
children,
self_closing,
}
}
pub fn add_attributes(
&mut self,
attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
) {
self.attrs.extend(attrs)
}
pub fn add_children(
&mut self,
children: impl IntoIterator<Item = Node<Ns, Tag, Leaf, Att, Val>>,
) {
self.children.extend(children.into_iter());
}
pub fn children(&self) -> &[Node<Ns, Tag, Leaf, Att, Val>] {
&self.children
}
pub fn children_mut(&mut self) -> &mut [Node<Ns, Tag, Leaf, Att, Val>] {
&mut self.children
}
pub fn swap_remove_child(
&mut self,
index: usize,
) -> Node<Ns, Tag, Leaf, Att, Val> {
self.children.swap_remove(index)
}
pub fn swap_children(&mut self, a: usize, b: usize) {
self.children.swap(a, b)
}
pub fn take_children(self) -> Vec<Node<Ns, Tag, Leaf, Att, Val>> {
self.children
}
pub fn attributes(&self) -> &[Attribute<Ns, Att, Val>] {
&self.attrs
}
pub fn take_attributes(self) -> Vec<Attribute<Ns, Att, Val>> {
self.attrs
}
pub fn namespace(&self) -> Option<&Ns> {
self.namespace.as_ref()
}
pub fn tag(&self) -> &Tag {
&self.tag
}
pub fn take_tag(self) -> Tag {
self.tag
}
pub fn set_tag(&mut self, tag: Tag) {
self.tag = tag;
}
pub fn remove_attribute(&mut self, key: &Att) {
self.attrs.retain(|att| att.name != *key)
}
pub fn set_attributes(
&mut self,
attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
) {
for attr in attrs {
self.remove_attribute(&attr.name);
self.attrs.push(attr);
}
}
pub fn merge_attributes(
&mut self,
new_attrs: impl IntoIterator<Item = Attribute<Ns, Att, Val>>,
) {
for new_att in new_attrs {
if let Some(existing_attr) =
self.attrs.iter_mut().find(|att| att.name == new_att.name)
{
existing_attr.value.extend(new_att.value);
} else {
self.attrs.push(new_att);
}
}
}
pub fn attribute_value(&self, name: &Att) -> Option<Vec<&Val>> {
let result: Vec<&Val> = self
.attrs
.iter()
.filter(|att| att.name == *name)
.flat_map(|att| att.value())
.collect();
if result.is_empty() {
None
} else {
Some(result)
}
}
}