1use crate::{
4 traversal::TraverseOwned, Asynchronous, InPostOwned, InPreOwned, Node, PrePostOwned,
5 Synchronous, TraverseMut,
6};
7use std::marker::PhantomData;
8
9impl<T> TraverseOwned<T, Synchronous>
10where
11 T: Sync + Send,
12{
13 pub fn into_async(self) -> TraverseOwned<T, Asynchronous> {
14 TraverseOwned::<T, Asynchronous>::from(self)
15 }
16}
17
18impl<T> TraverseOwned<T, Synchronous> {
19 pub(crate) fn new(node: Node<T>) -> Self {
20 Self {
21 node,
22 strategy: PhantomData,
23 }
24 }
25
26 pub fn for_each<F>(self, mut f: F)
28 where
29 F: FnMut(T),
30 {
31 pub fn for_each_immersion<T, F>(root: Node<T>, f: &mut F)
32 where
33 F: FnMut(T),
34 {
35 root.children
36 .into_iter()
37 .for_each(|node| for_each_immersion(node, f));
38
39 f(root.value)
40 }
41
42 for_each_immersion(self.node, &mut f);
43 }
44
45 pub fn map<F, R>(self, mut f: F) -> TraverseOwned<R, Synchronous>
47 where
48 F: FnMut(T, &mut [Node<T>]) -> R,
49 {
50 pub fn map_immersion<T, F, R>(mut root: Node<T>, f: &mut F) -> Node<R>
51 where
52 F: FnMut(T, &mut [Node<T>]) -> R,
53 {
54 Node::new(f(root.value, &mut root.children)).with_children(
55 root.children
56 .into_iter()
57 .map(|child| map_immersion::<T, F, R>(child, f))
58 .collect(),
59 )
60 }
61
62 TraverseOwned::new(map_immersion::<T, F, R>(self.node, &mut f))
63 }
64
65 pub fn reduce<F, R>(self, mut f: F) -> R
67 where
68 F: FnMut(T, Vec<R>) -> R,
69 R: Sized,
70 {
71 fn reduce_immersion<T, F, R>(root: Node<T>, f: &mut F) -> R
72 where
73 F: FnMut(T, Vec<R>) -> R,
74 {
75 let results = root
76 .children
77 .into_iter()
78 .map(|child| reduce_immersion(child, f))
79 .collect();
80
81 f(root.value, results)
82 }
83
84 reduce_immersion(self.node, &mut f)
85 }
86
87 pub fn cascade<F, R>(mut self, base: R, f: F) -> Self
89 where
90 F: FnMut(&mut Node<T>, &R) -> R,
91 R: Sized,
92 {
93 TraverseMut::new(&mut self.node).cascade(base, f);
94 self
95 }
96}
97
98impl<T> InPreOwned<T, Synchronous> {
99 pub fn map<R, F>(mut self, base: R, mut pre: F) -> Node<R>
101 where
102 F: FnMut(T, &R) -> R,
103 {
104 fn map_immersion<T, R, F>(root: Node<T>, base: &R, f: &mut F) -> Node<R>
105 where
106 F: FnMut(T, &R) -> R,
107 {
108 let parent = Node::new(f(root.value, base));
109 let children: Vec<Node<R>> = root
110 .children
111 .into_iter()
112 .map(|node| map_immersion(node, &parent.value, f))
113 .collect();
114
115 parent.with_children(children)
116 }
117
118 map_immersion(self.next.remove(0), &base, &mut pre)
119 }
120
121 pub fn cascade<F, R>(mut self, base: R, mut f: F) -> Self
123 where
124 F: FnMut(T, &R) -> R,
125 {
126 pub fn cascade_immersion<T, F, R>(root: Node<T>, base: &R, f: &mut F)
127 where
128 F: FnMut(T, &R) -> R,
129 {
130 let base = f(root.value, base);
131 root.children
132 .into_iter()
133 .for_each(|child| cascade_immersion(child, &base, f));
134 }
135
136 cascade_immersion(self.next.remove(0), &base, &mut f);
137 self
138 }
139}
140
141impl<T> InPostOwned<T, Synchronous> {
142 pub fn reduce<R, F>(mut self, mut post: F) -> R
145 where
146 F: FnMut(T, Vec<R>) -> R,
147 {
148 fn reduce_immersion<T, R, F>(root: Node<T>, f: &mut F) -> R
149 where
150 F: FnMut(T, Vec<R>) -> R,
151 {
152 let children: Vec<R> = root
153 .children
154 .into_iter()
155 .map(|node| reduce_immersion(node, f))
156 .collect();
157
158 f(root.value, children)
159 }
160
161 reduce_immersion(self.next.remove(0), &mut post)
162 }
163
164 pub fn map<R, F>(mut self, mut post: F) -> Node<R>
166 where
167 F: FnMut(T, &mut Vec<Node<R>>) -> R,
168 {
169 fn map_immersion<T, R, F>(root: Node<T>, f: &mut F) -> Node<R>
170 where
171 F: FnMut(T, &mut Vec<Node<R>>) -> R,
172 {
173 let mut children: Vec<Node<R>> = root
174 .children
175 .into_iter()
176 .map(|node| map_immersion(node, f))
177 .collect();
178
179 Node::new(f(root.value, &mut children)).with_children(children)
180 }
181
182 map_immersion(self.next.remove(0), &mut post)
183 }
184
185 pub fn with_pre<R, F>(mut self, pre: F) -> PrePostOwned<T, R, F, Synchronous>
187 where
188 F: FnMut(&mut Node<T>, &R) -> R,
189 {
190 PrePostOwned {
191 node: self.next.remove(0),
192 pre,
193 r: PhantomData,
194 strategy: PhantomData,
195 }
196 }
197}
198
199impl<T, R, F> PrePostOwned<T, R, F, Synchronous>
200where
201 F: FnMut(&mut Node<T>, &R) -> R,
202{
203 pub fn reduce<U, P>(mut self, base: R, mut post: P) -> U
206 where
207 P: FnMut(T, &R, Vec<U>) -> U,
208 {
209 fn reduce_immersion<T, R, U, F1, F2>(
210 mut root: Node<T>,
211 base: &R,
212 pre: &mut F1,
213 post: &mut F2,
214 ) -> U
215 where
216 F1: FnMut(&mut Node<T>, &R) -> R,
217 F2: FnMut(T, &R, Vec<U>) -> U,
218 {
219 let base = pre(&mut root, base);
220 let children: Vec<U> = root
221 .children
222 .into_iter()
223 .map(|node| reduce_immersion(node, &base, pre, post))
224 .collect();
225
226 post(root.value, &base, children)
227 }
228
229 reduce_immersion(self.node, &base, &mut self.pre, &mut post)
230 }
231
232 pub fn map<U, P>(mut self, base: R, mut post: P) -> Node<U>
235 where
236 P: FnMut(T, &R, &mut Vec<Node<U>>) -> U,
237 {
238 fn map_immersion<T, R, U, F1, F2>(
239 mut root: Node<T>,
240 base: &R,
241 pre: &mut F1,
242 post: &mut F2,
243 ) -> Node<U>
244 where
245 F1: FnMut(&mut Node<T>, &R) -> R,
246 F2: FnMut(T, &R, &mut Vec<Node<U>>) -> U,
247 {
248 let base = pre(&mut root, base);
249 let mut children: Vec<Node<U>> = root
250 .children
251 .into_iter()
252 .map(|node| map_immersion(node, &base, pre, post))
253 .collect();
254
255 Node::new(post(root.value, &base, &mut children)).with_children(children)
256 }
257
258 map_immersion(self.node, &base, &mut self.pre, &mut post)
259 }
260}
261
262#[cfg(test)]
263mod tests {
264 use super::*;
265 use crate::node;
266
267 #[test]
268 fn test_for_each() {
269 let root = node!(10_i32, node!(20, node!(40)), node!(30, node!(50)));
270
271 let mut result = Vec::new();
272 root.into_traverse().for_each(|value| result.push(value));
273
274 assert_eq!(result, vec![40, 20, 50, 30, 10]);
275 }
276
277 #[test]
278 fn test_map() {
279 let original = node!(1, node!(2, node!(4)), node!(3, node!(5)));
280 let new_root = original
281 .into_traverse()
282 .map(|value, children| value + children.len());
283
284 let want = node!(3, node!(3, node!(4)), node!(4, node!(5)));
285 assert_eq!(new_root.take(), want);
286 }
287
288 #[test]
289 fn test_reduce() {
290 let root = node!(1, node!(2, node!(4)), node!(3, node!(5)));
291 let sum = root.into_traverse().reduce(|value, results| {
292 value + results.len() as isize + results.iter().sum::<isize>()
293 });
294
295 assert_eq!(sum, 19);
296 }
297
298 #[test]
299 fn test_cascade() {
300 let root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
301 let root = root
302 .into_traverse()
303 .cascade(0, |n, parent_value| {
304 let next = n.value + parent_value;
305 n.value = *parent_value;
306 next
307 })
308 .take();
309
310 let want = node!(0, node!(10, node!(30)), node!(10, node!(40)));
311 assert_eq!(root, want);
312 }
313
314 #[test]
315 fn test_cascade_pre() {
316 let root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
317
318 let mut result = Vec::new();
319 root.into_traverse().pre().cascade(0, |current, parent| {
320 result.push(current + *parent);
321 current + *parent
322 });
323
324 assert_eq!(result, vec![10, 30, 70, 40, 90]);
325 }
326
327 #[test]
328 fn test_map_pre() {
329 let original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
330
331 let new_root = original
332 .into_traverse()
333 .pre()
334 .map(true, |child, parent| *parent && child % 2 != 0);
335
336 let want = node!(true, node!(false, node!(false)), node!(true, node!(true)));
337 assert_eq!(new_root, want);
338 }
339
340 #[test]
341 fn test_reduce_post() {
342 let root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
343
344 let mut result = Vec::new();
345 root.into_traverse().post().reduce(|current, children| {
346 result.push(current + children.len());
347 current + children.len()
348 });
349
350 assert_eq!(result, vec![40, 21, 50, 31, 12]);
351 }
352
353 #[test]
354 fn test_map_post() {
355 let original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
356
357 let new_root = original
358 .into_traverse()
359 .post()
360 .map(|current, _| current % 2 != 0);
361
362 let want = node!(true, node!(false, node!(true)), node!(true, node!(true)));
363 assert_eq!(new_root, want);
364 }
365
366 #[test]
367 fn test_reduce_pre_post() {
368 let root = node!(10, node!(20, node!(40)), node!(30, node!(50)));
369
370 let mut result = Vec::new();
371 root.into_traverse()
372 .post()
373 .with_pre(|current, base| current.value + *base)
374 .reduce(0, |_, base, children| {
375 result.push(children.len() + base);
376 children.len() + base
377 });
378
379 assert_eq!(result, vec![70, 31, 90, 41, 12]);
380 }
381
382 #[test]
383 fn test_map_pre_post() {
384 let original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
385 let new_root = original
386 .into_traverse()
387 .post()
388 .with_pre(|current, base| current.value + *base)
389 .map(0, |_, base, _| base % 2 == 0);
390
391 let want = node!(false, node!(false, node!(true)), node!(true, node!(false)));
392 assert_eq!(new_root, want);
393 }
394
395 }