1use crate::{
4 traversal::{macros, TraverseMut},
5 Asynchronous, InPostMut, InPreMut, Node, PrePostMut, Synchronous,
6};
7use std::marker::PhantomData;
8
9impl<'a, T> TraverseMut<'a, T, Synchronous>
10where
11 T: Sync + Send,
12{
13 pub fn into_async(self) -> TraverseMut<'a, T, Asynchronous> {
14 TraverseMut::<'a, T, Asynchronous>::from(self)
15 }
16}
17
18impl<'a, T> TraverseMut<'a, T, Synchronous> {
19 pub(crate) fn new(node: &'a mut Node<T>) -> Self {
20 Self {
21 node,
22 strategy: PhantomData,
23 }
24 }
25
26 macros::for_each!(&mut Node<T>, iter_mut);
27 macros::map!(&mut Node<T>, iter_mut);
28 macros::reduce!(&mut Node<T>, iter_mut);
29 macros::cascade!(&mut Node<T>, iter_mut);
30}
31
32impl<'a, T> InPreMut<'a, T, Synchronous> {
33 macros::map_pre!(&mut Node<T>, iter_mut);
34 macros::cascade!(&mut Node<T>, iter_mut);
35}
36
37impl<'a, T, S> InPostMut<'a, T, S> {
38 macros::reduce!(&mut Node<T>, iter_mut);
39 macros::map_post!(&mut Node<T>, iter_mut);
40
41 pub fn with_pre<R, F>(self, pre: F) -> PrePostMut<'a, T, R, F, Synchronous>
43 where
44 F: FnMut(&mut Node<T>, &R) -> R,
45 {
46 PrePostMut {
47 node: self.node,
48 pre,
49 r: PhantomData,
50 strategy: PhantomData,
51 }
52 }
53}
54
55impl<'a, T, R, F> PrePostMut<'a, T, R, F, Synchronous>
56where
57 F: FnMut(&mut Node<T>, &R) -> R,
58{
59 macros::reduce_pre_post!(&mut Node<T>, iter_mut);
60 macros::map_pre_post!(&mut Node<T>, iter_mut);
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use crate::node;
67
68 #[test]
69 fn test_for_each() {
70 let mut root = node!(10_i32, node!(20, node!(40)), node!(30, node!(50)));
71
72 let mut result = Vec::new();
73 root.traverse_mut().for_each(|n| {
74 n.value = n.value.saturating_add(1);
75 result.push(n.value)
76 });
77
78 assert_eq!(result, vec![41, 21, 51, 31, 11]);
79 }
80
81 #[test]
82 fn test_map() {
83 let mut original = node!(1, node!(2, node!(4)), node!(3, node!(5)));
84 let new_root = original.traverse_mut().map(|n| {
85 n.value += 1;
86 n.value % 2 == 0
87 });
88
89 let want = node!(2, node!(3, node!(5)), node!(4, node!(6)));
90 assert_eq!(original, want);
91
92 let want = node!(true, node!(false, node!(false)), node!(true, node!(true)));
93 assert_eq!(new_root.take(), want);
94 }
95
96 #[test]
97 fn test_reduce() {
98 let mut root = node!(10_i32, node!(20, node!(40)), node!(30, node!(50)));
99
100 let sum = root.traverse_mut().reduce(|n, results| {
101 n.value = n.value.saturating_add(1);
102 n.value + results.iter().sum::<i32>()
103 });
104
105 assert_eq!(sum, 155);
106 }
107
108 #[test]
109 fn test_cascade() {
110 let mut root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
111
112 root.traverse_mut().cascade(0, |n, parent_value| {
113 let next = n.value + parent_value;
114 n.value = *parent_value;
115 next
116 });
117
118 let want = node!(0, node!(10, node!(30)), node!(10, node!(40)));
119 assert_eq!(root, want);
120 }
121
122 #[test]
123 fn test_cascade_pre() {
124 let mut root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
125
126 let mut result = Vec::new();
127 root.traverse_mut().pre().cascade(0, |current, parent| {
128 result.push(current.value + *parent);
129 current.value += 1;
130
131 current.value + *parent
132 });
133
134 assert_eq!(result, vec![10, 31, 72, 41, 92]);
135
136 let want = node!(11, node!(21, node!(41)), node!(31, node!(51)));
137 assert_eq!(root, want);
138 }
139
140 #[test]
141 fn test_map_pre() {
142 let mut original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
143 let new_root = original.traverse_mut().pre().map(true, |child, parent| {
144 child.value += 1;
145 *parent && child.value % 2 == 0
146 });
147
148 let want = node!(2, node!(3, node!(6)), node!(4, node!(6)));
149 assert_eq!(original, want);
150
151 let want = node!(true, node!(false, node!(false)), node!(true, node!(true)));
152 assert_eq!(new_root, want);
153 }
154
155 #[test]
156 fn test_reduce_post() {
157 let mut root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
158
159 let mut result = Vec::new();
160 root.traverse_mut().post().reduce(|current, children| {
161 result.push(current.value + children.len());
162 current.value += 1;
163 current.value + children.len()
164 });
165
166 assert_eq!(result, vec![40, 21, 50, 31, 12]);
167
168 let want = node!(11, node!(21, node!(41)), node!(31, node!(51)));
169 assert_eq!(root, want);
170 }
171
172 #[test]
173 fn test_map_post() {
174 let mut original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
175 let new_root = original.traverse_mut().post().map(|current, _| {
176 current.value += 1;
177 current.value % 2 == 0
178 });
179
180 let want = node!(true, node!(false, node!(true)), node!(true, node!(true)));
181 assert_eq!(new_root, want);
182
183 let want = node!(2, node!(3, node!(6)), node!(4, node!(6)));
184 assert_eq!(original, want);
185 }
186
187 #[test]
188 fn test_reduce_pre_post() {
189 let mut root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
190
191 let mut result = Vec::new();
192 root.traverse_mut()
193 .post()
194 .with_pre(|current, base| {
195 current.value += 1;
196 current.value + base
197 })
198 .reduce(0, |current, base, children| {
199 result.push(current.value + children.len() + base);
200 current.value += 1;
201 current.value + children.len() + base
202 });
203
204 assert_eq!(result, vec![114, 54, 144, 74, 24]);
205
206 let want = node!(12, node!(22, node!(42)), node!(32, node!(52)));
207 assert_eq!(root, want);
208 }
209
210 #[test]
211 fn test_map_pre_post() {
212 let mut original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
213
214 let new_root = original
215 .traverse_mut()
216 .post()
217 .with_pre(|current, base| {
218 current.value += 1;
219 current.value + base
220 })
221 .map(0, |current, base, _| {
222 current.value += 1;
223 current.value % 2 != 0 && base % 2 == 0
224 });
225
226 let want = node!(true, node!(false, node!(false)), node!(true, node!(true)));
227 assert_eq!(new_root, want);
228
229 let want = node!(3, node!(4, node!(7)), node!(5, node!(7)));
230 assert_eq!(original, want);
231 }
232}