atree/lib.rs
1#![doc(html_root_url = "https://docs.rs/atree/0.5.2")]
2//! An arena based tree structure, backed by a custom allocator (ultimately
3//! built on `Vec`) that makes node removal a possibility. On top of the basic
4//! node insertion and removal operations, there are also many kinds of
5//! immutable and mutable iterators provided for various kinds of tree traversal
6//! operations.
7//!
8//! Most of the code in the crate is `unsafe` free, except for the mutable
9//! iterators, where the `unsafe` code is lifted from the core Rust
10//! implementation of `IterMut`.
11//!
12//! # General Guide to the API
13//!
14//! The crate consists of three main `struct`s: [`Arena<T>`], [`Token`] and
15//! [`Node<T>`]. `Arena<T>` provides the arena in which all data is stored.
16//! The data can then be accessed by indexing `Arena<T>` with `Token`. `Node<T>`
17//! is a container that encapsulates the data on the tree.
18//!
19//! As a general rule of thumb, methods that affect the memory layout such as
20//! splitting and merging arenas, or methods to create and destroy nodes regardless
21//! of existing tree structures like creating a free node, are defined on
22//! `Arena<T>`. Methods that alter pre-existing tree structures such as adding
23//! nodes with respect to existing ones ([`append`] or [`insert_after`] for
24//! instance) or splitting and attaching existing trees are defined on `Tokens`.
25//!
26//! When it comes to iterating, iterators can be created from methods on both
27//! `Token` and `Node<T>`. There are two versions of iterators, iterators over
28//! tokens or references to the nodes. Both can be created by methods on `Token`
29//! and `Node<T>`. However, due to the rules of borrow checking, mutable
30//! iterators over the node references are only defined on `Token`.
31//!
32//! # Crate Feature Flags
33//! - `serde`: support for serde 1.x. Optional feature/dependency.
34//!
35//! # Usage Examples
36//!
37//! We can start by initializing an empty arena and add stuff to it at a later
38//! time:
39//! ```
40//! use atree::Arena;
41//!
42//! let mut arena = Arena::default();
43//! assert!(arena.is_empty());
44//!
45//! // create a tree in the arena
46//! let data = "Indo-European";
47//! let token = arena.new_node(data);
48//! assert_eq!(arena.node_count(), 1)
49//! ```
50//!
51//! There is a shortcut to the above operation:
52//! ```
53//! use atree::Arena;
54//!
55//! let data = "Indo-European";
56//! let (mut arena, token) = Arena::with_data(data);
57//! assert_eq!(arena.node_count(), 1)
58//! ```
59//!
60//! To add more data to the tree, call the [`append`] method on the tokens (we
61//! can't do this directly to the nodes because of the limitations of borrow
62//! checking).
63//! ```
64//! use atree::Arena;
65//!
66//! let root_data = "Indo-European";
67//! let (mut arena, root_token) = Arena::with_data(root_data);
68//! root_token.append(&mut arena, "Romance");
69//! assert_eq!(arena.node_count(), 2);
70//! ```
71//!
72//! To access/modify existing nodes in the tree, we can use indexing or
73//! [`get`]/[`get_mut`].
74//! ```
75//! use atree::Arena;
76//!
77//! let root_data = "Indo-European";
78//! let (mut arena, root_token) = Arena::with_data(root_data);
79//!
80//! // add some more stuff to the tree
81//! let branch1 = root_token.append(&mut arena, "Romance");
82//! let branch2 = root_token.append(&mut arena, "Germanic");
83//! let branch3 = root_token.append(&mut arena, "Slavic");
84//! let lang1 = branch2.append(&mut arena, "English");
85//! let lang2 = branch2.append(&mut arena, "Swedish");
86//! let lang3 = branch3.append(&mut arena, "Polish");
87//!
88//! // Access data by indexing the arena by a token. This operation panics if the
89//! // token is invalid.
90//! assert_eq!(arena[branch3].data, "Slavic");
91//!
92//! // Access data by calling "get" on the arena with a token.
93//! assert_eq!(arena.get(lang1).unwrap().data, "English");
94//!
95//! // We can also do so mutably (with "get" or through indexing). As you can
96//! // see, calling the "get" functions is more verbose but you get to avoid
97//! // surprise panic attacks (if you don't unwrap like I do here).
98//! arena.get_mut(lang1).unwrap().data = "Icelandic";
99//! assert_eq!(arena[lang1].data, "Icelandic");
100//!
101//! // On the flip side, we can access the corresponding token if we already
102//! // have the node
103//! let branch3_node = &arena[branch3];
104//! assert_eq!(branch3, branch3_node.token());
105//! ```
106//!
107//! We can iterate over the elements by calling iterators on both the tokens
108//! or the nodes. Check the documentation of [`Token`] or [`Node<T>`] for a list
109//! of iterators. There is a version of each of the iterators that iterates
110//! over tokens instead of node references. See the docs for details.
111//! ```
112//! use atree::Arena;
113//!
114//! let root_data = "Indo-European";
115//! let (mut arena, root_token) = Arena::with_data(root_data);
116//!
117//! // add some more stuff to the tree
118//! let branch1 = root_token.append(&mut arena, "Romance");
119//! let branch2 = root_token.append(&mut arena, "Germanic");
120//! let branch3 = root_token.append(&mut arena, "Slavic");
121//! let lang1 = branch2.append(&mut arena, "English");
122//! let lang2 = branch2.append(&mut arena, "Swedish");
123//! let lang3 = branch3.append(&mut arena, "Polish");
124//!
125//! // Getting an iterator from a token and iterate
126//! let children: Vec<_> = root_token.children(&arena).map(|x| x.data).collect();
127//! assert_eq!(&["Romance", "Germanic", "Slavic"], &children[..]);
128//!
129//! // Getting an iterator from a node reference (that is if you already have it
130//! // around. To go out of your way to get the node reference before getting
131//! // the iterator seems kind of dumb).
132//! let polish = &arena[lang3];
133//! let ancestors: Vec<_> = polish.ancestors(&arena).map(|x| x.data).collect();
134//! assert_eq!(&["Slavic", "Indo-European"], &ancestors[..]);
135//!
136//! // We can also iterate mutably. Unfortunately we can only get mutable
137//! // iterators from the tokens but not from the node references because of
138//! // borrow checking.
139//! for lang in branch2.children_mut(&mut arena) {
140//! lang.data = "Not romantic enough";
141//! }
142//! assert_eq!(arena[lang1].data, "Not romantic enough");
143//! assert_eq!(arena[lang2].data, "Not romantic enough");
144//! ```
145//!
146//! To remove a single node from the arena, use the [`remove`] method. This will
147//! detach all the children of the node from the tree (but not remove them from
148//! memory).
149//! ```
150//! use atree::Arena;
151//! use atree::iter::TraversalOrder;
152//!
153//! // root node that we will attach subtrees to
154//! let root_data = "Indo-European";
155//! let (mut arena, root) = Arena::with_data(root_data);
156//!
157//! // the Germanic branch
158//! let germanic = root.append(&mut arena, "Germanic");
159//! let west = germanic.append(&mut arena, "West");
160//! let scots = west.append(&mut arena, "Scots");
161//! let english = west.append(&mut arena, "English");
162//!
163//! // detach the west branch from the main tree
164//! let west_children = arena.remove(west);
165//!
166//! // the west branch is gone from the original tree
167//! let mut iter = root.subtree(&arena, TraversalOrder::Pre)
168//! .map(|x| x.data);
169//! assert_eq!(iter.next(), Some("Indo-European"));
170//! assert_eq!(iter.next(), Some("Germanic"));
171//! assert!(iter.next().is_none());
172//!
173//! // its children are still areound
174//! let mut iter = west_children.iter().map(|&t| arena[t].data);
175//! assert_eq!(iter.next(), Some("Scots"));
176//! assert_eq!(iter.next(), Some("English"));
177//! assert!(iter.next().is_none());
178//! ```
179//!
180//! To uproot a tree from the arena, call the [`uproot`] method on the arena.
181//! Note that will also remove all descendants of the node. After removal, the
182//! "freed" memory will be reused if and when new data is inserted.
183//! ```
184//! use atree::Arena;
185//!
186//! let root_data = "Indo-European";
187//! let (mut arena, root_token) = Arena::with_data(root_data);
188//!
189//! // add some more stuff to the tree
190//! let branch1 = root_token.append(&mut arena, "Romance");
191//! let branch2 = root_token.append(&mut arena, "Germanic");
192//! let branch3 = root_token.append(&mut arena, "Slavic");
193//! let lang1 = branch2.append(&mut arena, "English");
194//! let lang2 = branch2.append(&mut arena, "Swedish");
195//! let lang3 = branch3.append(&mut arena, "Polish");
196//!
197//! assert_eq!(arena.node_count(), 7);
198//! arena.uproot(branch2); // boring languages anyway
199//! assert_eq!(arena.node_count(), 4);
200//! ```
201//!
202//! [`Arena<T>`]: struct.Arena.html
203//! [`Token`]: struct.Token.html
204//! [`Node<T>`]: struct.Node.html
205//! [`append`]: struct.Token.html#method.append
206//! [`insert_after`]: struct.Token.html#method.insert_after
207//! [`get`]: struct.Arena.html#method.get
208//! [`get_mut`]: struct.Arena.html#method.get_mut
209//! [`uproot`]: struct.Arena.html#method.uproot
210//! [`remove`]: struct.Arena.html#method.remove
211
212#[cfg(feature = "serde")]
213extern crate serde;
214
215mod alloc;
216mod arena;
217pub mod iter;
218mod node;
219mod token;
220
221pub use token::Token;
222pub use arena::Arena;
223pub use node::Node;
224
225#[derive(Clone, Copy, Debug)]
226/// The Error type
227pub enum Error {
228 /// Not a root node error
229 NotARootNode
230}