flange_flat_tree/
lib.rs

1/*!
2
3A Rust implementation of Tree Data-Structure storing nodes in a Flat Array (`Vec` to be exact)
4and allowing to "flange" more data to the nodes.
5
6# Examples
7
8## Building a tree.
9
10A tree is build using the `Builder`. Afterwards a tree can not be changed anymore.
11
12```
13use flange_flat_tree::{Builder, Tree, Subtree};
14
15let mut b = Builder::new();
16b.start_element("one"); // The root node
17b.start_end_element("two"); // This will be a child of "one"
18b.start_element("three"); // This will be a child of "one"
19b.start_end_element("four"); // This will be a child of "three"
20b.end_element(); // End "three"
21b.end_element(); // End "one" (the root)
22
23let tree = b.build();
24assert_eq!(tree.root().value(), &"one");
25assert_eq!(tree.root().child_values(), [&"two", &"three"]);
26```
27
28But you can change elements of the tree still in the builder by using the index:
29
30```
31use flange_flat_tree::{Builder, Tree, Subtree};
32
33struct Node {
34    pub name: String,
35    pub value: u32,
36}
37
38let mut b = Builder::new();
39let root_id = b.start_element(Node { name: "one".to_string(), value: 1 }); // The root node
40b.start_end_element(Node { name: "two".to_string(), value: 2 }); // This will be a child of "one"
41
42// Change root afterwards
43b.get_mut(root_id).unwrap().name = "root".to_string();
44b.end_element(); // End "one" (the root)
45
46let tree = b.build();
47assert_eq!(tree.root().value().name, "root".to_string());
48```
49
50See the [`builder`](./src/tree/builder.rs) for more detail.
51
52## Flanging data
53
54After the tree is build, additional data can be "flanged" to the nodes of the tree.
55This means data is added without modifying the original tree or copying its data.
56
57"Flanging" can happen in 2 ways:
58
59### Flanging using "flange"
60
61You can flange using `tree.flange`.
62This crates a new tree which references the old tree and adds new data
63from the vector passed to `tree.flange`. The Vector is consumed, so it is
64owned by the new tree.
65
66The nodes of the `Vec` are associated the nodes with the same index in the
67original tree. When you access the tree you get a tuple of references to the values:
68
69```
70use flange_flat_tree::{Builder, Tree, Subtree};
71
72let mut builder = Builder::with_capacity(2);
73builder.start_element("one".to_string());
74builder.start_end_element("two".to_string());
75builder.end_element();
76let tree = builder.build();
77
78// flanged values
79let values: Vec<u32> = (10..12).collect();
80
81let tree_with_values = tree.flange(values);
82assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &10));
83```
84
85You can also create the flange by directly mapping from the original tree:
86
87```
88use flange_flat_tree::{Builder, Tree, Subtree};
89
90let mut builder = Builder::with_capacity(2);
91builder.start_element("one".to_string());
92builder.start_end_element("two".to_string());
93builder.end_element();
94let tree = builder.build();
95
96let tree_with_values = tree.flange_map(
97    |n| format!("{}-flanged", n)
98);
99
100assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &"one-flanged".to_string()));
101```
102
103This can also be done "depth-first", in which case the children are available before the node is created:
104
105```
106use flange_flat_tree::{Builder, Tree, Subtree};
107
108let mut builder = Builder::with_capacity(2);
109builder.start_element("one".to_string());
110builder.start_end_element("two".to_string());
111builder.end_element();
112let tree = builder.build();
113
114let tree_with_values = tree.depth_first_flange(
115    |n, childs| format!("{} with {} children", n, childs.len())
116);
117
118assert_eq!(tree_with_values.root().value(), (&"one".to_string(), &"one with 1 children".to_string()));
119assert_eq!(tree_with_values.root().children()[0].value(), (&"two".to_string(), &"two with 0 children".to_string()));
120```
121
122### Flange using map
123
124If you want to access the tree and its flange using named properties, you have to create
125a type for it. The type should reference the values it exposes. Than
126you can use `tree.map` with a closure to return your type.
127You can also combine the existing tree with external data that way:
128
129```
130use flange_flat_tree::{Builder, Tree, Subtree};
131
132let mut builder = Builder::with_capacity(2);
133builder.start_element("one");
134builder.start_end_element("two");
135builder.end_element();
136let tree = builder.build();
137
138struct FlangedNode<'a> {
139    pub name: &'a str,
140    pub value: u32, // we don't use a reference for u32, because copying the value itself is fine
141}
142
143// The data we are going to flange
144let data: Vec<u32> = vec![1,2];
145
146let tree_with_values = tree.map(
147    |i,v| FlangedNode {
148        name: v,
149        value: data[i],
150    }
151);
152
153assert_eq!(tree_with_values.root().value().name, "one");
154assert_eq!(tree_with_values.root().value().value, 1);
155```
156*/
157
158pub mod navigator;
159mod tree;
160
161pub use navigator::Neighbors;
162pub use tree::Builder;
163pub use tree::FlangedTree;
164pub use tree::Subtree;
165pub use tree::Tree;
166pub use tree::VecTree;
167
168#[cfg(test)]
169mod tests;