easy-tree 0.3.0

A simple and efficient tree structure library for Rust with recursive traversal
Documentation
# easy-tree

[![Crates.io](https://img.shields.io/crates/v/easy-tree.svg)](https://crates.io/crates/easy-tree)
[![Documentation](https://docs.rs/easy-tree/badge.svg)](https://docs.rs/easy-tree)
[![Build and test](https://github.com/antouhou/easy-tree/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/antouhou/easy-tree/actions)

`easy-tree` is a lightweight Rust library for managing and traversing hierarchical data structures. It provides a simple interface for creating trees and supports **recursive depth-first traversal** with pre- and post-processing callbacks.

## Key Features

- **Depth-first traversal**: Easily process nodes with callbacks before and after their subtrees.
- **Simple API**: Add, modify, and retrieve nodes effortlessly.
- **Customizable traversal logic**: Use callbacks to handle specific traversal behaviors.
- **Optional parallel iteration**: Boost performance with [rayon]https://docs.rs/rayon.

## Why Use easy-tree?

1. **Designed for Hierarchical Data**: Ideal for file systems, DOM structures, organizational charts, and more.
2. **Traverse with Precision**: Depth-first traversal with pre- and post-order processing in one simple call.
3. **Memory Efficient**: Minimal overhead with direct references between nodes.
4. **Extensible**: Integrates easily into larger systems and workflows.

---

## Installation

Add `easy-tree` to your `Cargo.toml`:

```toml
[dependencies]
easy-tree = "0.1"
```

To enable parallel iteration:

```toml
[dependencies]
easy-tree = { version = "0.1", features = ["rayon"] }
```

---

## How It Works

### Tree Structure

Each node in the tree has:
- A **data payload** (your custom type)
- A single parent (or `None` for the root)
- A list of child indices

### Traversal Flow

Here’s an illustration of a depth-first traversal order:

```
Root
├── Child 1
│   └── Grandchild 1
├── Child 2
└── Child 3
```

Traversal output:
1. `Visiting Child 1`
2. `Visiting Grandchild 1`
3. `Leaving Grandchild 1`
4. `Leaving Child 1`
5. ...

---

## Examples

### 1. Basic Tree Creation

```rust
use easy_tree::Tree;

fn main() {
    let mut tree = Tree::new();
    let root = tree.add_node("root");
    let child = tree.add_child(root, "child");
    let grandchild = tree.add_child(child, "grandchild");

    assert_eq!(tree.get(root), Some(&"root"));
    assert_eq!(tree.get(grandchild), Some(&"grandchild"));
}
```

### 2. Depth-First Traversal

```rust
use easy_tree::Tree;

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

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

    println!("{:?}", log);
}
```

### 3. Parallel Iteration (Optional)

```rust
use easy_tree::Tree;

fn main() {
    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);

    #[cfg(feature = "rayon")]
    {
        tree.par_iter().for_each(|(idx, data)| {
            println!("Processing node {}: {}", idx, data);
        });
    }
}
```

---

## Use Cases

### Represent a File System

```rust
use easy_tree::Tree;

fn main() {
    let mut fs = Tree::new();
    let root = fs.add_node("root/");
    let home = fs.add_child(root, "home/");
    let user = fs.add_child(home, "user/");
    let file = fs.add_child(user, "file.txt");

    println!("Tree structure:");
    fs.traverse(
        |_, data, _| println!("Entering {}", data),
        |_, data, _| println!("Leaving {}", data),
        &mut (),
    );
}
```

---

## Performance

- **Low Memory Overhead**: Nodes are stored contiguously in a vector.
- **Efficient Traversal**: Iterative depth-first traversal minimizes recursion overhead.
- **Parallel Ready**: Enable the `rayon` feature for concurrent processing.

---

## Advanced Features

1. **Custom Traversal Logic**: Use pre- and post-processing callbacks for fine-grained control.
2. **Flexible Node Access**: Retrieve, update, or delete nodes efficiently.