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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//! ### is-tree
//! 
//! Convert everything into a tree structure that supports multi-type visitors for tree iterators and relative access.
//! 
//! ### Fully-featured example
//! 
//! ```rust
//! use is_tree::*;
//! 
//! visitor! {
//!     pub enum Visitors, VisitorsMut {
//!         Root(Library visits [Module]),
//!         Branches(
//!             Module visits [Module, Function],
//!             Function
//!         )
//!     }
//! }
//! 
//! #[derive(Debug, IsTree)]
//! pub struct Library {
//!     #[tree(path_segment)]
//!     #[tree(branch(String))]
//!     pub name: String,
//!     #[tree(branch(Module, String))]
//!     pub root_module: Module
//! }
//! 
//! #[derive(Debug, Default, IsTree)]
//! pub struct Function {
//!     #[tree(path_segment)]
//!     #[tree(branch(String))]
//!     pub name: String
//! }
//! 
//! #[derive(Debug, Default, IsTree)]
//! pub struct Module {
//!     #[tree(path_segment)]
//!     #[tree(branch(String))]
//!     pub name: String,
//!     #[tree(branch(Module, String))]
//!     pub modules: Vec<Module>,
//!     #[tree(branch(Function, String))]
//!     pub functions: Vec<Function>
//! }
//! 
//! // AddBranch<T> is logic-dependent so you need to implement it yourself.
//! impl AddBranch<Module> for Library {
//!     fn add_branch(&mut self, module: Module) -> &mut Module {
//!         self.root_module = module;
//!         &mut self.root_module
//!     }
//! }
//! 
//! impl AddBranch<String> for Library {
//!     fn add_branch(&mut self, name: String) -> &mut String {
//!         self.name = name;
//!         &mut self.name
//!     }
//! }
//! 
//! impl AddBranch<Module> for Module {
//!     fn add_branch(&mut self, branch: Module) -> &mut Module {
//!         self.modules.push(branch);
//!         self.modules.last_mut().unwrap()
//!     }
//! }
//! 
//! impl AddBranch<Function> for Module {
//!     fn add_branch(&mut self, branch: Function) -> &mut Function {
//!         self.functions.push(branch);
//!         self.functions.last_mut().unwrap()
//!     }
//! }
//! 
//! impl AddBranch<String> for Module {
//!     fn add_branch(&mut self, name: String) -> &mut String {
//!         self.name = name;
//!         &mut self.name
//!     }
//! }
//! 
//! impl Library {
//!     pub fn mock() -> Self {
//!         Library {
//!             name: String::from("library"),
//!             root_module: Module {
//!                 name: String::from("math"),
//!                 modules: vec![
//!                     Module {
//!                         name: String::from("geometry"),
//!                         modules: vec![Module { name: String::from("shapes"), .. Default::default() }],
//!                         .. Default::default()
//!                     },
//!                     Module {
//!                         name: String::from("algebra"),
//!                         functions: vec![Function { name: String::from("exponential") }],
//!                         .. Default::default()
//!                     },
//!                 ],
//!                 .. Default::default()
//!             },
//!         }
//!     }
//! }
//! 
//! fn main() {
//!     let mut library = Library::mock();
//!     
//!     // Getting the String branches of the structure.
//!     library.branches_mut::<&mut String>().for_each(|s| *s = s.to_uppercase());
//!     library.branches::<&String>().for_each(|s| println!("{}", s));
//! 
//!     // Getting a Module of the structure.
//!     library.get_mut::<&mut Module>("MATH").unwrap().name.push_str("EMATICS");
//!     println!("{}", library.get::<&Module>("MATHEMATICS").unwrap().name);
//! 
//!     // Getting an mutable tree visitor.
//!     let iterator: TreeIterator<VisitorsMut> = TreeIterator::new(&mut library);
//!     iterator.for_each(|mut visitor| {
//!         match &mut visitor {
//!             VisitorsMut::Library(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
//!             VisitorsMut::Module(visitor) => visitor.value.name = visitor.value.name.to_lowercase(),
//!             VisitorsMut::Function(visitor) => visitor.value.name = visitor.value.name.to_lowercase()
//!         }
//!     });
//! 
//!     // Getting a constant tree visitor.
//!     let iterator: TreeIterator<Visitors> = TreeIterator::new(&library);
//!     iterator.for_each(|visitor| println!("{}", visitor.path_segment()));
//! 
//!     // Getting the root visitor.
//!     let root_visitor = Visitors::from(&library);
//! 
//!      // Root don't have a parent.
//!     assert!(root_visitor.parent().is_none());
//! 
//!     // Root is the root of the structure.
//!     assert_eq!(root_visitor.root().as_library().unwrap().value.name, "library");
//! 
//!     // "self", "super" amd "root" are special path segments.
//!     assert_eq!(root_visitor.relative(vec!["self"]).unwrap().path(), Path::from(vec!["library"]));
//! 
//!     // Accessing Module structure.
//!     assert_eq!(root_visitor.relative(vec!["mathematics"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
//! 
//!     // Using "super".
//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "super"]).unwrap().as_module().unwrap().value.name, "mathematics"); 
//! 
//!     // Access a Function structure.
//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential"]).unwrap().as_function().unwrap().value.name, "exponential"); 
//! 
//!     // This is allowed.
//!     assert_eq!(root_visitor.relative(vec!["mathematics", "algebra", "exponential", "root"]).unwrap().as_library().unwrap().value.name, "library"); 
//! 
//!     // Mutably accessing the visitor's parent is unsafe because it allows you to get two mutable references to the same object.
//!     unsafe {
//!         let mut root_visitor = VisitorsMut::from(&mut library);
//! 
//!         assert!(root_visitor.parent_mut().is_none());
//! 
//!         root_visitor.root_mut().as_library_mut().unwrap().value.name = "LIBRARY".into();
//! 
//!         root_visitor.relative_mut(vec!["mathematics"]).unwrap().as_module_mut().unwrap().value.name = "MATHEMATICS".into(); 
//!     }
//! }
//! ```
//! 

pub mod prelude;

pub mod traits;
pub mod path;
pub mod visitor;
pub mod tree_iterator;
pub mod unsafe_;

pub use traits::*;
pub use path::*;
pub use visitor::*;
pub use tree_iterator::*;

pub use is_tree_macro::*;

pub mod visitor_macro;