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
//! [![](https://dcbadge.vercel.app/api/server/rzaesS82MT)](https://discord.gg/rzaesS82MT)
//!
//! ### 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)] // Any ToString can go here.
//!     pub name: String,
//!     #[tree(branch)] // If we want only this to be a branch.
//!     pub root_module: Module
//! }
//!
//! #[derive(Debug, Default, IsTree)]
//! #[tree(branches)] // This will make all fields branches.
//! pub struct Module {
//!     #[tree(path_segment)]
//!     pub name: String,
//!     pub modules: Vec<Module>,
//!     pub functions: Vec<Function>
//! }

//! 
//! #[derive(Debug, Default, IsTree)]
//! #[tree(branches)] 
//! pub struct Function {
//!     #[tree(path_segment)]
//!     pub name: String
//! }
//! 
//! 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 Module branches of the structure.
//!     library.branches_mut::<&mut Module>().for_each(|module| module.name = module.name.to_uppercase());
//!     library.branches::<&Module>().for_each(|module| println!("{}", module.name));
//! 
//!     // 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;