1use crate::{Arena, Node, NodeId};
4
5macro_rules! impl_node_iterator {
6 ($name:ident, $next:expr) => {
7 impl<'a, T> Iterator for $name<'a, T> {
8 type Item = NodeId;
9
10 fn next(&mut self) -> Option<NodeId> {
11 let node = self.node.take()?;
12 self.node = $next(&self.arena[node]);
13 Some(node)
14 }
15 }
16 };
17}
18
19#[derive(Clone)]
20pub struct Ancestors<'a, T> {
22 arena: &'a Arena<T>,
23 node: Option<NodeId>,
24}
25impl_node_iterator!(Ancestors, |node: &Node<T>| node.parent);
26
27impl<'a, T> Ancestors<'a, T> {
28 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
29 Self {
30 arena,
31 node: Some(current),
32 }
33 }
34}
35
36#[derive(Clone)]
37pub struct PrecedingSiblings<'a, T> {
39 arena: &'a Arena<T>,
40 node: Option<NodeId>,
41}
42impl_node_iterator!(PrecedingSiblings, |node: &Node<T>| node.previous_sibling);
43
44impl<'a, T> PrecedingSiblings<'a, T> {
45 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
46 Self {
47 arena,
48 node: Some(current),
49 }
50 }
51}
52
53#[derive(Clone)]
54pub struct FollowingSiblings<'a, T> {
56 arena: &'a Arena<T>,
57 node: Option<NodeId>,
58}
59impl_node_iterator!(FollowingSiblings, |node: &Node<T>| node.next_sibling);
60
61impl<'a, T> FollowingSiblings<'a, T> {
62 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
63 Self {
64 arena,
65 node: Some(current),
66 }
67 }
68}
69
70#[derive(Clone)]
71pub struct Children<'a, T> {
73 arena: &'a Arena<T>,
74 node: Option<NodeId>,
75}
76impl_node_iterator!(Children, |node: &Node<T>| node.next_sibling);
77
78impl<'a, T> Children<'a, T> {
79 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
80 Self {
81 arena,
82 node: arena[current].first_child,
83 }
84 }
85}
86
87#[derive(Clone)]
88pub struct ReverseChildren<'a, T> {
90 arena: &'a Arena<T>,
91 node: Option<NodeId>,
92}
93impl_node_iterator!(ReverseChildren, |node: &Node<T>| node.previous_sibling);
94
95impl<'a, T> ReverseChildren<'a, T> {
96 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
97 Self {
98 arena,
99 node: arena[current].last_child,
100 }
101 }
102}
103
104#[derive(Clone)]
105pub struct Descendants<'a, T>(Traverse<'a, T>);
109
110impl<'a, T> Descendants<'a, T> {
111 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
112 Self(Traverse::new(arena, current))
113 }
114}
115
116impl<'a, T> Iterator for Descendants<'a, T> {
117 type Item = NodeId;
118
119 fn next(&mut self) -> Option<NodeId> {
120 self.0.find_map(|edge| match edge {
121 NodeEdge::Start(node) => Some(node),
122 NodeEdge::End(_) => None,
123 })
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
128pub enum NodeEdge {
130 Start(NodeId),
135
136 End(NodeId),
141}
142
143#[derive(Clone)]
144pub struct Traverse<'a, T> {
149 arena: &'a Arena<T>,
150 root: NodeId,
151 next: Option<NodeEdge>,
152}
153
154impl<'a, T> Traverse<'a, T> {
155 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
156 Self {
157 arena,
158 root: current,
159 next: Some(NodeEdge::Start(current)),
160 }
161 }
162
163 fn next_of_next(&self, next: NodeEdge) -> Option<NodeEdge> {
165 match next {
166 NodeEdge::Start(node) => match self.arena[node].first_child {
167 Some(first_child) => Some(NodeEdge::Start(first_child)),
168 None => Some(NodeEdge::End(node)),
169 },
170 NodeEdge::End(node) => {
171 if node == self.root {
172 return None;
173 }
174 let node = &self.arena[node];
175 match node.next_sibling {
176 Some(next_sibling) => Some(NodeEdge::Start(next_sibling)),
177 None => node.parent.map(NodeEdge::End),
181 }
182 }
183 }
184 }
185}
186
187impl<'a, T> Iterator for Traverse<'a, T> {
188 type Item = NodeEdge;
189
190 fn next(&mut self) -> Option<NodeEdge> {
191 let next = self.next.take()?;
192 self.next = self.next_of_next(next);
193 Some(next)
194 }
195}
196
197#[derive(Clone)]
198pub struct ReverseTraverse<'a, T> {
203 arena: &'a Arena<T>,
204 root: NodeId,
205 next: Option<NodeEdge>,
206}
207
208impl<'a, T> ReverseTraverse<'a, T> {
209 pub(crate) fn new(arena: &'a Arena<T>, current: NodeId) -> Self {
210 Self {
211 arena,
212 root: current,
213 next: Some(NodeEdge::End(current)),
214 }
215 }
216
217 fn next_of_next(&self, next: NodeEdge) -> Option<NodeEdge> {
219 match next {
220 NodeEdge::End(node) => match self.arena[node].last_child {
221 Some(last_child) => Some(NodeEdge::End(last_child)),
222 None => Some(NodeEdge::Start(node)),
223 },
224 NodeEdge::Start(node) => {
225 if node == self.root {
226 return None;
227 }
228 let node = &self.arena[node];
229 match node.previous_sibling {
230 Some(previous_sibling) => Some(NodeEdge::End(previous_sibling)),
231 None => node.parent.map(NodeEdge::Start),
235 }
236 }
237 }
238 }
239}
240
241impl<'a, T> Iterator for ReverseTraverse<'a, T> {
242 type Item = NodeEdge;
243
244 fn next(&mut self) -> Option<NodeEdge> {
245 let next = self.next.take()?;
246 self.next = self.next_of_next(next);
247 Some(next)
248 }
249}