#tree #node #tree-structure #branch #data #generic #documentation

nb-tree

Very simple tree structure with generic node and branch data

1 unstable release

0.2.0-alpha01 Jan 21, 2025
0.1.0 Jun 24, 2024

#1091 in Data structures

Download history 1/week @ 2024-12-04 3/week @ 2024-12-11 41/week @ 2025-01-15 53/week @ 2025-01-22

94 downloads per month

MIT/Apache

175KB
4K SLoC

Generic Node - Branch Tree library

This library is still WIP (Work In Progress). Documentation and tests are partial, but the main module is covered, which presents the general Tree usages and functions provided by the various modules.

The motivation behind NB-Tree is the need for tree data manipulation for the ReTracer project (available on crates.io. The project is not usable just yet, but it is currently in active development).

Please see the library documentation for more information on its purpose and usage.

Quick showcase example

use nb_tree::prelude::Tree;

let mut tree1: Tree<usize, String> = Tree::new();

// quickly insert nodes
tree1
    .i("/", 1)
    .i("/a", 2)
    .i("/a/b", 3)
    .i("/c", 4)
    .i("/f", 15);

let mut tree2: Tree<usize, String> = Tree::new();
tree2
    .i("/", 10)
    .i("/a", 2)
    .i("/a/b", 3)
    .i("/c", 4)
    .i("/c/d", 51);

let tree2_orig = tree2.clone();

// Create tree diffs which are also trees
let diff = tree1.diff(&tree2);

// Combine trees
const OVERWRITE: bool = false;
tree2.combine(
    tree1.clone(),
    nb_tree::tree::CombinationMode::Union(OVERWRITE),
);

// Navigate trees
let mut node = tree2.root_entry_mut();
node.move_down("/a/b".into());
println!("Node at /a/b = {:?}", node.value());

// Modify trees
node.move_down_branch("w".to_string());
println!("Node at /a/b/w = {:?}", node.value());
let mut value_at_abw: &mut usize = node.or_insert(110); // creates a new node and returns a reference to its value
println!("Node at /a/b/w = {:?}", value_at_abw); // prints 110
value_at_abw = node.or_insert(99999); // retrieves the existing node's value
println!("Node at /a/b/w = {:?}", value_at_abw); // prints 110
node.move_up(2);
node.remove_subtree(); // removes the "/a" subtree
                       // Entries are convenient, but one can insert and remove nodes directly too
tree2.insert(&"/c/why".into(), 777).unwrap();
tree2.remove_subtree(&"/c".into()).unwrap();

// Iterate on the tree
println!("Tree: {:#?}", tree2);

let values: Vec<usize> = tree2.iter().map(|t| t.take()).cloned().collect();
println!("Tree's node values: {:?}", values);

let tuples: Vec<(Option<String>, usize)> = tree2
    .into_iter()
    .map(|t| (t.branch().cloned(), t.take()))
    .collect();
println!("Tree's node branch and values: {:?}", tuples);

// Apply tree diffs
tree1.apply(diff).unwrap();
// (making tree1 equal to the original tree2 in this example)
assert_eq!(tree1, tree2_orig);

// and more!

Dependencies

~1MB
~15K SLoC