pub use attribute::Attribute;
pub use element::Element;
use std::fmt::Debug;
pub(crate) mod attribute;
mod element;
#[derive(Clone, Debug, PartialEq)]
pub enum Node<NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
Element(Element<NS, TAG, LEAF, ATT, VAL>),
Leaf(LEAF),
}
impl<NS, TAG, LEAF, ATT, VAL> Node<NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
pub fn take_element(self) -> Option<Element<NS, TAG, LEAF, ATT, VAL>> {
match self {
Node::Element(element) => Some(element),
_ => None,
}
}
pub fn as_element_mut(
&mut self,
) -> Option<&mut Element<NS, TAG, LEAF, ATT, VAL>> {
match *self {
Node::Element(ref mut element) => Some(element),
_ => None,
}
}
pub fn as_element_ref(&self) -> Option<&Element<NS, TAG, LEAF, ATT, VAL>> {
match *self {
Node::Element(ref element) => Some(element),
_ => None,
}
}
pub fn add_children(
mut self,
children: impl IntoIterator<Item = Node<NS, TAG, LEAF, ATT, VAL>>,
) -> Self {
if let Some(element) = self.as_element_mut() {
element.add_children(children);
} else {
panic!("Can not add children to a text node");
}
self
}
pub fn add_children_ref_mut(
&mut self,
children: impl IntoIterator<Item = Node<NS, TAG, LEAF, ATT, VAL>>,
) {
if let Some(element) = self.as_element_mut() {
element.add_children(children);
} else {
panic!("Can not add children to a text node");
}
}
pub fn add_attributes(
mut self,
attributes: impl IntoIterator<Item = Attribute<NS, ATT, VAL>>,
) -> Self {
if let Some(elm) = self.as_element_mut() {
elm.add_attributes(attributes);
} else {
panic!("Can not add attributes to a text node");
}
self
}
pub fn add_attributes_ref_mut(
&mut self,
attributes: impl IntoIterator<Item = Attribute<NS, ATT, VAL>>,
) {
if let Some(elm) = self.as_element_mut() {
elm.add_attributes(attributes);
} else {
panic!("Can not add attributes to a text node");
}
}
pub fn get_attributes(&self) -> Option<&[Attribute<NS, ATT, VAL>]> {
match *self {
Node::Element(ref element) => Some(element.get_attributes()),
_ => None,
}
}
pub fn tag(&self) -> Option<&TAG> {
if let Some(e) = self.as_element_ref() {
Some(&e.tag)
} else {
None
}
}
pub fn get_children(&self) -> Option<&[Node<NS, TAG, LEAF, ATT, VAL>]> {
if let Some(element) = self.as_element_ref() {
Some(element.get_children())
} else {
None
}
}
pub fn get_children_count(&self) -> usize {
if let Some(children) = self.get_children() {
children.len()
} else {
0
}
}
pub fn children_mut(
&mut self,
) -> Option<&mut [Node<NS, TAG, LEAF, ATT, VAL>]> {
if let Some(element) = self.as_element_mut() {
Some(element.children_mut())
} else {
None
}
}
pub fn swap_remove_child(
&mut self,
index: usize,
) -> Node<NS, TAG, LEAF, ATT, VAL> {
match self {
Node::Element(element) => element.swap_remove_child(index),
_ => panic!("text has no child"),
}
}
pub fn swap_children(&mut self, a: usize, b: usize) {
match self {
Node::Element(element) => element.swap_children(a, b),
_ => panic!("text has no child"),
}
}
pub fn node_count(&self) -> usize {
1 + self.descendant_node_count()
}
pub fn descendant_node_count(&self) -> usize {
let mut cnt = 0;
match self {
Node::Element(element) => {
for child in element.children.iter() {
cnt += child.node_count();
}
}
_ => (),
}
cnt
}
pub fn set_attributes_ref_mut(
&mut self,
attributes: impl IntoIterator<Item = Attribute<NS, ATT, VAL>>,
) {
if let Some(elm) = self.as_element_mut() {
elm.set_attributes(attributes);
}
}
pub fn merge_attributes(
mut self,
attributes: impl IntoIterator<Item = Attribute<NS, ATT, VAL>>,
) -> Self {
if let Some(elm) = self.as_element_mut() {
elm.merge_attributes(attributes);
}
self
}
pub fn get_attribute_value(&self, name: &ATT) -> Option<Vec<&VAL>> {
if let Some(elm) = self.as_element_ref() {
elm.get_attribute_value(name)
} else {
None
}
}
}
#[inline]
pub fn element<NS, TAG, LEAF, ATT, VAL>(
tag: TAG,
attrs: impl IntoIterator<Item = Attribute<NS, ATT, VAL>>,
children: impl IntoIterator<Item = Node<NS, TAG, LEAF, ATT, VAL>>,
) -> Node<NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
element_ns(None, tag, attrs, children, false)
}
pub fn element_ns<NS, TAG, LEAF, ATT, VAL>(
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,
) -> Node<NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
Node::Element(Element::new(namespace, tag, attrs, children, self_closing))
}
pub fn leaf<NS, TAG, LEAF, ATT, VAL>(
leaf: LEAF,
) -> Node<NS, TAG, LEAF, ATT, VAL>
where
NS: PartialEq + Clone + Debug,
TAG: PartialEq + Clone + Debug,
LEAF: PartialEq + Clone + Debug,
ATT: PartialEq + Clone + Debug,
VAL: PartialEq + Clone + Debug,
{
Node::Leaf(leaf)
}