tree/lib.rs
1// This file is part of `tree-rizzen-yazston` crate. For the terms of use, please see the file
2// called `LICENSE-BSD-3-Clause` at the top level of the `tree-rizzen-yazston` crate.
3
4//! Welcome to the Tree project.
5//!
6//! A simple tree structure containing data nodes. The `tree` crate provides the [`Tree`] struct, which can store any
7//! data that implements the [`Any`] trait. Methods are provided for the manipulation of the tree structure, and
8//! obtaining information regarding the tree structure and its nodes. Manipulating the data of the nodes is done via
9//! the method [`data_mut`], which simply provides a mutable reference to the vector containing the data. The
10//! [`data_ref`] method is just an immutable reference if reading is only required.
11//!
12//! Internally the tree makes use of a node struct that contains information about the node in the tree. The
13//! information consists of: the immediate parent node, a vector containing children nodes, the node's features,
14//! the node type, the data type, and a vector containing data. All the node struct fields are optional except for the
15//! node's features (determines how the node will behave in the tree).
16//!
17//! The node's features are specified at the time of the node creation as a parameter `features` of [`insert`] and
18//! [`insert_at`] methods by passing an union of selected features. Currently the tree supports two features:
19//!
20//! - [`ALLOW_CHILDREN`]: indicates if the node can have children,
21//!
22//! - [`ALLOW_DATA`]: indicates if the node can have data.
23//!
24//! At the time of creating the nodes, the `node_type` and `data_type` parameters are passed to specify the node and
25//! data types. These fields are read only once they are set. The node type is normally used for indicating what the
26//! node is, especially when the node type can't be determined from the node's data, or the node lacks any data (such
27//! as structure information). The data type is generally used when the data of the entire tree is of different types.
28//! The data type is normally specified to aid in determining how to correctly downcast the data to its actual type. As
29//! the node can support multiple data instances, it is recommended that all the data instances within the node are of
30//! the same type, due to there being only one data type field for the node. Though it is possible to use an
31//! elaborate string than a simple enum to indicate all the data types used in the node.
32//!
33//! # Note
34//!
35//! Once [`core::error::Error`] is no longer experimental, this library will then only depend on the `core`, thus
36//! will be suitable for `no_std` environments.
37//!
38//! # Examples
39//!
40//! This example uses the `String` as the data type for all the nodes that have data, thus the parameter `data_type` is
41//! `None` to indicate it is not used. A string `"String"` could have be used to explicitly indicate the data is of
42//! type `String`. Alternative a simple enum could be used if all the data types are known at compile time to
43//! indicate the data type.
44//!
45//! Due the data being strings, that carry little structure information (not all nodes contains data), a good choice is
46//! to use an enum to indicate the node type. As with `data_type`, strings could have also be used for the `node_type`.
47//!
48//! ```
49//! use tree::{Tree, ALLOW_CHILDREN, ALLOW_DATA};
50//!
51//! enum Nodes {
52//! Root,
53//! Statement,
54//! Equal,
55//! Divide,
56//! Add,
57//! Leaf,
58//! }
59//!
60//! let mut tree = Tree::new();
61//! let no_data = ALLOW_CHILDREN;
62//! let variable = ALLOW_DATA;
63//!
64//! // Build tree of one statement: z = (x + y) / 2
65//! // Just ignoring the `Result` using .ok() as this is a trivial example.
66//! let mut index = tree.insert( 300, no_data.clone(), Some( Box::new( Nodes::Root ) ), None ).unwrap();
67//! tree.insert( index, no_data.clone(), Some( Box::new( Nodes::Statement ) ), None ).ok();
68//! tree.insert( 1, no_data.clone(), Some( Box::new( Nodes::Equal ) ), None ).ok();
69//! index = tree.insert( 2, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
70//! tree.data_mut( index ).unwrap().push( Box::new( "z".to_string() ) );
71//! tree.insert( 2, no_data.clone(), Some( Box::new( Nodes::Divide ) ), None ).ok();
72//! tree.insert( 4, no_data.clone(), Some( Box::new( Nodes::Add ) ), None ).ok();
73//! index = tree.insert( 5, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
74//! tree.data_mut( index ).unwrap().push( Box::new( "x".to_string() ) );
75//! index = tree.insert( 5, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
76//! tree.data_mut( index ).unwrap().push( Box::new( "y".to_string() ) );
77//! index = tree.insert( 4, variable.clone(), Some( Box::new( Nodes::Leaf ) ), None ).unwrap();
78//! tree.data_mut( index ).unwrap().push( Box::new( "2".to_string() ) );
79//! assert_eq!( tree.count(), 9, "9 nodes are present." );
80//! ```
81//! [`Tree`]: Tree
82//! [`Any`]: core::any::Any
83//! [`data_mut`]: Tree::data_mut
84//! [`data_ref`]: Tree::data_ref
85//! [`ALLOW_CHILDREN`]: ALLOW_CHILDREN
86//! [`ALLOW_DATA`]: ALLOW_DATA
87//! [`insert`]: Tree::insert
88//! [`insert_at`]: Tree::insert_at
89//! [`core::error::Error`]: core::error::Error
90
91pub mod tree;
92pub use crate::tree::*;
93pub mod error;
94pub use error::*;