1use std::collections::hash_map::Iter as HMIter;
2use std::{hash::Hash, iter::FusedIterator, marker::PhantomData};
3
4use crate::{path::Path, prelude::DiffNode, tree::node::TreeNode};
5
6use super::super::{NodeIDX, Tree};
7
8#[derive(Debug, PartialEq)]
14pub enum Traversal<N, B> {
15 Start(N),
16 Step {
17 up: usize,
19 branch: B,
21 data: N,
23 },
24}
25
26impl<N, B> Traversal<N, B> {
27 pub fn take(self) -> N {
28 match self {
29 Self::Start(data) => data,
30 Self::Step {
31 up: _,
32 branch: _,
33 data,
34 } => data,
35 }
36 }
37
38 pub fn map<M>(self, op: impl Fn(N) -> M) -> Traversal<M, B> {
39 match self {
40 Self::Start(data) => Traversal::Start(op(data)),
41 Self::Step { up, branch, data } => Traversal::Step {
42 up,
43 branch,
44 data: op(data),
45 },
46 }
47 }
48 pub fn data(&self) -> &N {
49 match self {
50 Self::Start(data) => data,
51 Self::Step {
52 up: _,
53 branch: _,
54 data,
55 } => data,
56 }
57 }
58 pub fn branch(&self) -> Option<&B> {
59 match self {
60 Self::Start(_) => None,
61 Self::Step {
62 up: _,
63 branch,
64 data: _,
65 } => Some(branch),
66 }
67 }
68 pub fn up(&self) -> usize {
69 match self {
70 Self::Start(_) => 0,
71 Self::Step {
72 up,
73 branch: _,
74 data: _,
75 } => *up,
76 }
77 }
78 pub(crate) fn truncate_up(&mut self, cut: usize) {
79 if let Self::Step { up, branch, data } = self {
80 *up -= cut;
81 }
82 }
83
84 pub fn is_root(&self) -> bool {
85 match self {
86 Traversal::Start(_) => true,
87 Traversal::Step { .. } => false,
88 }
89 }
90}
91
92pub trait TreeIterTarget<'a, N, B> {
95 type Target;
96 fn target(tree: &'a Tree<N, B>, idx: NodeIDX) -> Self::Target;
97}
98
99impl<'a, N, B> TreeIterTarget<'a, N, B> for &'a TreeNode<N, B> {
100 type Target = Self;
101 fn target(tree: &'a Tree<N, B>, idx: NodeIDX) -> Self::Target {
102 &tree.nodes[idx]
103 }
104}
105
106impl<'a, N, B> TreeIterTarget<'a, N, B> for &'a N {
107 type Target = Self;
108 fn target(tree: &'a Tree<N, B>, idx: NodeIDX) -> Self::Target {
109 &tree.nodes[idx].value
110 }
111}
112
113impl<'a, N, B> TreeIterTarget<'a, N, B> for () {
114 type Target = Self;
115 fn target(_: &'a Tree<N, B>, _: NodeIDX) -> Self::Target {}
116}
117
118impl<'a, N, B> TreeIterTarget<'a, N, B> for NodeIDX {
119 type Target = Self;
120 fn target(_: &'a Tree<N, B>, idx: NodeIDX) -> Self::Target {
121 idx
122 }
123}
124
125pub struct Iter<'a, N, B, T>
126where
127 T: TreeIterTarget<'a, N, B>,
128{
129 tree: &'a Tree<N, B>,
130 root: Option<NodeIDX>,
131 stages: Vec<HMIter<'a, B, usize>>,
132 up: usize,
133 _phantom: PhantomData<T>,
134 }
136
137impl<'a, N, B, T> Iter<'a, N, B, T>
138where
139 T: TreeIterTarget<'a, N, B>,
140{
141 pub fn new(tree: &'a Tree<N, B>) -> Self {
142 Self {
143 tree,
144 root: tree.get_root_idx(),
145 stages: vec![],
146 up: 0,
147 _phantom: PhantomData,
148 }
150 }
151
152 pub fn up(&self) -> usize {
153 self.up
154 }
155}
156
157impl<'a, N, B, T> Iter<'a, N, B, T>
158where
159 B: Clone + Eq + Hash,
160 T: TreeIterTarget<'a, N, B>,
161{
162 pub fn new_sub_state(tree: &'a Tree<N, B>, path: Path<B>) -> Result<Self, Option<Path<B>>> {
163 Ok(Self {
164 tree,
165 root: Some(
166 tree.get_idx(&path, None)
167 .map_err(|r| r.map(|(_, idx_p)| path.path_to(idx_p)))?,
168 ),
169 stages: vec![],
170 up: 0,
171 _phantom: PhantomData,
172 })
174 }
175
176 pub fn is_last_child(&mut self) -> bool {
177 if let Some(last) = self.stages.last_mut() {
178 last.peekable().peek().is_none()
179 } else {
180 true
181 }
182 }
183}
184impl<'a, N, B, T> Iterator for Iter<'a, N, B, T>
188where
189 T: TreeIterTarget<'a, N, B>,
190{
191 type Item = Traversal<T::Target, &'a B>;
192
193 fn next(&mut self) -> Option<Self::Item> {
194 if let Some(last) = self.stages.last_mut() {
195 if let Some((branch, node_idx)) = last.next() {
197 let node = &self.tree.nodes[*node_idx];
199 self.stages.push(node.children.iter());
200 Some(Traversal::Step {
202 up: std::mem::replace(&mut self.up, 0),
203 branch,
204 data: T::target(self.tree, *node_idx),
205 })
206 } else {
208 self.stages.pop();
210 self.up += 1;
212 self.next()
213 }
214 } else if let Some(root) = self.root.take() {
215 let node = &self.tree.nodes[root];
216 self.stages.push(node.children.iter());
217 Some(Traversal::Start(T::target(self.tree, root)))
218 } else {
219 None
220 }
221 }
222}
223
224impl<'a, N, B, T> FusedIterator for Iter<'a, N, B, T> where T: TreeIterTarget<'a, N, B> {}
225
226impl<'a, N, B> IntoIterator for &'a Tree<N, B> {
227 type Item = Traversal<&'a N, &'a B>;
228
229 type IntoIter = Iter<'a, N, B, &'a N>;
230
231 fn into_iter(self) -> Self::IntoIter {
232 Self::IntoIter::new(self)
233 }
234}
235
236pub trait TreeIntoIterTarget<N, B> {
247 type Target;
248 fn target(node: TreeNode<N, B>) -> Self::Target;
249}
250
251impl<N, B> TreeIntoIterTarget<N, B> for N {
252 type Target = Self;
253 fn target(node: TreeNode<N, B>) -> Self::Target {
254 node.value
255 }
256}
257
258impl<N, B> TreeIntoIterTarget<N, B> for TreeNode<N, B> {
259 type Target = Self;
260 fn target(node: TreeNode<N, B>) -> Self::Target {
261 node
262 }
263}
264
265pub struct IntoIter<N, B, T>
267where
268 B: Clone,
269 T: TreeIntoIterTarget<N, B>,
270{
271 idxs: Vec<Traversal<NodeIDX, B>>,
272 nodes: Vec<Option<TreeNode<N, B>>>,
273 _phantom: PhantomData<T>,
274}
275
276impl<N, B, T> IntoIter<N, B, T>
277where
278 B: Clone,
279 T: TreeIntoIterTarget<N, B>,
280{
281 pub fn new(tree: Tree<N, B>) -> Self {
282 let mut s = Self {
283 idxs: Iter::<N, B, NodeIDX>::new(&tree)
285 .map(|n| match n {
286 Traversal::Start(idx) => Traversal::Start(idx),
287 Traversal::Step { up, branch, data } => Traversal::Step {
288 up,
289 branch: branch.clone(),
290 data,
291 },
292 })
293 .collect(),
294 nodes: tree.nodes.into_iter().map(Some).collect(),
295 _phantom: PhantomData,
296 };
297 s.idxs.reverse();
299 s
300 }
301}
302
303impl<N, B, T> Iterator for IntoIter<N, B, T>
304where
305 B: Clone,
306 T: TreeIntoIterTarget<N, B>,
307{
308 type Item = Traversal<T::Target, B>;
309
310 fn next(&mut self) -> Option<Self::Item> {
311 match self.idxs.pop() {
312 Some(Traversal::Start(idx)) => {
313 Some(Traversal::Start(T::target(self.nodes[idx].take().unwrap())))
314 }
315 Some(Traversal::Step { up, branch, data }) => Some(Traversal::Step {
316 up,
317 branch,
318 data: T::target(self.nodes[data].take().unwrap()),
319 }),
320 None => None,
321 }
322 }
323}
324
325impl<N, B> IntoIterator for Tree<N, B>
326where
327 B: Clone,
328{
329 type Item = Traversal<N, B>;
330
331 type IntoIter = IntoIter<N, B, N>;
332
333 fn into_iter(self) -> Self::IntoIter {
334 Self::IntoIter::new(self)
335 }
336}