ntree_rs/traversal/traverse_owned/
sync.rs

1//! Synchronous traversal implementation.
2
3use 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    /// Traverses the tree rooted by self in `post-order`, calling the given closure along the way.
27    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    /// Traverses the tree rooted by self in `pre-order`, building a new tree by calling the given closure along the way.
46    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    /// Traverses the tree rooted by self in `post-order`, calling the given closure along the way and providing its results from children to parent.
66    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    /// Traverses the tree rooted by self in `pre-order`, calling the given closure along the way and providing its result from parent to children.
88    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    /// Traverses the tree in `pre-order`, building a new tree by calling the given closure along the way.
100    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    /// Traverses the tree rooted by self in `pre-order`, calling the given closure along the way and providing its result from parent to children.
122    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    /// Traverses the tree in post-order calling the associated closure.
143    /// Returns the latest result given by that closure, which value correspond to the root of the tree.
144    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    /// Traverses the tree in `post-order`, building a new tree by calling the given closure along the way.
165    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    /// Determines a closure to be executed in `pre-order` when traversing the tree.
186    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    /// Traverses the tree calling both associated closures when corresponding.
204    /// Returns the latest result given by the post closure, which value correspond to the root of the tree.
205    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    /// Traverses the tree in both orders, building a new tree by calling the post closure along the way.
233    /// Returns the latest result given by the post closure, which value correspond to the root of the tree.
234    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    // #[test]
396    // fn test_owned_lifetime() {
397    //     struct Context<'a> {
398    //         parent: Option<&'a Context<'a>>,
399    //     }
400
401    //     impl<'a> Context<'a> {
402    //         fn clone(&'a self) -> Self {
403    //             Self { parent: Some(self) }
404    //         }
405    //     }
406
407    //     let ctx = Context { parent: None };
408    //     let original = node!(1, node!(2, node!(5)), node!(3, node!(5)));
409    //     let new_root = original
410    //         .into_traverse()
411    //         .post()
412    //         .with_pre(|current, ctx| ctx.clone())
413    //         .map(ctx, |_, ctx, _| ctx.parent.is_some());
414    // }
415}