1#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)]
2#![allow(clippy::module_name_repetitions, clippy::ignored_unit_patterns)]
3#![forbid(unsafe_code)]
4#![doc = include_str!("../DOC.md")]
5
6mod nesting_function;
7#[cfg(feature = "vec")]
8mod tree;
9#[cfg(feature = "deque")]
10mod tree_deque;
11
12pub use nesting_function::*;
13#[cfg(feature = "vec")]
14pub use tree::*;
15#[cfg(feature = "deque")]
16pub use tree_deque::*;
17
18#[cfg(test)]
19mod tests {
20 #![allow(unused)]
21 use super::{Nesting, NestingFunction};
22
23 #[derive(Debug, Default)]
24 struct StackController<T> {
25 stack: Vec<T>,
26 }
27
28 impl<T> StackController<T> {
29 pub fn is_empty(&self) -> bool {
30 self.stack.is_empty()
31 }
32 }
33
34 impl NestingFunction<char> for &mut StackController<char> {
35 fn direction(&mut self, item: &char) -> Nesting {
36 let &c = item;
37 match c {
38 '<' | '(' => {
39 self.stack.push(c);
40 Nesting::Increase
41 }
42 '>' =>
43 {
44 #[allow(clippy::unwrap_used)]
45 if !self.stack.is_empty() && self.stack.last().unwrap() == &'<' {
46 self.stack.pop();
47 Nesting::Decrease
48 } else {
49 Nesting::Maintain
50 }
51 }
52 ')' =>
53 {
54 #[allow(clippy::unwrap_used)]
55 if !self.stack.is_empty() && self.stack.last().unwrap() == &'(' {
56 self.stack.pop();
57 Nesting::Decrease
58 } else {
59 Nesting::Maintain
60 }
61 }
62 _ => Nesting::Maintain,
63 }
64 }
65 }
66
67 #[cfg(feature = "vec")]
68 mod vec {
69 use super::*;
70 use crate::{IntoTreeExt, Tree};
71
72 #[test]
73 fn basic() {
74 let tree: Tree<char> = "a * ( (d + b) * c ) + e"
75 .chars()
76 .filter(|&c: &char| !c.is_whitespace())
77 .into_tree(|&c: &char| match c {
78 '(' => Nesting::Increase,
79 ')' => Nesting::Decrease,
80 _ => Nesting::Maintain,
81 });
82
83 println!("{tree:#?}");
84 }
85
86 #[test]
87 fn iter() {
88 let before = String::from("a+(b+c)+d");
89
90 let tree = before.chars().into_tree(|&item: &char| match item {
91 '(' => Nesting::Increase,
92 ')' => Nesting::Decrease,
93 _ => Nesting::Maintain,
94 });
95
96 let after: String = tree.into_iter().collect();
97
98 assert_eq!(before, after);
99 }
100
101 #[test]
102 fn with_fn_mut() {
103 let mut depth = 0;
104
105 let tree: Tree<char> = "a+(b+c)+d".chars().into_tree(|&item: &char| match item {
106 '(' => {
107 depth += 1;
108 Nesting::Increase
109 }
110 ')' => {
111 depth -= 1;
112 Nesting::Decrease
113 }
114 _ => Nesting::Maintain,
115 });
116
117 assert!(depth == 0);
118
119 println!("{tree:#?}");
120 }
121
122 #[test]
123 fn correct_stack() {
124 let mut parser = StackController::default();
125
126 let td = "< ( < > ) >"
127 .chars()
128 .filter(|c| !c.is_whitespace())
129 .into_tree(&mut parser);
130
131 println!("{td:#?}");
132
133 assert!(parser.is_empty());
134 }
135
136 #[test]
137 fn incorrect_stack() {
138 let mut parser = StackController::default();
139
140 let td = "<(>)".chars().into_tree(&mut parser);
141
142 println!("{td:#?}");
143
144 assert!(!parser.is_empty());
145 }
146 }
147
148 #[cfg(feature = "deque")]
149 mod deque {
150 use super::*;
151 use crate::{IntoTreeDequeExt, TreeDeque};
152
153 #[test]
154 fn basic() {
155 let tree: TreeDeque<char> = "a * ( (d + b) * c ) + e"
156 .chars()
157 .filter(|&c: &char| !c.is_whitespace())
158 .into_tree_deque(|&c: &char| match c {
159 '(' => Nesting::Increase,
160 ')' => Nesting::Decrease,
161 _ => Nesting::Maintain,
162 });
163
164 println!("{tree:#?}");
165 }
166
167 #[test]
168 fn iter() {
169 let before = String::from("a+(b+c)+d");
170
171 let tree = before.chars().into_tree_deque(|&item: &char| match item {
172 '(' => Nesting::Increase,
173 ')' => Nesting::Decrease,
174 _ => Nesting::Maintain,
175 });
176
177 let after: String = tree.into_iter().collect();
178
179 assert_eq!(before, after);
180 }
181
182 #[test]
183 fn correct_stack() {
184 let mut parser = StackController::default();
185
186 let td = "< ( < > ) >"
187 .chars()
188 .filter(|c| !c.is_whitespace())
189 .into_tree_deque(&mut parser);
190
191 println!("{td:#?}");
192
193 assert!(parser.is_empty());
194 }
195
196 #[test]
197 fn incorrect_stack() {
198 let mut parser = StackController::default();
199
200 let td = "<(>)".chars().into_tree_deque(&mut parser);
201
202 println!("{td:#?}");
203
204 assert!(!parser.is_empty());
205 }
206 }
207}