1use super::element::Element;
2use serde::Serialize;
3
4#[derive(Debug, Clone, Serialize, PartialEq)]
5#[serde(untagged)]
6pub enum Node {
7 Text(String),
8 Element(Element),
9 Comment(String),
10}
11
12impl Node {
13 pub fn text(&self) -> Option<&str> {
14 match self {
15 Node::Text(t) => Some(t.as_str()),
16 _ => None,
17 }
18 }
19
20 pub fn element(&self) -> Option<&Element> {
21 match self {
22 Node::Element(e) => Some(e),
23 _ => None,
24 }
25 }
26
27 pub fn comment(&self) -> Option<&str> {
28 match self {
29 Node::Comment(t) => Some(t.as_str()),
30 _ => None,
31 }
32 }
33}
34
35impl<'a> IntoIterator for &'a Node {
36 type Item = &'a Node;
37 type IntoIter = NodeIntoIterator<'a>;
38
39 fn into_iter(self) -> Self::IntoIter {
40 NodeIntoIterator {
41 node: self,
42 index: vec![],
43 }
44 }
45}
46
47pub struct NodeIntoIterator<'a> {
48 node: &'a Node,
49 index: Vec<(usize, &'a Node)>,
51}
52
53impl<'a> Iterator for NodeIntoIterator<'a> {
54 type Item = &'a Node;
55
56 fn next(&mut self) -> Option<Self::Item> {
57 let child = match self.node {
59 Node::Element(ref e) => e.children.get(0),
60 _ => None,
61 };
62
63 let result = match child {
64 Some(child) => {
66 self.index.push((0, self.node));
67 self.node = child;
68 Some(child)
69 }
70 None if self.index.len() > 0 => {
72 let mut has_finished = false;
73 let mut next_node = None;
74
75 while !has_finished {
76 if let Some((sibling_index, parent)) = self.index.pop() {
78 let next_sibling = sibling_index + 1;
79 let sibling = if let Node::Element(ref e) = parent {
80 e.children.get(next_sibling)
81 } else {
82 None
83 };
84 if sibling.is_some() {
85 has_finished = true;
86 self.index.push((next_sibling, parent));
87 next_node = sibling;
88 } else {
89 continue;
90 }
91 } else {
93 has_finished = true;
94 }
95 }
96
97 if let Some(next_node) = next_node {
98 self.node = next_node;
99 }
100
101 next_node
102 }
103 _ => None,
104 };
105
106 result
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn node_utillity_functions() {
116 let node = Node::Text("test".to_string());
117
118 assert_eq!(node.text(), Some("test"));
119 assert_eq!(node.element(), None);
120 assert_eq!(node.comment(), None);
121
122 let node = Node::Element(Element::default());
123
124 assert_eq!(node.text(), None);
125 assert_eq!(node.element(), Some(&Element::default()));
126 assert_eq!(node.comment(), None);
127
128 let node = Node::Comment("test".to_string());
129
130 assert_eq!(node.text(), None);
131 assert_eq!(node.element(), None);
132 assert_eq!(node.comment(), Some("test"));
133 }
134}