Skip to main content

easy_tree/
lib.rs

1//! # easy-tree
2//!
3//! `easy-tree` is a lightweight library for creating and manipulating tree structures in Rust.
4//! It provides a simple and efficient interface for managing hierarchical data and supports
5//! **depth-first traversal** with pre- and post-processing callbacks for flexible operations.
6//!
7//! ## Features
8//!
9//! - **Simple API**: Easily create, add, and retrieve nodes in the tree.
10//! - **Depth-first traversal**: Recursively traverse the tree with callbacks before and after processing subtrees.
11//! - **Flexible node access**: Access parent-child relationships and modify node data.
12//! - **Optional parallel iteration**: Speed up iteration with [rayon](https://docs.rs/rayon) when enabled.
13//!
14//! ## Use Cases
15//!
16//! `easy-tree` is ideal for representing and traversing hierarchical data, such as:
17//! - **File systems**
18//! - **Organizational charts**
19//! - **Abstract syntax trees (ASTs)**
20//! - **Graph-like structures with one parent per node**
21//!
22//! # Examples
23//!
24//! ## 1. Basic Tree Operations
25//! ```rust
26//!  use easy_tree::Tree;
27//!
28//!  let mut tree = Tree::new();
29//!  let root = tree.add_node("root");
30//!  let child1 = tree.add_child(root, "child1");
31//!  let child2 = tree.add_child(root, "child2");
32//!  let grandchild = tree.add_child(child1, "grandchild");
33//!
34//!  assert_eq!(tree.get(root), Some(&"root"));
35//!  assert_eq!(tree.get(grandchild), Some(&"grandchild"));
36//!  assert_eq!(tree.children(root), &[child1, child2]);
37//!  assert_eq!(tree.parent_index_unchecked(grandchild), Some(child1));
38//! ```
39//!
40//! ## 2. Depth-First Traversal
41//! Process nodes before and after their children using callbacks.
42//!
43//! ```rust
44//!  use easy_tree::Tree;
45//!
46//!  let mut tree = Tree::new();
47//!  let root = tree.add_node("root");
48//!  let child1 = tree.add_child(root, "child1");
49//!  let child2 = tree.add_child(root, "child2");
50//!
51//!  let mut result = vec![];
52//!  tree.traverse(
53//!     |idx, data, result| result.push(format!("Entering node {}: {}", idx, data)),
54//!     |idx, data, result| result.push(format!("Leaving node {}: {}", idx, data)),
55//!     &mut result,
56//!  );
57//!
58//!  assert_eq!(result, vec![
59//!     "Entering node 0: root",
60//!     "Entering node 1: child1",
61//!     "Leaving node 1: child1",
62//!     "Entering node 2: child2",
63//!     "Leaving node 2: child2",
64//!     "Leaving node 0: root",
65//!  ]);
66//! ```
67//!
68//! ## 3. Iteration
69//!
70//! Iterate over nodes and modify their data.
71//!
72//! ```rust
73//!  use easy_tree::Tree;
74//!
75//!  let mut tree = Tree::new();
76//!  let root = tree.add_node(0);
77//!  let child1 = tree.add_child(root, 1);
78//!  let child2 = tree.add_child(root, 2);
79//!
80//!  for (idx, data) in tree.iter_mut() {
81//!     *data += 10;
82//!  }
83//!
84//!  assert_eq!(tree.get(root), Some(&10));
85//!  assert_eq!(tree.get(child1), Some(&11));
86//!  assert_eq!(tree.get(child2), Some(&12));
87//! ```
88//!
89//! ## 4. Parallel Iteration (Optional)
90//!
91//! Use the `rayon` feature for parallel processing of nodes.
92//!
93//! ```rust
94//! #[cfg(feature = "rayon")]
95//! use easy_tree::Tree;
96//! #[cfg(feature = "rayon")]
97//! use rayon::prelude::*;
98//!
99//! #[cfg(feature = "rayon")]
100//! fn main() {
101//!     let mut tree = Tree::new();
102//!     let root = tree.add_node(0);
103//!     tree.add_child(root, 1);
104//!     tree.add_child(root, 2);
105//!
106//!     tree.par_iter().for_each(|(idx, data)| {
107//!         println!("Processing node {}: {}", idx, data);
108//!     });
109//! }
110//!
111//! #[cfg(not(feature = "rayon"))]
112//! fn main() {}
113//! ```
114//!
115//! ## API Overview
116//!
117//! - `Tree<T>`: Represents the tree structure containing nodes of type `T`.
118//! - `Node<T>`: Represents a single node in the tree.
119//! - `Tree::add_node(data: T) -> usize`: Adds a new root node.
120//! - `Tree::add_child(parent: usize, data: T) -> usize`: Adds a child node to a parent.
121//! - `Tree::traverse`: Walks the tree recursively with customizable callbacks.
122//! - `Tree::iter` / `Tree::iter_mut`: Provides immutable and mutable iterators over the nodes.
123//!
124//! ## Contributing
125//! Contributions are welcome! For more details, see the [GitHub repository](https://github.com/antouhou/easy-tree).
126//!
127//! ## License
128//! This project is licensed under the MIT License. See [LICENSE](https://github.com/antouhou/easy-tree/blob/main/LICENSE) for details.
129
130#[cfg(feature = "rayon")]
131pub use rayon;
132#[cfg(feature = "rayon")]
133use rayon::prelude::*;
134
135/// Represents a single node in a tree structure.
136///
137/// Each node contains:
138/// - **data**: A payload of generic type `T`.
139/// - **children**: A list of indices referring to its child nodes.
140/// - **parent**: An optional index referring to its parent node (or `None` if the node is a root).
141///
142/// Normally, you should use the `Tree::add_node` and
143/// `Tree::add_child` methods to create nodes and add them to the tree. There's no need to
144/// address `Node` directly in most cases.
145#[derive(Clone)]
146pub struct Node<T> {
147    data: T,
148    children: Vec<usize>,
149    parent: Option<usize>,
150}
151
152impl<T> Node<T> {
153    /// Creates a new node with the given data. Normally, you should use the `Tree::add_node` and
154    /// `Tree::add_child` methods to create nodes and add them to the tree. There's no need to
155    /// address `Node` directly in most cases.
156    ///
157    /// # Parameters
158    /// - `data`: The data to associate with this node.
159    ///
160    /// # Returns
161    /// A new `Node` instance.
162    ///
163    /// # Example
164    /// ```
165    /// use easy_tree::Node;
166    ///
167    /// let node = Node::new("example");
168    /// ```
169    pub fn new(data: T) -> Self {
170        Self {
171            data,
172            children: Vec::new(),
173            parent: None,
174        }
175    }
176
177    /// Adds a child to this node.
178    ///
179    /// # Parameters
180    /// - `child`: The index of the child node to add.
181    ///
182    /// # Internal Use
183    /// This method is used internally by the `Tree` struct.
184    pub(crate) fn add_child(&mut self, child: usize) {
185        self.children.push(child);
186    }
187
188    /// Sets the parent for this node.
189    ///
190    /// # Parameters
191    /// - `parent`: The index of the parent node to set.
192    ///
193    /// # Internal Use
194    /// This method is used internally by the `Tree` struct.
195    pub(crate) fn set_parent(&mut self, parent: usize) {
196        self.parent = Some(parent);
197    }
198}
199
200/// A tree structure containing multiple nodes of generic type `T`.
201///
202/// Each node in the tree is indexed by its position in the internal vector.
203/// The tree supports operations for adding, accessing, and traversing nodes.
204///
205/// # Example
206/// ```rust
207/// use easy_tree::Tree;
208///
209/// let mut tree = Tree::new();
210/// let root = tree.add_node("root");
211/// let child = tree.add_child(root, "child");
212/// ```
213#[derive(Clone)]
214pub struct Tree<T> {
215    nodes: Vec<Option<Node<T>>>,
216    /// Indices of removed nodes available for reuse.
217    free_list: Vec<usize>,
218    /// Number of live (non-removed) nodes.
219    node_count: usize,
220    /// Stack for traverse_mut to avoid allocations
221    stack: Vec<(usize, bool)>,
222}
223
224impl<T> Default for Tree<T> {
225    fn default() -> Self {
226        Self::new()
227    }
228}
229
230impl<T> Tree<T> {
231    /// Creates a new, empty tree.
232    ///
233    /// # Returns
234    /// A `Tree` instance with no nodes.
235    ///
236    /// # Example
237    /// ```rust
238    /// use easy_tree::Tree;
239    ///
240    /// let tree: Tree<i32> = Tree::new();
241    /// ```
242    pub fn new() -> Self {
243        Self {
244            nodes: Vec::new(),
245            free_list: Vec::new(),
246            node_count: 0,
247            stack: Vec::new(),
248        }
249    }
250
251    /// Adds a new node to the tree.
252    ///
253    /// This method is typically used to add a root node or a disconnected node.
254    ///
255    /// # Parameters
256    /// - `data`: The data to associate with the new node.
257    ///
258    /// # Returns
259    /// The index of the newly added node.
260    ///
261    /// # Example
262    /// ```rust
263    /// use easy_tree::Tree;
264    ///
265    /// let mut tree = Tree::new();
266    /// let root = tree.add_node("root");
267    /// ```
268    pub fn add_node(&mut self, data: T) -> usize {
269        let node = Node::new(data);
270        self.node_count += 1;
271        if let Some(index) = self.free_list.pop() {
272            self.nodes[index] = Some(node);
273            index
274        } else {
275            let index = self.nodes.len();
276            self.nodes.push(Some(node));
277            index
278        }
279    }
280
281    /// Adds a child node to an existing node in the tree.
282    ///
283    /// # Parameters
284    /// - `parent`: The index of the parent node.
285    /// - `data`: The data to associate with the new child node.
286    ///
287    /// # Returns
288    /// The index of the newly added child node.
289    ///
290    /// # Example
291    /// ```rust
292    /// use easy_tree::Tree;
293    ///
294    /// let mut tree = Tree::new();
295    /// let root = tree.add_node("root");
296    /// let child = tree.add_child(root, "child");
297    /// ```
298    pub fn add_child(&mut self, parent: usize, data: T) -> usize {
299        let index = self.add_node(data);
300        self.nodes[parent].as_mut().unwrap().add_child(index);
301        self.nodes[index].as_mut().unwrap().set_parent(parent);
302        index
303    }
304
305    /// Adds a child node to the tree root.
306    ///
307    /// # Parameters
308    /// - `data`: The data to associate with the new child node.
309    ///
310    /// # Returns
311    /// The index of the newly added child node.
312    ///
313    /// # Example
314    /// ```rust
315    /// use easy_tree::Tree;
316    ///
317    /// let mut tree = Tree::new();
318    /// let root = tree.add_node("root");
319    /// let child = tree.add_child_to_root("child");
320    /// ```
321    pub fn add_child_to_root(&mut self, data: T) -> usize {
322        self.add_child(0, data)
323    }
324
325    /// Retrieves a reference to the data stored in a node.
326    ///
327    /// # Parameters
328    /// - `index`: The index of the node to access.
329    ///
330    /// # Returns
331    /// `Some(&T)` if the node exists, or `None` if the index is out of bounds.
332    ///
333    /// # Example
334    /// ```rust
335    /// use easy_tree::Tree;
336    ///
337    /// let mut tree = Tree::new();
338    /// let root = tree.add_node(42);
339    /// assert_eq!(tree.get(root), Some(&42));
340    /// ```
341    pub fn get(&self, index: usize) -> Option<&T> {
342        self.nodes
343            .get(index)
344            .and_then(|slot| slot.as_ref().map(|node| &node.data))
345    }
346
347    /// Retrieves a reference to the data stored in a node without bounds checking.
348    ///
349    /// This method is faster than [`Tree::get`] because it does not perform any bounds checking.
350    /// However, it is unsafe to use if the provided index is out of bounds or invalid.
351    ///
352    /// # Parameters
353    /// - `index`: The index of the node to access.
354    ///
355    /// # Returns
356    /// A reference to the data stored in the node.
357    ///
358    /// # Safety
359    /// Ensure that:
360    /// - The `index` is within the valid range of node indices in the tree (0 to `Tree::len() - 1`).
361    /// - The node at the given index exists and has not been removed (if applicable).
362    ///
363    /// # Example
364    /// ```rust
365    /// use easy_tree::Tree;
366    ///
367    /// let mut tree = Tree::new();
368    /// let root = tree.add_node(42);
369    ///
370    /// // Safe use: The index is valid.
371    /// assert_eq!(tree.get_unchecked(root), &42);
372    ///
373    /// // Unsafe use: Accessing an invalid index would cause undefined behavior.
374    /// // let invalid = tree.get_unchecked(999); // Avoid this!
375    /// ```
376    #[inline(always)]
377    pub fn get_unchecked(&self, index: usize) -> &T {
378        &self.nodes[index].as_ref().unwrap().data
379    }
380
381    /// Retrieves a mutable reference to the data stored in a node.
382    ///
383    /// # Parameters
384    /// - `index`: The index of the node to access.
385    ///
386    /// # Returns
387    /// `Some(&mut T)` if the node exists, or `None` if the index is out of bounds.
388    ///
389    /// # Example
390    /// ```rust
391    /// use easy_tree::Tree;
392    ///
393    /// let mut tree = Tree::new();
394    /// let root = tree.add_node(42);
395    /// *tree.get_mut(root).unwrap() = 43;
396    /// assert_eq!(tree.get(root), Some(&43));
397    /// ```
398    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
399        self.nodes
400            .get_mut(index)
401            .and_then(|slot| slot.as_mut().map(|node| &mut node.data))
402    }
403
404    /// Retrieves a mutable reference to the data stored in a node without bounds checking.
405    ///
406    /// This method is faster than [`Tree::get_mut`] because it does not perform any bounds checking.
407    /// However, it is unsafe to use if the provided index is out of bounds or invalid.
408    ///
409    /// # Parameters
410    /// - `index`: The index of the node to access.
411    ///
412    /// # Returns
413    /// A mutable reference to the data stored in the node.
414    ///
415    /// # Safety
416    /// Ensure that:
417    /// - The `index` is within the valid range of node indices in the tree (0 to `Tree::len() - 1`).
418    /// - The node at the given index exists and has not been removed (if applicable).
419    /// - No other references to the same node are active during this call, to avoid data races or aliasing violations.
420    ///
421    /// # Example
422    /// ```rust
423    /// use easy_tree::Tree;
424    ///
425    /// let mut tree = Tree::new();
426    /// let root = tree.add_node(42);
427    ///
428    /// // Safe use: The index is valid.
429    /// *tree.get_unchecked_mut(root) = 99;
430    /// assert_eq!(tree.get_unchecked(root), &99);
431    ///
432    /// // Unsafe use: Accessing an invalid index would cause undefined behavior.
433    /// // let invalid = tree.get_unchecked_mut(999); // Avoid this!
434    /// ```
435    #[inline(always)]
436    pub fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
437        &mut self.nodes[index].as_mut().unwrap().data
438    }
439
440    /// Returns the parent index of a node, if it has a parent.
441    ///
442    /// # Parameters
443    /// - `index`: The index of the node.
444    ///
445    /// # Returns
446    /// `Some(parent_index)` if the node has a parent, or `None` otherwise.
447    ///
448    /// # Panics
449    /// This method panics if the index is out of bounds.
450    ///
451    /// # Example
452    /// ```rust
453    /// use easy_tree::Tree;
454    ///
455    /// let mut tree = Tree::new();
456    /// let root = tree.add_node(42);
457    /// let child = tree.add_child(root, 99);
458    /// assert_eq!(tree.parent_index_unchecked(child), Some(root));
459    /// ```
460    pub fn parent_index_unchecked(&self, index: usize) -> Option<usize> {
461        self.nodes[index].as_ref().unwrap().parent
462    }
463
464    /// Returns a slice of the indices of the children of a node.
465    ///
466    /// # Parameters
467    /// - `index`: The index of the node.
468    ///
469    /// # Returns
470    /// A slice containing the indices of the node's children.
471    ///
472    /// # Panics
473    /// This method panics if the index is out of bounds.
474    ///
475    /// # Example
476    /// ```rust
477    /// use easy_tree::Tree;
478    ///
479    /// let mut tree = Tree::new();
480    /// let root = tree.add_node("root");
481    /// let child = tree.add_child(root, "child");
482    /// assert_eq!(tree.children(root), &[child]);
483    /// ```
484    pub fn children(&self, index: usize) -> &[usize] {
485        &self.nodes[index].as_ref().unwrap().children
486    }
487
488    /// Traverses the tree in a depth-first manner.
489    ///
490    /// The traversal applies two callbacks:
491    /// - `before_processing_children`: Called before processing the children of a node.
492    /// - `after_processing_the_subtree`: Called after processing all children of a node.
493    ///
494    /// # Parameters
495    /// - `before_processing_children`: A function to apply before visiting children.
496    /// - `after_processing_the_subtree`: A function to apply after visiting children.
497    /// - `state`: Mutable state to share across callbacks.
498    ///
499    /// # Example
500    /// ```rust
501    /// use easy_tree::Tree;
502    ///
503    /// let mut tree = Tree::new();
504    /// let root = tree.add_node("root");
505    /// let child = tree.add_child(root, "child");
506    ///
507    /// let mut log = vec![];
508    /// tree.traverse(
509    ///     |idx, data, log| log.push(format!("Entering node {}: {}", idx, data)),
510    ///     |idx, data, log| log.push(format!("Leaving node {}: {}", idx, data)),
511    ///     &mut log,
512    /// );
513    /// ```
514    pub fn traverse<'a, S>(
515        &'a self,
516        mut before_processing_children: impl FnMut(usize, &'a T, &mut S),
517        mut after_processing_the_subtree: impl FnMut(usize, &'a T, &mut S),
518        s: &mut S,
519    ) {
520        if !matches!(self.nodes.first(), Some(Some(_))) {
521            return;
522        }
523
524        let mut stack = vec![(0, false)];
525
526        while let Some((index, children_visited)) = stack.pop() {
527            let node = self.nodes[index].as_ref().unwrap();
528            if children_visited {
529                // All children are processed, call f2
530                after_processing_the_subtree(index, &node.data, s);
531            } else {
532                // Call f and mark this node's children for processing
533                before_processing_children(index, &node.data, s);
534
535                // Re-push the current node with children_visited set to true
536                stack.push((index, true));
537
538                // Push all children onto the stack
539                for &child in node.children.iter().rev() {
540                    stack.push((child, false));
541                }
542            }
543        }
544    }
545
546    /// Walks the tree recursively, applying the given functions before and after processing the
547    /// children of each node. This version allows for mutable access to the nodes.
548    pub fn traverse_mut<S>(
549        &mut self,
550        mut before_processing_children: impl FnMut(usize, &mut T, &mut S),
551        mut after_processing_the_subtree: impl FnMut(usize, &mut T, &mut S),
552        s: &mut S,
553    ) {
554        if matches!(self.nodes.first(), Some(Some(_))) {
555            self.traverse_subtree_mut(
556                0,
557                &mut before_processing_children,
558                &mut after_processing_the_subtree,
559                s,
560            );
561        }
562    }
563
564    /// Walks the tree recursively starting from a specific node, applying the given functions
565    /// before and after processing the children of each node. This version allows for mutable
566    /// access to the nodes.
567    pub fn traverse_subtree_mut<S>(
568        &mut self,
569        start: usize,
570        mut before_processing_children: impl FnMut(usize, &mut T, &mut S),
571        mut after_processing_the_subtree: impl FnMut(usize, &mut T, &mut S),
572        s: &mut S,
573    ) {
574        if self.is_empty() || self.nodes.get(start).and_then(|n| n.as_ref()).is_none() {
575            return;
576        }
577
578        self.stack.clear();
579        self.stack.push((start, false));
580
581        while let Some((index, children_visited)) = self.stack.pop() {
582            if children_visited {
583                // All children are processed, call f2
584                let node = self.nodes[index].as_mut().unwrap();
585                after_processing_the_subtree(index, &mut node.data, s);
586            } else {
587                // Call f and mark this node's children for processing
588                let node = self.nodes[index].as_mut().unwrap();
589                before_processing_children(index, &mut node.data, s);
590
591                // Re-push the current node with children_visited set to true
592                self.stack.push((index, true));
593
594                // Push all children onto the stack
595                for &child in node.children.iter().rev() {
596                    self.stack.push((child, false));
597                }
598            }
599        }
600    }
601
602    /// Returns an iterator over the indices and data of the nodes in the tree.
603    pub fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
604        self.nodes
605            .iter()
606            .enumerate()
607            .filter_map(|(index, slot)| slot.as_ref().map(|node| (index, &node.data)))
608    }
609
610    /// Returns a mutable iterator over the indices and data of the nodes in the tree.
611    pub fn iter_mut(&mut self) -> impl Iterator<Item = (usize, &mut T)> {
612        self.nodes
613            .iter_mut()
614            .enumerate()
615            .filter_map(|(index, slot)| slot.as_mut().map(|node| (index, &mut node.data)))
616    }
617
618    /// Returns `true` if the tree contains no nodes.
619    pub fn is_empty(&self) -> bool {
620        self.node_count == 0
621    }
622
623    /// Returns the number of nodes in the tree.
624    pub fn len(&self) -> usize {
625        self.node_count
626    }
627
628    /// Removes all nodes from the tree.
629    pub fn clear(&mut self) {
630        self.nodes.clear();
631        self.free_list.clear();
632        self.node_count = 0;
633    }
634
635    /// Removes a node and all of its descendants from the tree.
636    ///
637    /// The removed node is detached from its parent, and all indices occupied by the
638    /// removed nodes are added to an internal free list for reuse by future
639    /// [`add_node`](Tree::add_node) or [`add_child`](Tree::add_child) calls.
640    ///
641    /// If `index` is out of bounds or refers to a previously removed node, this method
642    /// is a no-op.
643    ///
644    /// # Parameters
645    /// - `index`: The index of the root of the subtree to remove.
646    ///
647    /// # Example
648    /// ```rust
649    /// use easy_tree::Tree;
650    ///
651    /// let mut tree = Tree::new();
652    /// let root = tree.add_node("root");
653    /// let child1 = tree.add_child(root, "child1");
654    /// let child2 = tree.add_child(root, "child2");
655    /// let grandchild = tree.add_child(child1, "grandchild");
656    ///
657    /// assert_eq!(tree.len(), 4);
658    ///
659    /// tree.remove_subtree(child1);
660    ///
661    /// assert_eq!(tree.len(), 2);
662    /// assert_eq!(tree.get(child1), None);
663    /// assert_eq!(tree.get(grandchild), None);
664    /// assert_eq!(tree.children(root), &[child2]);
665    /// ```
666    pub fn remove_subtree(&mut self, index: usize) {
667        if !matches!(self.nodes.get(index), Some(Some(_))) {
668            return;
669        }
670
671        // Detach from parent
672        if let Some(parent_idx) = self.nodes[index].as_ref().unwrap().parent {
673            if let Some(parent) = self.nodes[parent_idx].as_mut() {
674                parent.children.retain(|&child| child != index);
675            }
676        }
677
678        // Remove all nodes in the subtree via iterative DFS
679        let mut removal_stack = vec![index];
680        while let Some(current) = removal_stack.pop() {
681            if let Some(node) = self.nodes[current].take() {
682                removal_stack.extend(node.children);
683                self.free_list.push(current);
684                self.node_count -= 1;
685            }
686        }
687
688        // Reset storage when the tree becomes empty, so the next add_node
689        // starts fresh from index 0.
690        if self.node_count == 0 {
691            self.nodes.clear();
692            self.free_list.clear();
693        }
694    }
695}
696
697#[cfg(feature = "rayon")]
698impl<T: Send + Sync> Tree<T> {
699    #[cfg(feature = "rayon")]
700    /// Returns a parallel iterator over the indices and data of the nodes in the tree.
701    pub fn par_iter(&self) -> impl ParallelIterator<Item = (usize, &T)> {
702        self.nodes
703            .par_iter()
704            .enumerate()
705            .filter_map(|(index, slot)| slot.as_ref().map(|node| (index, &node.data)))
706    }
707
708    #[cfg(feature = "rayon")]
709    /// Returns a mutable parallel iterator over the indices and data of the nodes in the tree.
710    pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = (usize, &mut T)> {
711        self.nodes
712            .par_iter_mut()
713            .enumerate()
714            .filter_map(|(index, slot)| slot.as_mut().map(|node| (index, &mut node.data)))
715    }
716}
717
718#[cfg(test)]
719mod tests {
720    use super::*;
721
722    #[test]
723    fn test_tree() {
724        let mut tree = Tree::new();
725        let root = tree.add_node(0);
726        let child1 = tree.add_child(root, 1);
727        let child2 = tree.add_child(root, 2);
728        let child3 = tree.add_child(child1, 3);
729
730        assert_eq!(tree.get(root), Some(&0));
731        assert_eq!(tree.get(child1), Some(&1));
732        assert_eq!(tree.get(child2), Some(&2));
733        assert_eq!(tree.get(child3), Some(&3));
734
735        assert_eq!(tree.parent_index_unchecked(child1), Some(root));
736        assert_eq!(tree.parent_index_unchecked(child2), Some(root));
737        assert_eq!(tree.parent_index_unchecked(child3), Some(child1));
738
739        assert_eq!(tree.children(root), &[child1, child2]);
740        assert_eq!(tree.children(child1), &[child3]);
741        assert_eq!(tree.children(child2), &[]);
742        assert_eq!(tree.children(child3), &[]);
743    }
744
745    #[test]
746    fn test_tree_iter() {
747        let mut tree = Tree::new();
748        let root = tree.add_node(0);
749        let child1 = tree.add_child(root, 1);
750        let child2 = tree.add_child(root, 2);
751        let child3 = tree.add_child(child1, 3);
752
753        let mut iter = tree.iter();
754        assert_eq!(iter.next(), Some((root, &0)));
755        assert_eq!(iter.next(), Some((child1, &1)));
756        assert_eq!(iter.next(), Some((child2, &2)));
757        assert_eq!(iter.next(), Some((child3, &3)));
758        assert_eq!(iter.next(), None);
759    }
760
761    #[test]
762    fn test_tree_iter_mut() {
763        let mut tree = Tree::new();
764        let root = tree.add_node(0);
765        let child1 = tree.add_child(root, 1);
766        let child2 = tree.add_child(root, 2);
767        let child3 = tree.add_child(child1, 3);
768
769        let mut iter = tree.iter_mut();
770        assert_eq!(iter.next(), Some((root, &mut 0)));
771        assert_eq!(iter.next(), Some((child1, &mut 1)));
772        assert_eq!(iter.next(), Some((child2, &mut 2)));
773        assert_eq!(iter.next(), Some((child3, &mut 3)));
774        assert_eq!(iter.next(), None);
775    }
776
777    #[test]
778    fn test_tree_traverse() {
779        let mut tree = Tree::new();
780        let root = tree.add_node(0); // Root node with data 0
781        let child1 = tree.add_child(root, 1); // Child node with data 1
782        let _child2 = tree.add_child(root, 2); // Child node with data 2
783        let _child3 = tree.add_child(child1, 3); // Child node with data 3
784
785        let mut result = vec![];
786
787        tree.traverse(
788            |index, node, result| result.push(format!("Calling handler for node {index}: {node}")),
789            |index, _node, result| {
790                result.push(format!(
791                    "Finished handling node {index} and all its children"
792                ))
793            },
794            &mut result,
795        );
796
797        assert_eq!(
798            result,
799            vec![
800                "Calling handler for node 0: 0",
801                "Calling handler for node 1: 1",
802                "Calling handler for node 3: 3",
803                "Finished handling node 3 and all its children",
804                "Finished handling node 1 and all its children",
805                "Calling handler for node 2: 2",
806                "Finished handling node 2 and all its children",
807                "Finished handling node 0 and all its children",
808            ]
809        );
810    }
811
812    #[test]
813    fn test_remove_subtree() {
814        let mut tree = Tree::new();
815        let root = tree.add_node("root");
816        let child1 = tree.add_child(root, "child1");
817        let child2 = tree.add_child(root, "child2");
818        let grandchild1 = tree.add_child(child1, "grandchild1");
819        let _grandchild2 = tree.add_child(child1, "grandchild2");
820
821        assert_eq!(tree.len(), 5);
822
823        tree.remove_subtree(child1);
824
825        assert_eq!(tree.len(), 2);
826        assert_eq!(tree.get(root), Some(&"root"));
827        assert_eq!(tree.get(child1), None);
828        assert_eq!(tree.get(child2), Some(&"child2"));
829        assert_eq!(tree.get(grandchild1), None);
830        assert_eq!(tree.children(root), &[child2]);
831    }
832
833    #[test]
834    fn test_remove_leaf_node() {
835        let mut tree = Tree::new();
836        let root = tree.add_node("root");
837        let child1 = tree.add_child(root, "child1");
838        let child2 = tree.add_child(root, "child2");
839
840        tree.remove_subtree(child1);
841
842        assert_eq!(tree.len(), 2);
843        assert_eq!(tree.get(child1), None);
844        assert_eq!(tree.children(root), &[child2]);
845    }
846
847    #[test]
848    fn test_remove_root() {
849        let mut tree = Tree::new();
850        let root = tree.add_node("root");
851        tree.add_child(root, "child1");
852        tree.add_child(root, "child2");
853
854        tree.remove_subtree(root);
855
856        assert!(tree.is_empty());
857        assert_eq!(tree.len(), 0);
858    }
859
860    #[test]
861    fn test_remove_and_reuse() {
862        let mut tree = Tree::new();
863        let root = tree.add_node(0);
864        let child1 = tree.add_child(root, 1);
865        tree.add_child(root, 2);
866        tree.add_child(child1, 3);
867
868        // Remove child1 subtree (indices 1 and 3)
869        tree.remove_subtree(child1);
870
871        // Add new nodes — should reuse freed indices
872        let new_child = tree.add_child(root, 10);
873        assert!(new_child == 3 || new_child == 1);
874
875        assert_eq!(tree.len(), 3);
876        assert_eq!(tree.get(new_child), Some(&10));
877    }
878
879    #[test]
880    fn test_iter_after_remove() {
881        let mut tree = Tree::new();
882        let root = tree.add_node(0);
883        let child1 = tree.add_child(root, 1);
884        let child2 = tree.add_child(root, 2);
885        tree.add_child(child1, 3);
886
887        tree.remove_subtree(child1);
888
889        let items: Vec<_> = tree.iter().collect();
890        assert_eq!(items.len(), 2);
891        assert_eq!(items[0], (root, &0));
892        assert_eq!(items[1], (child2, &2));
893    }
894
895    #[test]
896    fn test_traverse_after_remove() {
897        let mut tree = Tree::new();
898        let root = tree.add_node(0);
899        let child1 = tree.add_child(root, 1);
900        tree.add_child(root, 2);
901        tree.add_child(child1, 3);
902
903        tree.remove_subtree(child1);
904
905        let mut result = vec![];
906        tree.traverse(
907            |idx, data, result: &mut Vec<String>| result.push(format!("enter {idx}:{data}")),
908            |idx, data, result: &mut Vec<String>| result.push(format!("leave {idx}:{data}")),
909            &mut result,
910        );
911
912        assert_eq!(
913            result,
914            vec!["enter 0:0", "enter 2:2", "leave 2:2", "leave 0:0",]
915        );
916    }
917
918    #[test]
919    fn test_traverse_after_removing_first_root() {
920        let mut tree = Tree::new();
921        let root0 = tree.add_node("root0");
922        let root1 = tree.add_node("root1");
923        tree.add_child(root1, "child");
924
925        tree.remove_subtree(root0);
926
927        let mut result = vec![];
928        tree.traverse(
929            |idx, data, result: &mut Vec<String>| result.push(format!("enter {idx}:{data}")),
930            |idx, data, result: &mut Vec<String>| result.push(format!("leave {idx}:{data}")),
931            &mut result,
932        );
933
934        assert!(result.is_empty());
935    }
936
937    #[test]
938    fn test_traverse_mut_after_removing_first_root() {
939        let mut tree = Tree::new();
940        let root0 = tree.add_node(0);
941        let root1 = tree.add_node(10);
942        let child = tree.add_child(root1, 20);
943
944        tree.remove_subtree(root0);
945
946        let mut visited = vec![];
947        tree.traverse_mut(
948            |idx, data, visited: &mut Vec<(usize, i32)>| {
949                *data += 1;
950                visited.push((idx, *data));
951            },
952            |_, _, _| {},
953            &mut visited,
954        );
955
956        assert!(visited.is_empty());
957        assert_eq!(tree.get(root1), Some(&10));
958        assert_eq!(tree.get(child), Some(&20));
959    }
960
961    #[test]
962    fn test_remove_idempotent() {
963        let mut tree = Tree::new();
964        let root = tree.add_node("root");
965        let child = tree.add_child(root, "child");
966
967        tree.remove_subtree(child);
968        tree.remove_subtree(child); // no-op
969
970        assert_eq!(tree.len(), 1);
971    }
972
973    #[test]
974    fn test_remove_out_of_bounds() {
975        let mut tree = Tree::new();
976        let root = tree.add_node("root");
977
978        tree.remove_subtree(999); // no-op
979
980        assert_eq!(tree.len(), 1);
981        assert_eq!(tree.get(root), Some(&"root"));
982    }
983
984    #[test]
985    fn test_add_after_remove_root() {
986        let mut tree = Tree::new();
987        let root = tree.add_node("root");
988        tree.add_child(root, "child");
989
990        tree.remove_subtree(root);
991        assert!(tree.is_empty());
992
993        // New root should start fresh at index 0
994        let new_root = tree.add_node("new_root");
995        assert_eq!(new_root, 0);
996        assert_eq!(tree.get(new_root), Some(&"new_root"));
997        assert_eq!(tree.len(), 1);
998    }
999}