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    use crate::tree::Node;
127
128    #[test]
129    fn test_custom_tree_depth_first() {
130        // Create a test tree:
131        //      1
132        //     / \
133        //    2   3
134        //   / \
135        //  4   5
136        let tree = Node {
137            value: 1,
138            children: vec![
139                Node {
140                    value: 2,
141                    children: vec![Node::new(4), Node::new(5)],
142                },
143                Node::new(3),
144            ],
145        };
146
147        // Collect values in depth-first order
148        let values: Vec<i32> = tree.iter::<DepthFirst>().map(|node| node.value).collect();
149        assert_eq!(values, vec![1, 2, 4, 5, 3]);
150    }
151
152    #[test]
153    fn test_custom_tree_breadth_first() {
154        // Create a test tree:
155        //      1
156        //     / \
157        //    2   3
158        //   / \
159        //  4   5
160        let tree = Node {
161            value: 1,
162            children: vec![
163                Node {
164                    value: 2,
165                    children: vec![Node::new(4), Node::new(5)],
166                },
167                Node::new(3),
168            ],
169        };
170
171        // Collect values in breadth-first order
172        let values: Vec<i32> = tree.iter::<BreadthFirst>().map(|node| node.value).collect();
173        assert_eq!(values, vec![1, 2, 3, 4, 5]);
174    }
175
176    #[test]
177    fn test_empty_custom_tree() {
178        let tree = Node::<i32>::new(42);
179
180        // Test depth-first traversal
181        let df_values: Vec<i32> = tree.iter::<DepthFirst>().map(|node| node.value).collect();
182        assert_eq!(df_values, vec![42]);
183
184        // Test breadth-first traversal
185        let bf_values: Vec<i32> = tree.iter::<BreadthFirst>().map(|node| node.value).collect();
186        assert_eq!(bf_values, vec![42]);
187    }
188
189    #[test]
190    fn test_forest_traversal() {
191        // Test traversing a forest (multiple root nodes)
192        let tree1 = Node {
193            value: 1,
194            children: vec![Node::new(2)],
195        };
196        let tree2 = Node {
197            value: 3,
198            children: vec![Node::new(4)],
199        };
200
201        // Create an iterator with multiple roots
202        let forest_iter = super::TreeIter::<_, DepthFirst>::new([&tree1, &tree2]);
203        let values: Vec<i32> = forest_iter.map(|node| node.value).collect();
204
205        // Should traverse tree1 completely before starting tree2
206        assert_eq!(values, vec![1, 2, 3, 4]);
207    }
208}