tree_iter/iter.rs
1use std::{collections::VecDeque, marker::PhantomData};
2
3use crate::traversal_order::{BreadthFirst, DepthFirst, TraversalOrder};
4
5/// Trait for immutable tree traversal.
6///
7/// This trait defines the interface required to iterate over a tree structure
8/// in an immutable fashion. Any type that implements this trait can be traversed
9/// using the provided iterators.
10///
11/// # Examples
12///
13/// ```rust
14/// use tree_iter::prelude::*;
15/// use tree_iter::tree::Node;
16///
17/// // Create a custom tree structure
18/// struct MyTree<T> {
19/// value: T,
20/// children: Vec<MyTree<T>>,
21/// }
22///
23/// // Implement TreeNode for custom tree structure
24/// impl<T> TreeNode for MyTree<T> {
25/// fn children(&self) -> impl DoubleEndedIterator<Item = &Self> + '_ {
26/// self.children.iter()
27/// }
28/// }
29///
30/// // Now you can use the tree iterator
31/// let my_tree = MyTree {
32/// value: 1,
33/// children: vec![
34/// MyTree { value: 2, children: vec![] },
35/// MyTree { value: 3, children: vec![] },
36/// ],
37/// };
38///
39/// let values: Vec<i32> = my_tree.iter::<DepthFirst>()
40/// .map(|node| node.value)
41/// .collect();
42/// ```
43pub trait TreeNode {
44 /// Returns an iterator over the children of this node.
45 ///
46 /// This method must be implemented by all types implementing `TreeNode`.
47 fn children(&self) -> impl DoubleEndedIterator<Item = &Self> + '_;
48
49 /// Creates an iterator that traverses the tree starting from this node.
50 ///
51 /// # Type Parameters
52 ///
53 /// * `T` - The traversal order strategy to use (e.g., `DepthFirst` or `BreadthFirst`).
54 fn iter<T: TraversalOrder>(&self) -> TreeIter<'_, Self, T>
55 where
56 Self: Sized,
57 {
58 TreeIter::new([self])
59 }
60}
61
62/// An iterator over tree nodes in a specified traversal order.
63///
64/// This struct provides the implementation for traversing a tree structure
65/// with nodes implementing the `TreeNode` trait.
66///
67/// # Type Parameters
68///
69/// * `'a` - The lifetime of the tree nodes being traversed.
70/// * `N` - The type of tree node.
71/// * `T` - The traversal order strategy (e.g., `DepthFirst` or `BreadthFirst`).
72pub struct TreeIter<'a, N, T> {
73 /// Queue of nodes to be visited.
74 nodes: VecDeque<&'a N>,
75 /// Phantom data to track the traversal order type.
76 _order: PhantomData<T>,
77}
78
79impl<'a, N, T: TraversalOrder> TreeIter<'a, N, T> {
80 /// Creates a new tree iterator from a collection of root nodes.
81 ///
82 /// # Parameters
83 ///
84 /// * `roots` - An iterator yielding the root nodes to start traversal from.
85 fn new(roots: impl IntoIterator<Item = &'a N>) -> Self {
86 Self {
87 nodes: roots.into_iter().collect(),
88 _order: PhantomData,
89 }
90 }
91}
92
93/// Implementation of `Iterator` for breadth-first traversal.
94impl<'a, N: TreeNode> Iterator for TreeIter<'a, N, BreadthFirst> {
95 type Item = &'a N;
96
97 /// Returns the next node in breadth-first order.
98 ///
99 /// Breadth-first traversal visits all nodes at a given depth before moving to the next level.
100 fn next(&mut self) -> Option<Self::Item> {
101 let node = self.nodes.pop_front()?;
102 self.nodes.extend(node.children());
103 Some(node)
104 }
105}
106
107/// Implementation of `Iterator` for depth-first traversal.
108impl<'a, N: TreeNode> Iterator for TreeIter<'a, N, DepthFirst> {
109 type Item = &'a N;
110
111 /// Returns the next node in depth-first order.
112 ///
113 /// Depth-first traversal explores as far down a branch as possible before backtracking.
114 fn next(&mut self) -> Option<Self::Item> {
115 let node = self.nodes.pop_front()?;
116 for child in node.children().rev() {
117 self.nodes.push_front(child);
118 }
119 Some(node)
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use crate::prelude::*;
126
127 // Define a simple tree structure for testing
128 struct TestTree<T> {
129 value: T,
130 children: Vec<TestTree<T>>,
131 }
132
133 impl<T> TestTree<T> {
134 fn new(value: T) -> Self {
135 Self {
136 value,
137 children: Vec::new(),
138 }
139 }
140
141 fn with_children(value: T, children: Vec<TestTree<T>>) -> Self {
142 Self { value, children }
143 }
144 }
145
146 // Implement TreeNode for TestTree
147 impl<T> super::TreeNode for TestTree<T> {
148 fn children(&self) -> impl DoubleEndedIterator<Item = &Self> + '_ {
149 self.children.iter()
150 }
151 }
152
153 #[test]
154 fn test_custom_tree_depth_first() {
155 // Create a test tree:
156 // 1
157 // / \
158 // 2 3
159 // / \
160 // 4 5
161 let tree = TestTree::with_children(
162 1,
163 vec![
164 TestTree::with_children(2, vec![TestTree::new(4), TestTree::new(5)]),
165 TestTree::new(3),
166 ],
167 );
168
169 // Collect values in depth-first order
170 let values: Vec<i32> = tree.iter::<DepthFirst>().map(|node| node.value).collect();
171 assert_eq!(values, vec![1, 2, 4, 5, 3]);
172 }
173
174 #[test]
175 fn test_custom_tree_breadth_first() {
176 // Create a test tree:
177 // 1
178 // / \
179 // 2 3
180 // / \
181 // 4 5
182 let tree = TestTree::with_children(
183 1,
184 vec![
185 TestTree::with_children(2, vec![TestTree::new(4), TestTree::new(5)]),
186 TestTree::new(3),
187 ],
188 );
189
190 // Collect values in breadth-first order
191 let values: Vec<i32> = tree.iter::<BreadthFirst>().map(|node| node.value).collect();
192 assert_eq!(values, vec![1, 2, 3, 4, 5]);
193 }
194
195 #[test]
196 fn test_empty_custom_tree() {
197 let tree = TestTree::<i32>::new(42);
198
199 // Test depth-first traversal
200 let df_values: Vec<i32> = tree.iter::<DepthFirst>().map(|node| node.value).collect();
201 assert_eq!(df_values, vec![42]);
202
203 // Test breadth-first traversal
204 let bf_values: Vec<i32> = tree.iter::<BreadthFirst>().map(|node| node.value).collect();
205 assert_eq!(bf_values, vec![42]);
206 }
207
208 #[test]
209 fn test_forest_traversal() {
210 // Test traversing a forest (multiple root nodes)
211 let tree1 = TestTree::with_children(1, vec![TestTree::new(2)]);
212 let tree2 = TestTree::with_children(3, vec![TestTree::new(4)]);
213
214 // Create an iterator with multiple roots
215 let forest_iter = super::TreeIter::<_, DepthFirst>::new([&tree1, &tree2]);
216 let values: Vec<i32> = forest_iter.map(|node| node.value).collect();
217
218 // Should traverse tree1 completely before starting tree2
219 assert_eq!(values, vec![1, 2, 3, 4]);
220 }
221}