Crate easy_tree

Source
Expand description

§easy-tree

easy-tree is a lightweight library for creating and manipulating tree structures in Rust. It provides a simple and efficient interface for managing hierarchical data and supports depth-first traversal with pre- and post-processing callbacks for flexible operations.

§Features

  • Simple API: Easily create, add, and retrieve nodes in the tree.
  • Depth-first traversal: Recursively traverse the tree with callbacks before and after processing subtrees.
  • Flexible node access: Access parent-child relationships and modify node data.
  • Optional parallel iteration: Speed up iteration with rayon when enabled.

§Use Cases

easy-tree is ideal for representing and traversing hierarchical data, such as:

  • File systems
  • Organizational charts
  • Abstract syntax trees (ASTs)
  • Graph-like structures with one parent per node

§Examples

§1. Basic Tree Operations

 use easy_tree::Tree;

 let mut tree = Tree::new();
 let root = tree.add_node("root");
 let child1 = tree.add_child(root, "child1");
 let child2 = tree.add_child(root, "child2");
 let grandchild = tree.add_child(child1, "grandchild");

 assert_eq!(tree.get(root), Some(&"root"));
 assert_eq!(tree.get(grandchild), Some(&"grandchild"));
 assert_eq!(tree.children(root), &[child1, child2]);
 assert_eq!(tree.parent_index_unchecked(grandchild), Some(child1));

§2. Depth-First Traversal

Process nodes before and after their children using callbacks.

 use easy_tree::Tree;

 let mut tree = Tree::new();
 let root = tree.add_node("root");
 let child1 = tree.add_child(root, "child1");
 let child2 = tree.add_child(root, "child2");

 let mut result = vec![];
 tree.traverse(
    |idx, data, result| result.push(format!("Entering node {}: {}", idx, data)),
    |idx, data, result| result.push(format!("Leaving node {}: {}", idx, data)),
    &mut result,
 );

 assert_eq!(result, vec![
    "Entering node 0: root",
    "Entering node 1: child1",
    "Leaving node 1: child1",
    "Entering node 2: child2",
    "Leaving node 2: child2",
    "Leaving node 0: root",
 ]);

§3. Iteration

Iterate over nodes and modify their data.

 use easy_tree::Tree;

 let mut tree = Tree::new();
 let root = tree.add_node(0);
 let child1 = tree.add_child(root, 1);
 let child2 = tree.add_child(root, 2);

 for (idx, data) in tree.iter_mut() {
    *data += 10;
 }

 assert_eq!(tree.get(root), Some(&10));
 assert_eq!(tree.get(child1), Some(&11));
 assert_eq!(tree.get(child2), Some(&12));

§4. Parallel Iteration (Optional)

Use the rayon feature for parallel processing of nodes.

#[cfg(feature = "rayon")]
use easy_tree::Tree;
#[cfg(feature = "rayon")]
use rayon::prelude::*;

#[cfg(feature = "rayon")]
fn main() {
    let mut tree = Tree::new();
    let root = tree.add_node(0);
    tree.add_child(root, 1);
    tree.add_child(root, 2);

    tree.par_iter().for_each(|(idx, data)| {
        println!("Processing node {}: {}", idx, data);
    });
}

#[cfg(not(feature = "rayon"))]
fn main() {}

§API Overview

  • Tree<T>: Represents the tree structure containing nodes of type T.
  • Node<T>: Represents a single node in the tree.
  • Tree::add_node(data: T) -> usize: Adds a new root node.
  • Tree::add_child(parent: usize, data: T) -> usize: Adds a child node to a parent.
  • Tree::traverse: Walks the tree recursively with customizable callbacks.
  • Tree::iter / Tree::iter_mut: Provides immutable and mutable iterators over the nodes.

§Contributing

Contributions are welcome! For more details, see the GitHub repository.

§License

This project is licensed under the MIT License. See LICENSE for details.

Re-exports§

pub use rayon;

Structs§

Node
Represents a single node in a tree structure.
Tree
A tree structure containing multiple nodes of generic type T.