1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! # TreeFlat is the simplest way to build & traverse a pre-order Tree for Rust.
//!
//! If you build a [tree::Tree] *in pre-order*, and display *in pre-order*,
//! this is the tree for you.
//!
//! **No extra fluff**, just a simple & performant one-trick pony.
//!
//! Note: The tree depends in the build order, so is not possible to re-order the tree
//! (changing parents or levels) in different order. So, for example, you can't add
//! a branch later to one in the *middle* (only can add *after* the end...).
//!
//! ## How it works
//!
//! Instead of creating an [tree::Tree] of [node::Node] pointers, nested enums, or nested `Arena`-based `ids`,
//! it just stores the representation of a [tree::Tree] like:
//!
//! ```bash
//! . Users
//! ├── jhon_doe
//! ├   ├── file1.rs
//! ├   ├── file2.rs
//! ├── jane_doe
//! └────── cat.jpg
//! ```
//!
//! ... flattened in pre-order on 3 [Vec], that store the data, the level/level and the parent:
//!
//! | DATA:  | Users | jhon_doe | file1.rs | file2.rs | jane_doe | cat.jpg |
//! |--------|-------|----------|----------|----------|----------|---------|
//! | level:  | 0     | 1        | 2        | 2        | 1        | 2       |
//! | PARENT:| 0     | 0        | 1        | 1        | 0        | 4       |
//!
//! This allows for the performance of [Vec], on the most common operations
//! (critically: Push items + Iterate), and very efficient iterations of
//! [node::Node::parents]/[node::Node::children]/[node::Node::siblings], because
//! it just traverse the flat vectors.
//!
//! The iterators exploit this observations:
//!
//! * The children are at the right/up of the parent
//! * The parents are at the left/down of the children
//! * The siblings are all that share the same level
//!
//! # Examples
//! ```
//! use tree_flat::prelude::*;
//!
//! let mut tree = Tree::with_capacity("Users", 6);
//!
//! let mut root = tree.root_mut();
//!
//! let mut child = root.push("jhon_doe");
//! child.push("file1.rs");
//! child.push("file2.rs");
//!
//! let mut child = root.push("jane_doe");
//! child.push("cat.jpg");
//!
//! //The data is backed by vectors and arena-like ids on them:
//! assert_eq!(
//!    tree.as_data(),
//!    ["Users", "jhon_doe", "file1.rs", "file2.rs", "jane_doe", "cat.jpg",]
//! );
//! assert_eq!(tree.as_level(), [0, 1, 2, 2, 1, 2,]);
//! assert_eq!(tree.as_parents(), [0, 0, 1, 1, 0, 4,]);
//! //Pretty print the tree
//! println!("{}", tree);
//!
//! //Iterations is as inserted:
//! for f in &tree {
//!   dbg!(f);
//! }
//!
//! ```
//! - - - - - -
//!
//! Inspired by the talk:
//!
//! > “High-performance Tree Wrangling, the APL Way”
//! > -- <cite> [Aaron Hsu - APL Wiki](https://aplwiki.com/wiki/Aaron_Hsu)  

/// Flat-tree iterators
pub mod iter;
/// Flat-tree nodes
pub mod node;
#[cfg(test)]
mod tests;
/// Flat-tree implementation
pub mod tree;
/// Import this module for easy access to the Flat-tree
pub mod prelude {
    pub use crate::iter;
    pub use crate::node::{Node, NodeId, NodeMut};
    pub use crate::tree;
    pub use crate::tree::Tree;
}