is_tree/
lib.rs

1//! [![](https://dcbadge.vercel.app/api/server/rzaesS82MT)](https://discord.gg/rzaesS82MT)
2//!
3//! ### is-tree
4//! 
5//! Convert everything into a tree structure that supports multi-type visitors for tree iterators and relative access.
6//! 
7//! ### Fully-featured example
8//! 
9//! ```rust
10//! use is_tree::*;
11//! 
12//! visitor! {
13//!     pub enum Visitors, VisitorsMut {
14//!         Root(Library visits [Module]),
15//!         Branches(
16//!             Module visits [Module, Function],
17//!             Function
18//!         )
19//!     }
20//! }
21//! 
22//! #[derive(Debug, IsTree)]
23//! pub struct Library {
24//!     #[tree(path_segment)] // Any ToString can go here.
25//!     pub name: String,
26//!     #[tree(branch)] // If we want only this to be a branch.
27//!     pub root_module: Module
28//! }
29//!
30//! #[derive(Debug, Default, IsTree)]
31//! #[tree(branches)] // This will make all fields branches.
32//! pub struct Module {
33//!     #[tree(path_segment)]
34//!     pub name: String,
35//!     pub modules: Vec<Module>,
36//!     pub functions: Vec<Function>
37//! }
38
39//! 
40//! #[derive(Debug, Default, IsTree)]
41//! #[tree(branches)] 
42//! pub struct Function {
43//!     #[tree(path_segment)]
44//!     pub name: String
45//! }
46//! 
47//! impl Library {
48//!     pub fn mock() -> Self {
49//!         Library {
50//!             name: String::from("library"),
51//!             root_module: Module {
52//!                 name: String::from("math"),
53//!                 modules: vec![
54//!                     Module {
55//!                         name: String::from("geometry"),
56//!                         modules: vec![Module { name: String::from("shapes"), .. Default::default() }],
57//!                         .. Default::default()
58//!                     },
59//!                     Module {
60//!                         name: String::from("algebra"),
61//!                         functions: vec![Function { name: String::from("exponential") }],
62//!                         .. Default::default()
63//!                     },
64//!                 ],
65//!                 .. Default::default()
66//!             },
67//!         }
68//!     }
69//! }
70//! 
71//! fn main() {
72//!     let mut library = Library::mock();
73//!     
74//!     // Getting the Module branches of the structure.
75//!     library.branches_mut::<&mut Module>().for_each(|module| module.name = module.name.to_uppercase());
76//!     library.branches::<&Module>().for_each(|module| println!("{}", module.name));
77//! 
78//!     // Getting a Module of the structure.
79//!     library.get_mut::<&mut Module>("MATH").unwrap().name.push_str("EMATICS");
80//!     println!("{}", library.get::<&Module>("MATHEMATICS").unwrap().name);
81//! 
82//!     // Getting an mutable tree visitor.
83//!     let iterator: TreeIterator<VisitorsMut> = TreeIterator::new(&mut library);
84//!     iterator.for_each(|mut visitor| {
85//!         match &mut visitor {
86//!             VisitorsMut::Library(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
87//!             VisitorsMut::Module(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
88//!             VisitorsMut::Function(visitor) => visitor.value.name = visitor.value.name.to_lowercase()
89//!         }
90//!     });
91//! 
92//!     // Getting a constant tree visitor.
93//!     let iterator: TreeIterator<Visitors> = TreeIterator::new(&library);
94//!     iterator.for_each(|visitor| println!("{}", visitor.path_segment()));
95//! 
96//!     // Getting the root visitor.
97//!     let root_visitor = Visitors::from(&library);
98//! 
99//!      // Root don't have a parent.
100//!     assert!(root_visitor.parent().is_none());
101//! 
102//!     // Root is the root of the structure.
103//!     assert_eq!(root_visitor.root().as_library().unwrap().value.name, "library");
104//! 
105//!     // "self", "super" amd "root" are special path segments.
106//!     assert_eq!(root_visitor.relative(vec!["self"]).unwrap().path(), Path::from(vec!["library"]));
107//! 
108//!     // Accessing Module structure.
109//!     assert_eq!(root_visitor.relative(vec!["mathematics"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
110//! 
111//!     // Using "super".
112//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "super"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
113//! 
114//!     // Access a Function structure.
115//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential"]).unwrap().as_function().unwrap().value.name, "exponential"); 
116//! 
117//!     // This is allowed.
118//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential", "root"]).unwrap().as_library().unwrap().value.name, "library"); 
119//! 
120//!     // Mutably accessing the visitor's parent is unsafe because it allows you to get two mutable references to the same object.
121//!     unsafe {
122//!         let mut root_visitor = VisitorsMut::from(&mut library);
123//! 
124//!         assert!(root_visitor.parent_mut().is_none());
125//! 
126//!         root_visitor.root_mut().as_library_mut().unwrap().value.name = "LIBRARY".into();
127//! 
128//!         root_visitor.relative_mut(vec!["mathematics"]).unwrap().as_module_mut().unwrap().value.name = "MATHEMATICS".into(); 
129//!     }
130//! }
131//! ```
132//! 
133
134pub mod prelude;
135
136pub mod traits;
137pub mod path;
138pub mod visitor;
139pub mod tree_iterator;
140pub mod unsafe_;
141
142pub use traits::*;
143pub use path::*;
144pub use visitor::*;
145pub use tree_iterator::*;
146
147pub use is_tree_macro::*;
148
149pub mod visitor_macro;