generational_indextree/
traverse.rs

1//! Iterators.
2
3use 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)]
20/// An iterator of the IDs of the ancestors a given node.
21pub 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)]
37/// An iterator of the IDs of the siblings before a given node.
38pub 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)]
54/// An iterator of the IDs of the siblings after a given node.
55pub 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)]
71/// An iterator of the IDs of the children of a given node, in insertion order.
72pub 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)]
88/// An iterator of the IDs of the children of a given node, in reverse insertion order.
89pub 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)]
105/// An iterator of the IDs of a given node and its descendants, as a pre-order depth-first search where children are visited in insertion order.
106///
107/// i.e. node -> first child -> second child
108pub 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)]
128/// Indicator if the node is at a start or endpoint of the tree
129pub enum NodeEdge {
130    /// Indicates that start of a node that has children.
131    ///
132    /// Yielded by `Traverse::next()` before the node’s descendants. In HTML or
133    /// XML, this corresponds to an opening tag like `<div>`.
134    Start(NodeId),
135
136    /// Indicates that end of a node that has children.
137    ///
138    /// Yielded by `Traverse::next()` after the node’s descendants. In HTML or
139    /// XML, this corresponds to a closing tag like `</div>`
140    End(NodeId),
141}
142
143#[derive(Clone)]
144/// An iterator of the "sides" of a node visited during a depth-first pre-order traversal,
145/// where node sides are visited start to end and children are visited in insertion order.
146///
147/// i.e. node.start -> first child -> second child -> node.end
148pub 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    /// Calculates the next node.
164    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                    // `node.parent()` here can only be `None` if the tree has
178                    // been modified during iteration, but silently stoping
179                    // iteration seems a more sensible behavior than panicking.
180                    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)]
198/// An iterator of the "sides" of a node visited during a depth-first pre-order traversal,
199/// where nodes are visited end to start and children are visited in reverse insertion order.
200///
201/// i.e. node.end -> second child -> first child -> node.start
202pub 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    /// Calculates the next node.
218    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                    // `node.parent()` here can only be `None` if the tree has
232                    // been modified during iteration, but silently stoping
233                    // iteration seems a more sensible behavior than panicking.
234                    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}