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