datafusion_common/
tree_node.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! [`TreeNode`] for visiting and rewriting expression and plan trees
19
20use crate::Result;
21use std::collections::HashMap;
22use std::hash::Hash;
23use std::sync::Arc;
24
25/// These macros are used to determine continuation during transforming traversals.
26macro_rules! handle_transform_recursion {
27    ($F_DOWN:expr, $F_CHILD:expr, $F_UP:expr) => {{
28        $F_DOWN?
29            .transform_children(|n| n.map_children($F_CHILD))?
30            .transform_parent($F_UP)
31    }};
32}
33
34/// API for inspecting and rewriting tree data structures.
35///
36/// The `TreeNode` API is used to express algorithms separately from traversing
37/// the structure of `TreeNode`s, avoiding substantial code duplication.
38///
39/// This trait is implemented for plans ([`ExecutionPlan`], [`LogicalPlan`]) and
40/// expression trees ([`PhysicalExpr`], [`Expr`]) as well as Plan+Payload
41/// combinations [`PlanContext`] and [`ExprContext`].
42///
43/// # Overview
44/// There are three categories of TreeNode APIs:
45///
46/// 1. "Inspecting" APIs to traverse a tree of `&TreeNodes`:
47///    [`apply`], [`visit`], [`exists`].
48///
49/// 2. "Transforming" APIs that traverse and consume a tree of `TreeNode`s
50///    producing possibly changed `TreeNode`s: [`transform`], [`transform_up`],
51///    [`transform_down`], [`transform_down_up`], and [`rewrite`].
52///
53/// 3. Internal APIs used to implement the `TreeNode` API: [`apply_children`],
54///    and [`map_children`].
55///
56/// | Traversal Order | Inspecting | Transforming |
57/// | --- | --- | --- |
58/// | top-down | [`apply`], [`exists`] | [`transform_down`]|
59/// | bottom-up | | [`transform`] , [`transform_up`]|
60/// | combined with separate `f_down` and `f_up` closures | | [`transform_down_up`] |
61/// | combined with `f_down()` and `f_up()` in an object | [`visit`]  | [`rewrite`] |
62///
63/// **Note**:while there is currently no in-place mutation API that uses `&mut
64/// TreeNode`, the transforming APIs are efficient and optimized to avoid
65/// cloning.
66///
67/// [`apply`]: Self::apply
68/// [`visit`]: Self::visit
69/// [`exists`]: Self::exists
70/// [`transform`]: Self::transform
71/// [`transform_up`]: Self::transform_up
72/// [`transform_down`]: Self::transform_down
73/// [`transform_down_up`]: Self::transform_down_up
74/// [`rewrite`]: Self::rewrite
75/// [`apply_children`]: Self::apply_children
76/// [`map_children`]: Self::map_children
77///
78/// # Terminology
79/// The following terms are used in this trait
80///
81/// * `f_down`: Invoked before any children of the current node are visited.
82/// * `f_up`: Invoked after all children of the current node are visited.
83/// * `f`: closure that is applied to the current node.
84/// * `map_*`: applies a transformation to rewrite owned nodes
85/// * `apply_*`:  invokes a function on borrowed nodes
86/// * `transform_`: applies a transformation to rewrite owned nodes
87///
88/// <!-- Since these are in the datafusion-common crate, can't use intra doc links) -->
89/// [`ExecutionPlan`]: https://docs.rs/datafusion/latest/datafusion/physical_plan/trait.ExecutionPlan.html
90/// [`PhysicalExpr`]: https://docs.rs/datafusion/latest/datafusion/physical_plan/trait.PhysicalExpr.html
91/// [`LogicalPlan`]: https://docs.rs/datafusion-expr/latest/datafusion_expr/logical_plan/enum.LogicalPlan.html
92/// [`Expr`]: https://docs.rs/datafusion-expr/latest/datafusion_expr/expr/enum.Expr.html
93/// [`PlanContext`]: https://docs.rs/datafusion/latest/datafusion/physical_plan/tree_node/struct.PlanContext.html
94/// [`ExprContext`]: https://docs.rs/datafusion/latest/datafusion/physical_expr/tree_node/struct.ExprContext.html
95pub trait TreeNode: Sized {
96    /// Visit the tree node with a [`TreeNodeVisitor`], performing a
97    /// depth-first walk of the node and its children.
98    ///
99    /// [`TreeNodeVisitor::f_down()`] is called in top-down order (before
100    /// children are visited), [`TreeNodeVisitor::f_up()`] is called in
101    /// bottom-up order (after children are visited).
102    ///
103    /// # Return Value
104    /// Specifies how the tree walk ended. See [`TreeNodeRecursion`] for details.
105    ///
106    /// # See Also:
107    /// * [`Self::apply`] for inspecting nodes with a closure
108    /// * [`Self::rewrite`] to rewrite owned `TreeNode`s
109    ///
110    /// # Example
111    /// Consider the following tree structure:
112    /// ```text
113    /// ParentNode
114    ///    left: ChildNode1
115    ///    right: ChildNode2
116    /// ```
117    ///
118    /// Here, the nodes would be visited using the following order:
119    /// ```text
120    /// TreeNodeVisitor::f_down(ParentNode)
121    /// TreeNodeVisitor::f_down(ChildNode1)
122    /// TreeNodeVisitor::f_up(ChildNode1)
123    /// TreeNodeVisitor::f_down(ChildNode2)
124    /// TreeNodeVisitor::f_up(ChildNode2)
125    /// TreeNodeVisitor::f_up(ParentNode)
126    /// ```
127    #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
128    fn visit<'n, V: TreeNodeVisitor<'n, Node = Self>>(
129        &'n self,
130        visitor: &mut V,
131    ) -> Result<TreeNodeRecursion> {
132        visitor
133            .f_down(self)?
134            .visit_children(|| self.apply_children(|c| c.visit(visitor)))?
135            .visit_parent(|| visitor.f_up(self))
136    }
137
138    /// Rewrite the tree node with a [`TreeNodeRewriter`], performing a
139    /// depth-first walk of the node and its children.
140    ///
141    /// [`TreeNodeRewriter::f_down()`] is called in top-down order (before
142    /// children are visited), [`TreeNodeRewriter::f_up()`] is called in
143    /// bottom-up order (after children are visited).
144    ///
145    /// Note: If using the default [`TreeNodeRewriter::f_up`] or
146    /// [`TreeNodeRewriter::f_down`] that do nothing, consider using
147    /// [`Self::transform_down`] instead.
148    ///
149    /// # Return Value
150    /// The returns value specifies how the tree walk should proceed. See
151    /// [`TreeNodeRecursion`] for details. If an [`Err`] is returned, the
152    /// recursion stops immediately.
153    ///
154    /// # See Also
155    /// * [`Self::visit`] for inspecting (without modification) `TreeNode`s
156    /// * [Self::transform_down_up] for a top-down (pre-order) traversal.
157    /// * [Self::transform_down] for a top-down (pre-order) traversal.
158    /// * [`Self::transform_up`] for a bottom-up (post-order) traversal.
159    ///
160    /// # Example
161    /// Consider the following tree structure:
162    /// ```text
163    /// ParentNode
164    ///    left: ChildNode1
165    ///    right: ChildNode2
166    /// ```
167    ///
168    /// Here, the nodes would be visited using the following order:
169    /// ```text
170    /// TreeNodeRewriter::f_down(ParentNode)
171    /// TreeNodeRewriter::f_down(ChildNode1)
172    /// TreeNodeRewriter::f_up(ChildNode1)
173    /// TreeNodeRewriter::f_down(ChildNode2)
174    /// TreeNodeRewriter::f_up(ChildNode2)
175    /// TreeNodeRewriter::f_up(ParentNode)
176    /// ```
177    #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
178    fn rewrite<R: TreeNodeRewriter<Node = Self>>(
179        self,
180        rewriter: &mut R,
181    ) -> Result<Transformed<Self>> {
182        handle_transform_recursion!(rewriter.f_down(self), |c| c.rewrite(rewriter), |n| {
183            rewriter.f_up(n)
184        })
185    }
186
187    /// Applies `f` to the node then each of its children, recursively (a
188    /// top-down, pre-order traversal).
189    ///
190    /// The return [`TreeNodeRecursion`] controls the recursion and can cause
191    /// an early return.
192    ///
193    /// # See Also
194    /// * [`Self::transform_down`] for the equivalent transformation API.
195    /// * [`Self::visit`] for both top-down and bottom up traversal.
196    fn apply<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
197        &'n self,
198        mut f: F,
199    ) -> Result<TreeNodeRecursion> {
200        #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
201        fn apply_impl<'n, N: TreeNode, F: FnMut(&'n N) -> Result<TreeNodeRecursion>>(
202            node: &'n N,
203            f: &mut F,
204        ) -> Result<TreeNodeRecursion> {
205            f(node)?.visit_children(|| node.apply_children(|c| apply_impl(c, f)))
206        }
207
208        apply_impl(self, &mut f)
209    }
210
211    /// Recursively rewrite the node's children and then the node using `f`
212    /// (a bottom-up post-order traversal).
213    ///
214    /// A synonym of [`Self::transform_up`].
215    fn transform<F: FnMut(Self) -> Result<Transformed<Self>>>(
216        self,
217        f: F,
218    ) -> Result<Transformed<Self>> {
219        self.transform_up(f)
220    }
221
222    /// Recursively rewrite the tree using `f` in a top-down (pre-order)
223    /// fashion.
224    ///
225    /// `f` is applied to the node first, and then its children.
226    ///
227    /// # See Also
228    /// * [`Self::transform_up`] for a bottom-up (post-order) traversal.
229    /// * [Self::transform_down_up] for a combined traversal with closures
230    /// * [`Self::rewrite`] for a combined traversal with a visitor
231    fn transform_down<F: FnMut(Self) -> Result<Transformed<Self>>>(
232        self,
233        mut f: F,
234    ) -> Result<Transformed<Self>> {
235        #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
236        fn transform_down_impl<N: TreeNode, F: FnMut(N) -> Result<Transformed<N>>>(
237            node: N,
238            f: &mut F,
239        ) -> Result<Transformed<N>> {
240            f(node)?.transform_children(|n| n.map_children(|c| transform_down_impl(c, f)))
241        }
242
243        transform_down_impl(self, &mut f)
244    }
245
246    /// Recursively rewrite the node using `f` in a bottom-up (post-order)
247    /// fashion.
248    ///
249    /// `f` is applied to the node's  children first, and then to the node itself.
250    ///
251    /// # See Also
252    /// * [`Self::transform_down`] top-down (pre-order) traversal.
253    /// * [Self::transform_down_up] for a combined traversal with closures
254    /// * [`Self::rewrite`] for a combined traversal with a visitor
255    fn transform_up<F: FnMut(Self) -> Result<Transformed<Self>>>(
256        self,
257        mut f: F,
258    ) -> Result<Transformed<Self>> {
259        #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
260        fn transform_up_impl<N: TreeNode, F: FnMut(N) -> Result<Transformed<N>>>(
261            node: N,
262            f: &mut F,
263        ) -> Result<Transformed<N>> {
264            node.map_children(|c| transform_up_impl(c, f))?
265                .transform_parent(f)
266        }
267
268        transform_up_impl(self, &mut f)
269    }
270
271    /// Transforms the node using `f_down` while traversing the tree top-down
272    /// (pre-order), and using `f_up` while traversing the tree bottom-up
273    /// (post-order).
274    ///
275    /// The method behaves the same as calling [`Self::transform_down`] followed
276    /// by [`Self::transform_up`] on the same node. Use this method if you want
277    /// to start the `f_up` process right where `f_down` jumps. This can make
278    /// the whole process faster by reducing the number of `f_up` steps.
279    ///
280    /// # See Also
281    /// * [`Self::transform_up`] for a bottom-up (post-order) traversal.
282    /// * [Self::transform_down] for a top-down (pre-order) traversal.
283    /// * [`Self::rewrite`] for a combined traversal with a visitor
284    ///
285    /// # Example
286    /// Consider the following tree structure:
287    /// ```text
288    /// ParentNode
289    ///    left: ChildNode1
290    ///    right: ChildNode2
291    /// ```
292    ///
293    /// The nodes are visited using the following order:
294    /// ```text
295    /// f_down(ParentNode)
296    /// f_down(ChildNode1)
297    /// f_up(ChildNode1)
298    /// f_down(ChildNode2)
299    /// f_up(ChildNode2)
300    /// f_up(ParentNode)
301    /// ```
302    ///
303    /// See [`TreeNodeRecursion`] for more details on controlling the traversal.
304    ///
305    /// If `f_down` or `f_up` returns [`Err`], the recursion stops immediately.
306    ///
307    /// Example:
308    /// ```text
309    ///                                               |   +---+
310    ///                                               |   | J |
311    ///                                               |   +---+
312    ///                                               |     |
313    ///                                               |   +---+
314    ///                  TreeNodeRecursion::Continue  |   | I |
315    ///                                               |   +---+
316    ///                                               |     |
317    ///                                               |   +---+
318    ///                                              \|/  | F |
319    ///                                               '   +---+
320    ///                                                  /     \ ___________________
321    ///                  When `f_down` is           +---+                           \ ---+
322    ///                  applied on node "E",       | E |                            | G |
323    ///                  it returns with "Jump".    +---+                            +---+
324    ///                                               |                                |
325    ///                                             +---+                            +---+
326    ///                                             | C |                            | H |
327    ///                                             +---+                            +---+
328    ///                                             /   \
329    ///                                        +---+     +---+
330    ///                                        | B |     | D |
331    ///                                        +---+     +---+
332    ///                                                    |
333    ///                                                  +---+
334    ///                                                  | A |
335    ///                                                  +---+
336    ///
337    /// Instead of starting from leaf nodes, `f_up` starts from the node "E".
338    ///                                                   +---+
339    ///                                               |   | J |
340    ///                                               |   +---+
341    ///                                               |     |
342    ///                                               |   +---+
343    ///                                               |   | I |
344    ///                                               |   +---+
345    ///                                               |     |
346    ///                                              /    +---+
347    ///                                            /      | F |
348    ///                                          /        +---+
349    ///                                        /         /     \ ______________________
350    ///                                       |     +---+   .                          \ ---+
351    ///                                       |     | E |  /|\  After `f_down` jumps    | G |
352    ///                                       |     +---+   |   on node E, `f_up`       +---+
353    ///                                        \------| ---/   if applied on node E.      |
354    ///                                             +---+                               +---+
355    ///                                             | C |                               | H |
356    ///                                             +---+                               +---+
357    ///                                             /   \
358    ///                                        +---+     +---+
359    ///                                        | B |     | D |
360    ///                                        +---+     +---+
361    ///                                                    |
362    ///                                                  +---+
363    ///                                                  | A |
364    ///                                                  +---+
365    /// ```
366    fn transform_down_up<
367        FD: FnMut(Self) -> Result<Transformed<Self>>,
368        FU: FnMut(Self) -> Result<Transformed<Self>>,
369    >(
370        self,
371        mut f_down: FD,
372        mut f_up: FU,
373    ) -> Result<Transformed<Self>> {
374        #[cfg_attr(feature = "recursive_protection", recursive::recursive)]
375        fn transform_down_up_impl<
376            N: TreeNode,
377            FD: FnMut(N) -> Result<Transformed<N>>,
378            FU: FnMut(N) -> Result<Transformed<N>>,
379        >(
380            node: N,
381            f_down: &mut FD,
382            f_up: &mut FU,
383        ) -> Result<Transformed<N>> {
384            handle_transform_recursion!(
385                f_down(node),
386                |c| transform_down_up_impl(c, f_down, f_up),
387                f_up
388            )
389        }
390
391        transform_down_up_impl(self, &mut f_down, &mut f_up)
392    }
393
394    /// Returns true if `f` returns true for any node in the tree.
395    ///
396    /// Stops recursion as soon as a matching node is found
397    fn exists<F: FnMut(&Self) -> Result<bool>>(&self, mut f: F) -> Result<bool> {
398        let mut found = false;
399        self.apply(|n| {
400            Ok(if f(n)? {
401                found = true;
402                TreeNodeRecursion::Stop
403            } else {
404                TreeNodeRecursion::Continue
405            })
406        })
407        .map(|_| found)
408    }
409
410    /// Low-level API used to implement other APIs.
411    ///
412    /// If you want to implement the [`TreeNode`] trait for your own type, you
413    /// should implement this method and [`Self::map_children`].
414    ///
415    /// Users should use one of the higher level APIs described on [`Self`].
416    ///
417    /// Description: Apply `f` to inspect node's children (but not the node
418    /// itself).
419    fn apply_children<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
420        &'n self,
421        f: F,
422    ) -> Result<TreeNodeRecursion>;
423
424    /// Low-level API used to implement other APIs.
425    ///
426    /// If you want to implement the [`TreeNode`] trait for your own type, you
427    /// should implement this method and [`Self::apply_children`].
428    ///
429    /// Users should use one of the higher level APIs described on [`Self`].
430    ///
431    /// Description: Apply `f` to rewrite the node's children (but not the node itself).
432    fn map_children<F: FnMut(Self) -> Result<Transformed<Self>>>(
433        self,
434        f: F,
435    ) -> Result<Transformed<Self>>;
436}
437
438/// A [Visitor](https://en.wikipedia.org/wiki/Visitor_pattern) for recursively
439/// inspecting [`TreeNode`]s via [`TreeNode::visit`].
440///
441/// See [`TreeNode`] for more details on available APIs
442///
443/// When passed to [`TreeNode::visit`], [`TreeNodeVisitor::f_down`] and
444/// [`TreeNodeVisitor::f_up`] are invoked recursively on the tree.
445/// See [`TreeNodeRecursion`] for more details on controlling the traversal.
446///
447/// # Return Value
448/// The returns value of `f_up` and `f_down` specifies how the tree walk should
449/// proceed. See [`TreeNodeRecursion`] for details. If an [`Err`] is returned,
450/// the recursion stops immediately.
451///
452/// Note: If using the default implementations of [`TreeNodeVisitor::f_up`] or
453/// [`TreeNodeVisitor::f_down`] that do nothing, consider using
454/// [`TreeNode::apply`] instead.
455///
456/// # See Also:
457/// * [`TreeNode::rewrite`] to rewrite owned `TreeNode`s
458pub trait TreeNodeVisitor<'n>: Sized {
459    /// The node type which is visitable.
460    type Node: TreeNode;
461
462    /// Invoked while traversing down the tree, before any children are visited.
463    /// Default implementation continues the recursion.
464    fn f_down(&mut self, _node: &'n Self::Node) -> Result<TreeNodeRecursion> {
465        Ok(TreeNodeRecursion::Continue)
466    }
467
468    /// Invoked while traversing up the tree after children are visited. Default
469    /// implementation continues the recursion.
470    fn f_up(&mut self, _node: &'n Self::Node) -> Result<TreeNodeRecursion> {
471        Ok(TreeNodeRecursion::Continue)
472    }
473}
474
475/// A [Visitor](https://en.wikipedia.org/wiki/Visitor_pattern) for recursively
476/// rewriting [`TreeNode`]s via [`TreeNode::rewrite`].
477///
478/// For example you can implement this trait on a struct to rewrite `Expr` or
479/// `LogicalPlan` that needs to track state during the rewrite.
480///
481/// See [`TreeNode`] for more details on available APIs
482///
483/// When passed to [`TreeNode::rewrite`], [`TreeNodeRewriter::f_down`] and
484/// [`TreeNodeRewriter::f_up`] are invoked recursively on the tree.
485/// See [`TreeNodeRecursion`] for more details on controlling the traversal.
486///
487/// # Return Value
488/// The returns value of `f_up` and `f_down` specifies how the tree walk should
489/// proceed. See [`TreeNodeRecursion`] for details. If an [`Err`] is returned,
490/// the recursion stops immediately.
491///
492/// Note: If using the default implementations of [`TreeNodeRewriter::f_up`] or
493/// [`TreeNodeRewriter::f_down`] that do nothing, consider using
494/// [`TreeNode::transform_up`] or [`TreeNode::transform_down`] instead.
495///
496/// # See Also:
497/// * [`TreeNode::visit`] to inspect borrowed `TreeNode`s
498pub trait TreeNodeRewriter: Sized {
499    /// The node type which is rewritable.
500    type Node: TreeNode;
501
502    /// Invoked while traversing down the tree before any children are rewritten.
503    /// Default implementation returns the node as is and continues recursion.
504    fn f_down(&mut self, node: Self::Node) -> Result<Transformed<Self::Node>> {
505        Ok(Transformed::no(node))
506    }
507
508    /// Invoked while traversing up the tree after all children have been rewritten.
509    /// Default implementation returns the node as is and continues recursion.
510    fn f_up(&mut self, node: Self::Node) -> Result<Transformed<Self::Node>> {
511        Ok(Transformed::no(node))
512    }
513}
514
515/// Controls how [`TreeNode`] recursions should proceed.
516#[derive(Debug, PartialEq, Clone, Copy)]
517pub enum TreeNodeRecursion {
518    /// Continue recursion with the next node.
519    Continue,
520    /// In top-down traversals, skip recursing into children but continue with
521    /// the next node, which actually means pruning of the subtree.
522    ///
523    /// In bottom-up traversals, bypass calling bottom-up closures till the next
524    /// leaf node.
525    ///
526    /// In combined traversals, if it is the `f_down` (pre-order) phase, execution
527    /// "jumps" to the next `f_up` (post-order) phase by shortcutting its children.
528    /// If it is the `f_up` (post-order) phase, execution "jumps" to the next `f_down`
529    /// (pre-order) phase by shortcutting its parent nodes until the first parent node
530    /// having unvisited children path.
531    Jump,
532    /// Stop recursion.
533    Stop,
534}
535
536impl TreeNodeRecursion {
537    /// Continues visiting nodes with `f` depending on the current [`TreeNodeRecursion`]
538    /// value and the fact that `f` is visiting the current node's children.
539    pub fn visit_children<F: FnOnce() -> Result<TreeNodeRecursion>>(
540        self,
541        f: F,
542    ) -> Result<TreeNodeRecursion> {
543        match self {
544            TreeNodeRecursion::Continue => f(),
545            TreeNodeRecursion::Jump => Ok(TreeNodeRecursion::Continue),
546            TreeNodeRecursion::Stop => Ok(self),
547        }
548    }
549
550    /// Continues visiting nodes with `f` depending on the current [`TreeNodeRecursion`]
551    /// value and the fact that `f` is visiting the current node's sibling.
552    pub fn visit_sibling<F: FnOnce() -> Result<TreeNodeRecursion>>(
553        self,
554        f: F,
555    ) -> Result<TreeNodeRecursion> {
556        match self {
557            TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => f(),
558            TreeNodeRecursion::Stop => Ok(self),
559        }
560    }
561
562    /// Continues visiting nodes with `f` depending on the current [`TreeNodeRecursion`]
563    /// value and the fact that `f` is visiting the current node's parent.
564    pub fn visit_parent<F: FnOnce() -> Result<TreeNodeRecursion>>(
565        self,
566        f: F,
567    ) -> Result<TreeNodeRecursion> {
568        match self {
569            TreeNodeRecursion::Continue => f(),
570            TreeNodeRecursion::Jump | TreeNodeRecursion::Stop => Ok(self),
571        }
572    }
573}
574
575/// Result of tree walk / transformation APIs
576///
577/// `Transformed` is a wrapper around the tree node data (e.g. `Expr` or
578/// `LogicalPlan`). It is used to indicate whether the node was transformed
579/// and how the recursion should proceed.
580///
581/// [`TreeNode`] API users control the transformation by returning:
582/// - The resulting (possibly transformed) node,
583/// - `transformed`: flag indicating whether any change was made to the node
584/// - `tnr`: [`TreeNodeRecursion`] specifying how to proceed with the recursion.
585///
586/// At the end of the transformation, the return value will contain:
587/// - The final (possibly transformed) tree,
588/// - `transformed`: flag indicating whether any change was made to the node
589/// - `tnr`: [`TreeNodeRecursion`] specifying how the recursion ended.
590///
591/// See also
592/// * [`Transformed::update_data`] to modify the node without changing the `transformed` flag
593/// * [`Transformed::map_data`] for fallable operation that return the same type
594/// * [`Transformed::transform_data`] to chain fallable transformations
595/// * [`TransformedResult`] for working with `Result<Transformed<U>>`
596///
597/// # Examples
598///
599/// Use [`Transformed::yes`] and [`Transformed::no`] to signal that a node was
600/// rewritten and the recursion should continue:
601///
602/// ```
603/// # use datafusion_common::tree_node::Transformed;
604/// # // note use i64 instead of Expr as Expr is not in datafusion-common
605/// # fn orig_expr() -> i64 { 1 }
606/// # fn make_new_expr(i: i64) -> i64 { 2 }
607/// let expr = orig_expr();
608///
609/// // Create a new `Transformed` object signaling the node was not rewritten
610/// let ret = Transformed::no(expr.clone());
611/// assert!(!ret.transformed);
612///
613/// // Create a new `Transformed` object signaling the node was rewritten
614/// let ret = Transformed::yes(expr);
615/// assert!(ret.transformed)
616/// ```
617///
618/// Access the node within the `Transformed` object:
619/// ```
620/// # use datafusion_common::tree_node::Transformed;
621/// # // note use i64 instead of Expr as Expr is not in datafusion-common
622/// # fn orig_expr() -> i64 { 1 }
623/// # fn make_new_expr(i: i64) -> i64 { 2 }
624/// let expr = orig_expr();
625///
626/// // `Transformed` object signaling the node was not rewritten
627/// let ret = Transformed::no(expr.clone());
628/// // Access the inner object using .data
629/// assert_eq!(expr, ret.data);
630/// ```
631///
632/// Transform the node within the `Transformed` object.
633///
634/// ```
635/// # use datafusion_common::tree_node::Transformed;
636/// # // note use i64 instead of Expr as Expr is not in datafusion-common
637/// # fn orig_expr() -> i64 { 1 }
638/// # fn make_new_expr(i: i64) -> i64 { 2 }
639/// let expr = orig_expr();
640/// let ret = Transformed::no(expr.clone())
641///   .transform_data(|expr| {
642///    // closure returns a result and potentially transforms the node
643///    // in this example, it does transform the node
644///    let new_expr = make_new_expr(expr);
645///    Ok(Transformed::yes(new_expr))
646///  }).unwrap();
647/// // transformed flag is the union of the original ans closure's  transformed flag
648/// assert!(ret.transformed);
649/// ```
650/// # Example APIs that use `TreeNode`
651/// - [`TreeNode`],
652/// - [`TreeNode::rewrite`],
653/// - [`TreeNode::transform_down`],
654/// - [`TreeNode::transform_up`],
655/// - [`TreeNode::transform_down_up`]
656#[derive(PartialEq, Debug)]
657pub struct Transformed<T> {
658    pub data: T,
659    pub transformed: bool,
660    pub tnr: TreeNodeRecursion,
661}
662
663impl<T> Transformed<T> {
664    /// Create a new `Transformed` object with the given information.
665    pub fn new(data: T, transformed: bool, tnr: TreeNodeRecursion) -> Self {
666        Self {
667            data,
668            transformed,
669            tnr,
670        }
671    }
672
673    /// Create a `Transformed` with `transformed` and [`TreeNodeRecursion::Continue`].
674    pub fn new_transformed(data: T, transformed: bool) -> Self {
675        Self::new(data, transformed, TreeNodeRecursion::Continue)
676    }
677
678    /// Wrapper for transformed data with [`TreeNodeRecursion::Continue`] statement.
679    pub fn yes(data: T) -> Self {
680        Self::new(data, true, TreeNodeRecursion::Continue)
681    }
682
683    /// Wrapper for unchanged data with [`TreeNodeRecursion::Continue`] statement.
684    pub fn no(data: T) -> Self {
685        Self::new(data, false, TreeNodeRecursion::Continue)
686    }
687
688    /// Applies an infallible `f` to the data of this [`Transformed`] object,
689    /// without modifying the `transformed` flag.
690    pub fn update_data<U, F: FnOnce(T) -> U>(self, f: F) -> Transformed<U> {
691        Transformed::new(f(self.data), self.transformed, self.tnr)
692    }
693
694    /// Applies a fallible `f` (returns `Result`) to the data of this
695    /// [`Transformed`] object, without modifying the `transformed` flag.
696    pub fn map_data<U, F: FnOnce(T) -> Result<U>>(self, f: F) -> Result<Transformed<U>> {
697        f(self.data).map(|data| Transformed::new(data, self.transformed, self.tnr))
698    }
699
700    /// Applies a fallible transforming `f` to the data of this [`Transformed`]
701    /// object.
702    ///
703    /// The returned `Transformed` object has the `transformed` flag set if either
704    /// `self` or the return value of `f` have the `transformed` flag set.
705    pub fn transform_data<U, F: FnOnce(T) -> Result<Transformed<U>>>(
706        self,
707        f: F,
708    ) -> Result<Transformed<U>> {
709        f(self.data).map(|mut t| {
710            t.transformed |= self.transformed;
711            t
712        })
713    }
714
715    /// Maps the [`Transformed`] object to the result of the given `f` depending on the
716    /// current [`TreeNodeRecursion`] value and the fact that `f` is changing the current
717    /// node's children.
718    pub fn transform_children<F: FnOnce(T) -> Result<Transformed<T>>>(
719        mut self,
720        f: F,
721    ) -> Result<Transformed<T>> {
722        match self.tnr {
723            TreeNodeRecursion::Continue => {
724                return f(self.data).map(|mut t| {
725                    t.transformed |= self.transformed;
726                    t
727                });
728            }
729            TreeNodeRecursion::Jump => {
730                self.tnr = TreeNodeRecursion::Continue;
731            }
732            TreeNodeRecursion::Stop => {}
733        }
734        Ok(self)
735    }
736
737    /// Maps the [`Transformed`] object to the result of the given `f` depending on the
738    /// current [`TreeNodeRecursion`] value and the fact that `f` is changing the current
739    /// node's sibling.
740    pub fn transform_sibling<F: FnOnce(T) -> Result<Transformed<T>>>(
741        self,
742        f: F,
743    ) -> Result<Transformed<T>> {
744        match self.tnr {
745            TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {
746                f(self.data).map(|mut t| {
747                    t.transformed |= self.transformed;
748                    t
749                })
750            }
751            TreeNodeRecursion::Stop => Ok(self),
752        }
753    }
754
755    /// Maps the [`Transformed`] object to the result of the given `f` depending on the
756    /// current [`TreeNodeRecursion`] value and the fact that `f` is changing the current
757    /// node's parent.
758    pub fn transform_parent<F: FnOnce(T) -> Result<Transformed<T>>>(
759        self,
760        f: F,
761    ) -> Result<Transformed<T>> {
762        match self.tnr {
763            TreeNodeRecursion::Continue => f(self.data).map(|mut t| {
764                t.transformed |= self.transformed;
765                t
766            }),
767            TreeNodeRecursion::Jump | TreeNodeRecursion::Stop => Ok(self),
768        }
769    }
770}
771
772/// [`TreeNodeContainer`] contains elements that a function can be applied on or mapped.
773/// The elements of the container are siblings so the continuation rules are similar to
774/// [`TreeNodeRecursion::visit_sibling`] / [`Transformed::transform_sibling`].
775pub trait TreeNodeContainer<'a, T: 'a>: Sized {
776    /// Applies `f` to all elements of the container.
777    /// This method is usually called from [`TreeNode::apply_children`] implementations as
778    /// a node is actually a container of the node's children.
779    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
780        &'a self,
781        f: F,
782    ) -> Result<TreeNodeRecursion>;
783
784    /// Maps all elements of the container with `f`.
785    /// This method is usually called from [`TreeNode::map_children`] implementations as
786    /// a node is actually a container of the node's children.
787    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
788        self,
789        f: F,
790    ) -> Result<Transformed<Self>>;
791}
792
793impl<'a, T: 'a, C: TreeNodeContainer<'a, T>> TreeNodeContainer<'a, T> for Box<C> {
794    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
795        &'a self,
796        f: F,
797    ) -> Result<TreeNodeRecursion> {
798        self.as_ref().apply_elements(f)
799    }
800
801    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
802        self,
803        f: F,
804    ) -> Result<Transformed<Self>> {
805        (*self).map_elements(f)?.map_data(|c| Ok(Self::new(c)))
806    }
807}
808
809impl<'a, T: 'a, C: TreeNodeContainer<'a, T> + Clone> TreeNodeContainer<'a, T> for Arc<C> {
810    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
811        &'a self,
812        f: F,
813    ) -> Result<TreeNodeRecursion> {
814        self.as_ref().apply_elements(f)
815    }
816
817    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
818        self,
819        f: F,
820    ) -> Result<Transformed<Self>> {
821        Arc::unwrap_or_clone(self)
822            .map_elements(f)?
823            .map_data(|c| Ok(Arc::new(c)))
824    }
825}
826
827impl<'a, T: 'a, C: TreeNodeContainer<'a, T>> TreeNodeContainer<'a, T> for Option<C> {
828    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
829        &'a self,
830        f: F,
831    ) -> Result<TreeNodeRecursion> {
832        match self {
833            Some(t) => t.apply_elements(f),
834            None => Ok(TreeNodeRecursion::Continue),
835        }
836    }
837
838    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
839        self,
840        f: F,
841    ) -> Result<Transformed<Self>> {
842        self.map_or(Ok(Transformed::no(None)), |c| {
843            c.map_elements(f)?.map_data(|c| Ok(Some(c)))
844        })
845    }
846}
847
848impl<'a, T: 'a, C: TreeNodeContainer<'a, T>> TreeNodeContainer<'a, T> for Vec<C> {
849    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
850        &'a self,
851        mut f: F,
852    ) -> Result<TreeNodeRecursion> {
853        let mut tnr = TreeNodeRecursion::Continue;
854        for c in self {
855            tnr = c.apply_elements(&mut f)?;
856            match tnr {
857                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {}
858                TreeNodeRecursion::Stop => return Ok(TreeNodeRecursion::Stop),
859            }
860        }
861        Ok(tnr)
862    }
863
864    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
865        self,
866        mut f: F,
867    ) -> Result<Transformed<Self>> {
868        let mut tnr = TreeNodeRecursion::Continue;
869        let mut transformed = false;
870        self.into_iter()
871            .map(|c| match tnr {
872                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {
873                    c.map_elements(&mut f).map(|result| {
874                        tnr = result.tnr;
875                        transformed |= result.transformed;
876                        result.data
877                    })
878                }
879                TreeNodeRecursion::Stop => Ok(c),
880            })
881            .collect::<Result<Vec<_>>>()
882            .map(|data| Transformed::new(data, transformed, tnr))
883    }
884}
885
886impl<'a, T: 'a, K: Eq + Hash, C: TreeNodeContainer<'a, T>> TreeNodeContainer<'a, T>
887    for HashMap<K, C>
888{
889    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
890        &'a self,
891        mut f: F,
892    ) -> Result<TreeNodeRecursion> {
893        let mut tnr = TreeNodeRecursion::Continue;
894        for c in self.values() {
895            tnr = c.apply_elements(&mut f)?;
896            match tnr {
897                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {}
898                TreeNodeRecursion::Stop => return Ok(TreeNodeRecursion::Stop),
899            }
900        }
901        Ok(tnr)
902    }
903
904    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
905        self,
906        mut f: F,
907    ) -> Result<Transformed<Self>> {
908        let mut tnr = TreeNodeRecursion::Continue;
909        let mut transformed = false;
910        self.into_iter()
911            .map(|(k, c)| match tnr {
912                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {
913                    c.map_elements(&mut f).map(|result| {
914                        tnr = result.tnr;
915                        transformed |= result.transformed;
916                        (k, result.data)
917                    })
918                }
919                TreeNodeRecursion::Stop => Ok((k, c)),
920            })
921            .collect::<Result<HashMap<_, _>>>()
922            .map(|data| Transformed::new(data, transformed, tnr))
923    }
924}
925
926impl<'a, T: 'a, C0: TreeNodeContainer<'a, T>, C1: TreeNodeContainer<'a, T>>
927    TreeNodeContainer<'a, T> for (C0, C1)
928{
929    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
930        &'a self,
931        mut f: F,
932    ) -> Result<TreeNodeRecursion> {
933        self.0
934            .apply_elements(&mut f)?
935            .visit_sibling(|| self.1.apply_elements(&mut f))
936    }
937
938    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
939        self,
940        mut f: F,
941    ) -> Result<Transformed<Self>> {
942        self.0
943            .map_elements(&mut f)?
944            .map_data(|new_c0| Ok((new_c0, self.1)))?
945            .transform_sibling(|(new_c0, c1)| {
946                c1.map_elements(&mut f)?
947                    .map_data(|new_c1| Ok((new_c0, new_c1)))
948            })
949    }
950}
951
952impl<
953        'a,
954        T: 'a,
955        C0: TreeNodeContainer<'a, T>,
956        C1: TreeNodeContainer<'a, T>,
957        C2: TreeNodeContainer<'a, T>,
958    > TreeNodeContainer<'a, T> for (C0, C1, C2)
959{
960    fn apply_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
961        &'a self,
962        mut f: F,
963    ) -> Result<TreeNodeRecursion> {
964        self.0
965            .apply_elements(&mut f)?
966            .visit_sibling(|| self.1.apply_elements(&mut f))?
967            .visit_sibling(|| self.2.apply_elements(&mut f))
968    }
969
970    fn map_elements<F: FnMut(T) -> Result<Transformed<T>>>(
971        self,
972        mut f: F,
973    ) -> Result<Transformed<Self>> {
974        self.0
975            .map_elements(&mut f)?
976            .map_data(|new_c0| Ok((new_c0, self.1, self.2)))?
977            .transform_sibling(|(new_c0, c1, c2)| {
978                c1.map_elements(&mut f)?
979                    .map_data(|new_c1| Ok((new_c0, new_c1, c2)))
980            })?
981            .transform_sibling(|(new_c0, new_c1, c2)| {
982                c2.map_elements(&mut f)?
983                    .map_data(|new_c2| Ok((new_c0, new_c1, new_c2)))
984            })
985    }
986}
987
988/// [`TreeNodeRefContainer`] contains references to elements that a function can be
989/// applied on. The elements of the container are siblings so the continuation rules are
990/// similar to [`TreeNodeRecursion::visit_sibling`].
991///
992/// This container is similar to [`TreeNodeContainer`], but the lifetime of the reference
993/// elements (`T`) are not derived from the container's lifetime.
994/// A typical usage of this container is in `Expr::apply_children` when we need to
995/// construct a temporary container to be able to call `apply_ref_elements` on a
996/// collection of tree node references. But in that case the container's temporary
997/// lifetime is different to the lifetime of tree nodes that we put into it.
998/// Please find an example use case in `Expr::apply_children` with the `Expr::Case` case.
999///
1000/// Most of the cases we don't need to create a temporary container with
1001/// `TreeNodeRefContainer`, but we can just call `TreeNodeContainer::apply_elements`.
1002/// Please find an example use case in `Expr::apply_children` with the `Expr::GroupingSet`
1003/// case.
1004pub trait TreeNodeRefContainer<'a, T: 'a>: Sized {
1005    /// Applies `f` to all elements of the container.
1006    /// This method is usually called from [`TreeNode::apply_children`] implementations as
1007    /// a node is actually a container of the node's children.
1008    fn apply_ref_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
1009        &self,
1010        f: F,
1011    ) -> Result<TreeNodeRecursion>;
1012}
1013
1014impl<'a, T: 'a, C: TreeNodeContainer<'a, T>> TreeNodeRefContainer<'a, T> for Vec<&'a C> {
1015    fn apply_ref_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
1016        &self,
1017        mut f: F,
1018    ) -> Result<TreeNodeRecursion> {
1019        let mut tnr = TreeNodeRecursion::Continue;
1020        for c in self {
1021            tnr = c.apply_elements(&mut f)?;
1022            match tnr {
1023                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {}
1024                TreeNodeRecursion::Stop => return Ok(TreeNodeRecursion::Stop),
1025            }
1026        }
1027        Ok(tnr)
1028    }
1029}
1030
1031impl<'a, T: 'a, C0: TreeNodeContainer<'a, T>, C1: TreeNodeContainer<'a, T>>
1032    TreeNodeRefContainer<'a, T> for (&'a C0, &'a C1)
1033{
1034    fn apply_ref_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
1035        &self,
1036        mut f: F,
1037    ) -> Result<TreeNodeRecursion> {
1038        self.0
1039            .apply_elements(&mut f)?
1040            .visit_sibling(|| self.1.apply_elements(&mut f))
1041    }
1042}
1043
1044impl<
1045        'a,
1046        T: 'a,
1047        C0: TreeNodeContainer<'a, T>,
1048        C1: TreeNodeContainer<'a, T>,
1049        C2: TreeNodeContainer<'a, T>,
1050    > TreeNodeRefContainer<'a, T> for (&'a C0, &'a C1, &'a C2)
1051{
1052    fn apply_ref_elements<F: FnMut(&'a T) -> Result<TreeNodeRecursion>>(
1053        &self,
1054        mut f: F,
1055    ) -> Result<TreeNodeRecursion> {
1056        self.0
1057            .apply_elements(&mut f)?
1058            .visit_sibling(|| self.1.apply_elements(&mut f))?
1059            .visit_sibling(|| self.2.apply_elements(&mut f))
1060    }
1061}
1062
1063/// Transformation helper to process a sequence of iterable tree nodes that are siblings.
1064pub trait TreeNodeIterator: Iterator {
1065    /// Apples `f` to each item in this iterator
1066    ///
1067    /// Visits all items in the iterator unless
1068    /// `f` returns an error or `f` returns `TreeNodeRecursion::Stop`.
1069    ///
1070    /// # Returns
1071    /// Error if `f` returns an error or `Ok(TreeNodeRecursion)` from the last invocation
1072    /// of `f` or `Continue` if the iterator is empty
1073    fn apply_until_stop<F: FnMut(Self::Item) -> Result<TreeNodeRecursion>>(
1074        self,
1075        f: F,
1076    ) -> Result<TreeNodeRecursion>;
1077
1078    /// Apples `f` to each item in this iterator
1079    ///
1080    /// Visits all items in the iterator unless
1081    /// `f` returns an error or `f` returns `TreeNodeRecursion::Stop`.
1082    ///
1083    /// # Returns
1084    /// Error if `f` returns an error
1085    ///
1086    /// Ok(Transformed) such that:
1087    /// 1. `transformed` is true if any return from `f` had transformed true
1088    /// 2. `data` from the last invocation of `f`
1089    /// 3. `tnr` from the last invocation of `f` or `Continue` if the iterator is empty
1090    fn map_until_stop_and_collect<
1091        F: FnMut(Self::Item) -> Result<Transformed<Self::Item>>,
1092    >(
1093        self,
1094        f: F,
1095    ) -> Result<Transformed<Vec<Self::Item>>>;
1096}
1097
1098impl<I: Iterator> TreeNodeIterator for I {
1099    fn apply_until_stop<F: FnMut(Self::Item) -> Result<TreeNodeRecursion>>(
1100        self,
1101        mut f: F,
1102    ) -> Result<TreeNodeRecursion> {
1103        let mut tnr = TreeNodeRecursion::Continue;
1104        for i in self {
1105            tnr = f(i)?;
1106            match tnr {
1107                TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {}
1108                TreeNodeRecursion::Stop => return Ok(TreeNodeRecursion::Stop),
1109            }
1110        }
1111        Ok(tnr)
1112    }
1113
1114    fn map_until_stop_and_collect<
1115        F: FnMut(Self::Item) -> Result<Transformed<Self::Item>>,
1116    >(
1117        self,
1118        mut f: F,
1119    ) -> Result<Transformed<Vec<Self::Item>>> {
1120        let mut tnr = TreeNodeRecursion::Continue;
1121        let mut transformed = false;
1122        self.map(|item| match tnr {
1123            TreeNodeRecursion::Continue | TreeNodeRecursion::Jump => {
1124                f(item).map(|result| {
1125                    tnr = result.tnr;
1126                    transformed |= result.transformed;
1127                    result.data
1128                })
1129            }
1130            TreeNodeRecursion::Stop => Ok(item),
1131        })
1132        .collect::<Result<Vec<_>>>()
1133        .map(|data| Transformed::new(data, transformed, tnr))
1134    }
1135}
1136
1137/// Transformation helper to access [`Transformed`] fields in a [`Result`] easily.
1138///
1139/// # Example
1140/// Access the internal data of a `Result<Transformed<T>>`
1141/// as a `Result<T>` using the `data` method:
1142/// ```
1143/// # use datafusion_common::Result;
1144/// # use datafusion_common::tree_node::{Transformed, TransformedResult};
1145/// # // note use i64 instead of Expr as Expr is not in datafusion-common
1146/// # fn update_expr() -> i64 { 1 }
1147/// # fn main() -> Result<()> {
1148/// let transformed: Result<Transformed<_>> = Ok(Transformed::yes(update_expr()));
1149/// // access the internal data of the transformed result, or return the error
1150/// let transformed_expr = transformed.data()?;
1151/// # Ok(())
1152/// # }
1153/// ```
1154pub trait TransformedResult<T> {
1155    fn data(self) -> Result<T>;
1156
1157    fn transformed(self) -> Result<bool>;
1158
1159    fn tnr(self) -> Result<TreeNodeRecursion>;
1160}
1161
1162impl<T> TransformedResult<T> for Result<Transformed<T>> {
1163    fn data(self) -> Result<T> {
1164        self.map(|t| t.data)
1165    }
1166
1167    fn transformed(self) -> Result<bool> {
1168        self.map(|t| t.transformed)
1169    }
1170
1171    fn tnr(self) -> Result<TreeNodeRecursion> {
1172        self.map(|t| t.tnr)
1173    }
1174}
1175
1176/// Helper trait for implementing [`TreeNode`] that have children stored as
1177/// `Arc`s. If some trait object, such as `dyn T`, implements this trait,
1178/// its related `Arc<dyn T>` will automatically implement [`TreeNode`].
1179pub trait DynTreeNode {
1180    /// Returns all children of the specified `TreeNode`.
1181    fn arc_children(&self) -> Vec<&Arc<Self>>;
1182
1183    /// Constructs a new node with the specified children.
1184    fn with_new_arc_children(
1185        &self,
1186        arc_self: Arc<Self>,
1187        new_children: Vec<Arc<Self>>,
1188    ) -> Result<Arc<Self>>;
1189}
1190
1191/// Blanket implementation for any `Arc<T>` where `T` implements [`DynTreeNode`]
1192/// (such as [`Arc<dyn PhysicalExpr>`]).
1193impl<T: DynTreeNode + ?Sized> TreeNode for Arc<T> {
1194    fn apply_children<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
1195        &'n self,
1196        f: F,
1197    ) -> Result<TreeNodeRecursion> {
1198        self.arc_children().into_iter().apply_until_stop(f)
1199    }
1200
1201    fn map_children<F: FnMut(Self) -> Result<Transformed<Self>>>(
1202        self,
1203        f: F,
1204    ) -> Result<Transformed<Self>> {
1205        let children = self.arc_children();
1206        if !children.is_empty() {
1207            let new_children = children
1208                .into_iter()
1209                .cloned()
1210                .map_until_stop_and_collect(f)?;
1211            // Propagate up `new_children.transformed` and `new_children.tnr`
1212            // along with the node containing transformed children.
1213            if new_children.transformed {
1214                let arc_self = Arc::clone(&self);
1215                new_children.map_data(|new_children| {
1216                    self.with_new_arc_children(arc_self, new_children)
1217                })
1218            } else {
1219                Ok(Transformed::new(self, false, new_children.tnr))
1220            }
1221        } else {
1222            Ok(Transformed::no(self))
1223        }
1224    }
1225}
1226
1227/// Instead of implementing [`TreeNode`], it's recommended to implement a [`ConcreteTreeNode`] for
1228/// trees that contain nodes with payloads. This approach ensures safe execution of algorithms
1229/// involving payloads, by enforcing rules for detaching and reattaching child nodes.
1230pub trait ConcreteTreeNode: Sized {
1231    /// Provides read-only access to child nodes.
1232    fn children(&self) -> &[Self];
1233
1234    /// Detaches the node from its children, returning the node itself and its detached children.
1235    fn take_children(self) -> (Self, Vec<Self>);
1236
1237    /// Reattaches updated child nodes to the node, returning the updated node.
1238    fn with_new_children(self, children: Vec<Self>) -> Result<Self>;
1239}
1240
1241impl<T: ConcreteTreeNode> TreeNode for T {
1242    fn apply_children<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
1243        &'n self,
1244        f: F,
1245    ) -> Result<TreeNodeRecursion> {
1246        self.children().iter().apply_until_stop(f)
1247    }
1248
1249    fn map_children<F: FnMut(Self) -> Result<Transformed<Self>>>(
1250        self,
1251        f: F,
1252    ) -> Result<Transformed<Self>> {
1253        let (new_self, children) = self.take_children();
1254        if !children.is_empty() {
1255            let new_children = children.into_iter().map_until_stop_and_collect(f)?;
1256            // Propagate up `new_children.transformed` and `new_children.tnr` along with
1257            // the node containing transformed children.
1258            new_children.map_data(|new_children| new_self.with_new_children(new_children))
1259        } else {
1260            Ok(Transformed::no(new_self))
1261        }
1262    }
1263}
1264
1265#[cfg(test)]
1266pub(crate) mod tests {
1267    use std::collections::HashMap;
1268    use std::fmt::Display;
1269
1270    use crate::tree_node::{
1271        Transformed, TreeNode, TreeNodeContainer, TreeNodeRecursion, TreeNodeRewriter,
1272        TreeNodeVisitor,
1273    };
1274    use crate::Result;
1275
1276    #[derive(Debug, Eq, Hash, PartialEq, Clone)]
1277    pub struct TestTreeNode<T> {
1278        pub(crate) children: Vec<TestTreeNode<T>>,
1279        pub(crate) data: T,
1280    }
1281
1282    impl<T> TestTreeNode<T> {
1283        pub(crate) fn new(children: Vec<TestTreeNode<T>>, data: T) -> Self {
1284            Self { children, data }
1285        }
1286
1287        pub(crate) fn new_leaf(data: T) -> Self {
1288            Self {
1289                children: vec![],
1290                data,
1291            }
1292        }
1293
1294        pub(crate) fn is_leaf(&self) -> bool {
1295            self.children.is_empty()
1296        }
1297    }
1298
1299    impl<T> TreeNode for TestTreeNode<T> {
1300        fn apply_children<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
1301            &'n self,
1302            f: F,
1303        ) -> Result<TreeNodeRecursion> {
1304            self.children.apply_elements(f)
1305        }
1306
1307        fn map_children<F: FnMut(Self) -> Result<Transformed<Self>>>(
1308            self,
1309            f: F,
1310        ) -> Result<Transformed<Self>> {
1311            Ok(self
1312                .children
1313                .map_elements(f)?
1314                .update_data(|new_children| Self {
1315                    children: new_children,
1316                    ..self
1317                }))
1318        }
1319    }
1320
1321    impl<'a, T: 'a> TreeNodeContainer<'a, Self> for TestTreeNode<T> {
1322        fn apply_elements<F: FnMut(&'a Self) -> Result<TreeNodeRecursion>>(
1323            &'a self,
1324            mut f: F,
1325        ) -> Result<TreeNodeRecursion> {
1326            f(self)
1327        }
1328
1329        fn map_elements<F: FnMut(Self) -> Result<Transformed<Self>>>(
1330            self,
1331            mut f: F,
1332        ) -> Result<Transformed<Self>> {
1333            f(self)
1334        }
1335    }
1336
1337    //       J
1338    //       |
1339    //       I
1340    //       |
1341    //       F
1342    //     /   \
1343    //    E     G
1344    //    |     |
1345    //    C     H
1346    //  /   \
1347    // B     D
1348    //       |
1349    //       A
1350    fn test_tree() -> TestTreeNode<String> {
1351        let node_a = TestTreeNode::new_leaf("a".to_string());
1352        let node_b = TestTreeNode::new_leaf("b".to_string());
1353        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1354        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1355        let node_e = TestTreeNode::new(vec![node_c], "e".to_string());
1356        let node_h = TestTreeNode::new_leaf("h".to_string());
1357        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1358        let node_f = TestTreeNode::new(vec![node_e, node_g], "f".to_string());
1359        let node_i = TestTreeNode::new(vec![node_f], "i".to_string());
1360        TestTreeNode::new(vec![node_i], "j".to_string())
1361    }
1362
1363    // Continue on all nodes
1364    // Expected visits in a combined traversal
1365    fn all_visits() -> Vec<String> {
1366        vec![
1367            "f_down(j)",
1368            "f_down(i)",
1369            "f_down(f)",
1370            "f_down(e)",
1371            "f_down(c)",
1372            "f_down(b)",
1373            "f_up(b)",
1374            "f_down(d)",
1375            "f_down(a)",
1376            "f_up(a)",
1377            "f_up(d)",
1378            "f_up(c)",
1379            "f_up(e)",
1380            "f_down(g)",
1381            "f_down(h)",
1382            "f_up(h)",
1383            "f_up(g)",
1384            "f_up(f)",
1385            "f_up(i)",
1386            "f_up(j)",
1387        ]
1388        .into_iter()
1389        .map(|s| s.to_string())
1390        .collect()
1391    }
1392
1393    // Expected transformed tree after a combined traversal
1394    fn transformed_tree() -> TestTreeNode<String> {
1395        let node_a = TestTreeNode::new_leaf("f_up(f_down(a))".to_string());
1396        let node_b = TestTreeNode::new_leaf("f_up(f_down(b))".to_string());
1397        let node_d = TestTreeNode::new(vec![node_a], "f_up(f_down(d))".to_string());
1398        let node_c =
1399            TestTreeNode::new(vec![node_b, node_d], "f_up(f_down(c))".to_string());
1400        let node_e = TestTreeNode::new(vec![node_c], "f_up(f_down(e))".to_string());
1401        let node_h = TestTreeNode::new_leaf("f_up(f_down(h))".to_string());
1402        let node_g = TestTreeNode::new(vec![node_h], "f_up(f_down(g))".to_string());
1403        let node_f =
1404            TestTreeNode::new(vec![node_e, node_g], "f_up(f_down(f))".to_string());
1405        let node_i = TestTreeNode::new(vec![node_f], "f_up(f_down(i))".to_string());
1406        TestTreeNode::new(vec![node_i], "f_up(f_down(j))".to_string())
1407    }
1408
1409    // Expected transformed tree after a top-down traversal
1410    fn transformed_down_tree() -> TestTreeNode<String> {
1411        let node_a = TestTreeNode::new_leaf("f_down(a)".to_string());
1412        let node_b = TestTreeNode::new_leaf("f_down(b)".to_string());
1413        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1414        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1415        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1416        let node_h = TestTreeNode::new_leaf("f_down(h)".to_string());
1417        let node_g = TestTreeNode::new(vec![node_h], "f_down(g)".to_string());
1418        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1419        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1420        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1421    }
1422
1423    // Expected transformed tree after a bottom-up traversal
1424    fn transformed_up_tree() -> TestTreeNode<String> {
1425        let node_a = TestTreeNode::new_leaf("f_up(a)".to_string());
1426        let node_b = TestTreeNode::new_leaf("f_up(b)".to_string());
1427        let node_d = TestTreeNode::new(vec![node_a], "f_up(d)".to_string());
1428        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_up(c)".to_string());
1429        let node_e = TestTreeNode::new(vec![node_c], "f_up(e)".to_string());
1430        let node_h = TestTreeNode::new_leaf("f_up(h)".to_string());
1431        let node_g = TestTreeNode::new(vec![node_h], "f_up(g)".to_string());
1432        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_up(f)".to_string());
1433        let node_i = TestTreeNode::new(vec![node_f], "f_up(i)".to_string());
1434        TestTreeNode::new(vec![node_i], "f_up(j)".to_string())
1435    }
1436
1437    // f_down Jump on A node
1438    fn f_down_jump_on_a_visits() -> Vec<String> {
1439        vec![
1440            "f_down(j)",
1441            "f_down(i)",
1442            "f_down(f)",
1443            "f_down(e)",
1444            "f_down(c)",
1445            "f_down(b)",
1446            "f_up(b)",
1447            "f_down(d)",
1448            "f_down(a)",
1449            "f_up(a)",
1450            "f_up(d)",
1451            "f_up(c)",
1452            "f_up(e)",
1453            "f_down(g)",
1454            "f_down(h)",
1455            "f_up(h)",
1456            "f_up(g)",
1457            "f_up(f)",
1458            "f_up(i)",
1459            "f_up(j)",
1460        ]
1461        .into_iter()
1462        .map(|s| s.to_string())
1463        .collect()
1464    }
1465
1466    fn f_down_jump_on_a_transformed_down_tree() -> TestTreeNode<String> {
1467        let node_a = TestTreeNode::new_leaf("f_down(a)".to_string());
1468        let node_b = TestTreeNode::new_leaf("f_down(b)".to_string());
1469        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1470        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1471        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1472        let node_h = TestTreeNode::new_leaf("f_down(h)".to_string());
1473        let node_g = TestTreeNode::new(vec![node_h], "f_down(g)".to_string());
1474        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1475        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1476        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1477    }
1478
1479    // f_down Jump on E node
1480    fn f_down_jump_on_e_visits() -> Vec<String> {
1481        vec![
1482            "f_down(j)",
1483            "f_down(i)",
1484            "f_down(f)",
1485            "f_down(e)",
1486            "f_up(e)",
1487            "f_down(g)",
1488            "f_down(h)",
1489            "f_up(h)",
1490            "f_up(g)",
1491            "f_up(f)",
1492            "f_up(i)",
1493            "f_up(j)",
1494        ]
1495        .into_iter()
1496        .map(|s| s.to_string())
1497        .collect()
1498    }
1499
1500    fn f_down_jump_on_e_transformed_tree() -> TestTreeNode<String> {
1501        let node_a = TestTreeNode::new_leaf("a".to_string());
1502        let node_b = TestTreeNode::new_leaf("b".to_string());
1503        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1504        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1505        let node_e = TestTreeNode::new(vec![node_c], "f_up(f_down(e))".to_string());
1506        let node_h = TestTreeNode::new_leaf("f_up(f_down(h))".to_string());
1507        let node_g = TestTreeNode::new(vec![node_h], "f_up(f_down(g))".to_string());
1508        let node_f =
1509            TestTreeNode::new(vec![node_e, node_g], "f_up(f_down(f))".to_string());
1510        let node_i = TestTreeNode::new(vec![node_f], "f_up(f_down(i))".to_string());
1511        TestTreeNode::new(vec![node_i], "f_up(f_down(j))".to_string())
1512    }
1513
1514    fn f_down_jump_on_e_transformed_down_tree() -> TestTreeNode<String> {
1515        let node_a = TestTreeNode::new_leaf("a".to_string());
1516        let node_b = TestTreeNode::new_leaf("b".to_string());
1517        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1518        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1519        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1520        let node_h = TestTreeNode::new_leaf("f_down(h)".to_string());
1521        let node_g = TestTreeNode::new(vec![node_h], "f_down(g)".to_string());
1522        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1523        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1524        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1525    }
1526
1527    // f_up Jump on A node
1528    fn f_up_jump_on_a_visits() -> Vec<String> {
1529        vec![
1530            "f_down(j)",
1531            "f_down(i)",
1532            "f_down(f)",
1533            "f_down(e)",
1534            "f_down(c)",
1535            "f_down(b)",
1536            "f_up(b)",
1537            "f_down(d)",
1538            "f_down(a)",
1539            "f_up(a)",
1540            "f_down(g)",
1541            "f_down(h)",
1542            "f_up(h)",
1543            "f_up(g)",
1544            "f_up(f)",
1545            "f_up(i)",
1546            "f_up(j)",
1547        ]
1548        .into_iter()
1549        .map(|s| s.to_string())
1550        .collect()
1551    }
1552
1553    fn f_up_jump_on_a_transformed_tree() -> TestTreeNode<String> {
1554        let node_a = TestTreeNode::new_leaf("f_up(f_down(a))".to_string());
1555        let node_b = TestTreeNode::new_leaf("f_up(f_down(b))".to_string());
1556        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1557        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1558        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1559        let node_h = TestTreeNode::new_leaf("f_up(f_down(h))".to_string());
1560        let node_g = TestTreeNode::new(vec![node_h], "f_up(f_down(g))".to_string());
1561        let node_f =
1562            TestTreeNode::new(vec![node_e, node_g], "f_up(f_down(f))".to_string());
1563        let node_i = TestTreeNode::new(vec![node_f], "f_up(f_down(i))".to_string());
1564        TestTreeNode::new(vec![node_i], "f_up(f_down(j))".to_string())
1565    }
1566
1567    fn f_up_jump_on_a_transformed_up_tree() -> TestTreeNode<String> {
1568        let node_a = TestTreeNode::new_leaf("f_up(a)".to_string());
1569        let node_b = TestTreeNode::new_leaf("f_up(b)".to_string());
1570        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1571        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1572        let node_e = TestTreeNode::new(vec![node_c], "e".to_string());
1573        let node_h = TestTreeNode::new_leaf("f_up(h)".to_string());
1574        let node_g = TestTreeNode::new(vec![node_h], "f_up(g)".to_string());
1575        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_up(f)".to_string());
1576        let node_i = TestTreeNode::new(vec![node_f], "f_up(i)".to_string());
1577        TestTreeNode::new(vec![node_i], "f_up(j)".to_string())
1578    }
1579
1580    // f_up Jump on E node
1581    fn f_up_jump_on_e_visits() -> Vec<String> {
1582        vec![
1583            "f_down(j)",
1584            "f_down(i)",
1585            "f_down(f)",
1586            "f_down(e)",
1587            "f_down(c)",
1588            "f_down(b)",
1589            "f_up(b)",
1590            "f_down(d)",
1591            "f_down(a)",
1592            "f_up(a)",
1593            "f_up(d)",
1594            "f_up(c)",
1595            "f_up(e)",
1596            "f_down(g)",
1597            "f_down(h)",
1598            "f_up(h)",
1599            "f_up(g)",
1600            "f_up(f)",
1601            "f_up(i)",
1602            "f_up(j)",
1603        ]
1604        .into_iter()
1605        .map(|s| s.to_string())
1606        .collect()
1607    }
1608
1609    fn f_up_jump_on_e_transformed_tree() -> TestTreeNode<String> {
1610        transformed_tree()
1611    }
1612
1613    fn f_up_jump_on_e_transformed_up_tree() -> TestTreeNode<String> {
1614        transformed_up_tree()
1615    }
1616
1617    // f_down Stop on A node
1618
1619    fn f_down_stop_on_a_visits() -> Vec<String> {
1620        vec![
1621            "f_down(j)",
1622            "f_down(i)",
1623            "f_down(f)",
1624            "f_down(e)",
1625            "f_down(c)",
1626            "f_down(b)",
1627            "f_up(b)",
1628            "f_down(d)",
1629            "f_down(a)",
1630        ]
1631        .into_iter()
1632        .map(|s| s.to_string())
1633        .collect()
1634    }
1635
1636    fn f_down_stop_on_a_transformed_tree() -> TestTreeNode<String> {
1637        let node_a = TestTreeNode::new_leaf("f_down(a)".to_string());
1638        let node_b = TestTreeNode::new_leaf("f_up(f_down(b))".to_string());
1639        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1640        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1641        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1642        let node_h = TestTreeNode::new_leaf("h".to_string());
1643        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1644        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1645        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1646        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1647    }
1648
1649    fn f_down_stop_on_a_transformed_down_tree() -> TestTreeNode<String> {
1650        let node_a = TestTreeNode::new_leaf("f_down(a)".to_string());
1651        let node_b = TestTreeNode::new_leaf("f_down(b)".to_string());
1652        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1653        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1654        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1655        let node_h = TestTreeNode::new_leaf("h".to_string());
1656        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1657        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1658        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1659        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1660    }
1661
1662    // f_down Stop on E node
1663    fn f_down_stop_on_e_visits() -> Vec<String> {
1664        vec!["f_down(j)", "f_down(i)", "f_down(f)", "f_down(e)"]
1665            .into_iter()
1666            .map(|s| s.to_string())
1667            .collect()
1668    }
1669
1670    fn f_down_stop_on_e_transformed_tree() -> TestTreeNode<String> {
1671        let node_a = TestTreeNode::new_leaf("a".to_string());
1672        let node_b = TestTreeNode::new_leaf("b".to_string());
1673        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1674        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1675        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1676        let node_h = TestTreeNode::new_leaf("h".to_string());
1677        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1678        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1679        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1680        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1681    }
1682
1683    fn f_down_stop_on_e_transformed_down_tree() -> TestTreeNode<String> {
1684        let node_a = TestTreeNode::new_leaf("a".to_string());
1685        let node_b = TestTreeNode::new_leaf("b".to_string());
1686        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1687        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1688        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1689        let node_h = TestTreeNode::new_leaf("h".to_string());
1690        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1691        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1692        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1693        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1694    }
1695
1696    // f_up Stop on A node
1697    fn f_up_stop_on_a_visits() -> Vec<String> {
1698        vec![
1699            "f_down(j)",
1700            "f_down(i)",
1701            "f_down(f)",
1702            "f_down(e)",
1703            "f_down(c)",
1704            "f_down(b)",
1705            "f_up(b)",
1706            "f_down(d)",
1707            "f_down(a)",
1708            "f_up(a)",
1709        ]
1710        .into_iter()
1711        .map(|s| s.to_string())
1712        .collect()
1713    }
1714
1715    fn f_up_stop_on_a_transformed_tree() -> TestTreeNode<String> {
1716        let node_a = TestTreeNode::new_leaf("f_up(f_down(a))".to_string());
1717        let node_b = TestTreeNode::new_leaf("f_up(f_down(b))".to_string());
1718        let node_d = TestTreeNode::new(vec![node_a], "f_down(d)".to_string());
1719        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_down(c)".to_string());
1720        let node_e = TestTreeNode::new(vec![node_c], "f_down(e)".to_string());
1721        let node_h = TestTreeNode::new_leaf("h".to_string());
1722        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1723        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1724        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1725        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1726    }
1727
1728    fn f_up_stop_on_a_transformed_up_tree() -> TestTreeNode<String> {
1729        let node_a = TestTreeNode::new_leaf("f_up(a)".to_string());
1730        let node_b = TestTreeNode::new_leaf("f_up(b)".to_string());
1731        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
1732        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
1733        let node_e = TestTreeNode::new(vec![node_c], "e".to_string());
1734        let node_h = TestTreeNode::new_leaf("h".to_string());
1735        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1736        let node_f = TestTreeNode::new(vec![node_e, node_g], "f".to_string());
1737        let node_i = TestTreeNode::new(vec![node_f], "i".to_string());
1738        TestTreeNode::new(vec![node_i], "j".to_string())
1739    }
1740
1741    // f_up Stop on E node
1742    fn f_up_stop_on_e_visits() -> Vec<String> {
1743        vec![
1744            "f_down(j)",
1745            "f_down(i)",
1746            "f_down(f)",
1747            "f_down(e)",
1748            "f_down(c)",
1749            "f_down(b)",
1750            "f_up(b)",
1751            "f_down(d)",
1752            "f_down(a)",
1753            "f_up(a)",
1754            "f_up(d)",
1755            "f_up(c)",
1756            "f_up(e)",
1757        ]
1758        .into_iter()
1759        .map(|s| s.to_string())
1760        .collect()
1761    }
1762
1763    fn f_up_stop_on_e_transformed_tree() -> TestTreeNode<String> {
1764        let node_a = TestTreeNode::new_leaf("f_up(f_down(a))".to_string());
1765        let node_b = TestTreeNode::new_leaf("f_up(f_down(b))".to_string());
1766        let node_d = TestTreeNode::new(vec![node_a], "f_up(f_down(d))".to_string());
1767        let node_c =
1768            TestTreeNode::new(vec![node_b, node_d], "f_up(f_down(c))".to_string());
1769        let node_e = TestTreeNode::new(vec![node_c], "f_up(f_down(e))".to_string());
1770        let node_h = TestTreeNode::new_leaf("h".to_string());
1771        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1772        let node_f = TestTreeNode::new(vec![node_e, node_g], "f_down(f)".to_string());
1773        let node_i = TestTreeNode::new(vec![node_f], "f_down(i)".to_string());
1774        TestTreeNode::new(vec![node_i], "f_down(j)".to_string())
1775    }
1776
1777    fn f_up_stop_on_e_transformed_up_tree() -> TestTreeNode<String> {
1778        let node_a = TestTreeNode::new_leaf("f_up(a)".to_string());
1779        let node_b = TestTreeNode::new_leaf("f_up(b)".to_string());
1780        let node_d = TestTreeNode::new(vec![node_a], "f_up(d)".to_string());
1781        let node_c = TestTreeNode::new(vec![node_b, node_d], "f_up(c)".to_string());
1782        let node_e = TestTreeNode::new(vec![node_c], "f_up(e)".to_string());
1783        let node_h = TestTreeNode::new_leaf("h".to_string());
1784        let node_g = TestTreeNode::new(vec![node_h], "g".to_string());
1785        let node_f = TestTreeNode::new(vec![node_e, node_g], "f".to_string());
1786        let node_i = TestTreeNode::new(vec![node_f], "i".to_string());
1787        TestTreeNode::new(vec![node_i], "j".to_string())
1788    }
1789
1790    fn down_visits(visits: Vec<String>) -> Vec<String> {
1791        visits
1792            .into_iter()
1793            .filter(|v| v.starts_with("f_down"))
1794            .collect()
1795    }
1796
1797    type TestVisitorF<T> = Box<dyn FnMut(&TestTreeNode<T>) -> Result<TreeNodeRecursion>>;
1798
1799    struct TestVisitor<T> {
1800        visits: Vec<String>,
1801        f_down: TestVisitorF<T>,
1802        f_up: TestVisitorF<T>,
1803    }
1804
1805    impl<T> TestVisitor<T> {
1806        fn new(f_down: TestVisitorF<T>, f_up: TestVisitorF<T>) -> Self {
1807            Self {
1808                visits: vec![],
1809                f_down,
1810                f_up,
1811            }
1812        }
1813    }
1814
1815    impl<'n, T: Display> TreeNodeVisitor<'n> for TestVisitor<T> {
1816        type Node = TestTreeNode<T>;
1817
1818        fn f_down(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> {
1819            self.visits.push(format!("f_down({})", node.data));
1820            (*self.f_down)(node)
1821        }
1822
1823        fn f_up(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> {
1824            self.visits.push(format!("f_up({})", node.data));
1825            (*self.f_up)(node)
1826        }
1827    }
1828
1829    fn visit_continue<T>(_: &TestTreeNode<T>) -> Result<TreeNodeRecursion> {
1830        Ok(TreeNodeRecursion::Continue)
1831    }
1832
1833    fn visit_event_on<T: PartialEq, D: Into<T>>(
1834        data: D,
1835        event: TreeNodeRecursion,
1836    ) -> impl FnMut(&TestTreeNode<T>) -> Result<TreeNodeRecursion> {
1837        let d = data.into();
1838        move |node| {
1839            Ok(if node.data == d {
1840                event
1841            } else {
1842                TreeNodeRecursion::Continue
1843            })
1844        }
1845    }
1846
1847    macro_rules! visit_test {
1848        ($NAME:ident, $F_DOWN:expr, $F_UP:expr, $EXPECTED_VISITS:expr) => {
1849            #[test]
1850            fn $NAME() -> Result<()> {
1851                let tree = test_tree();
1852                let mut visitor = TestVisitor::new(Box::new($F_DOWN), Box::new($F_UP));
1853                tree.visit(&mut visitor)?;
1854                assert_eq!(visitor.visits, $EXPECTED_VISITS);
1855
1856                Ok(())
1857            }
1858        };
1859    }
1860
1861    macro_rules! test_apply {
1862        ($NAME:ident, $F:expr, $EXPECTED_VISITS:expr) => {
1863            #[test]
1864            fn $NAME() -> Result<()> {
1865                let tree = test_tree();
1866                let mut visits = vec![];
1867                tree.apply(|node| {
1868                    visits.push(format!("f_down({})", node.data));
1869                    $F(node)
1870                })?;
1871                assert_eq!(visits, $EXPECTED_VISITS);
1872
1873                Ok(())
1874            }
1875        };
1876    }
1877
1878    type TestRewriterF<T> =
1879        Box<dyn FnMut(TestTreeNode<T>) -> Result<Transformed<TestTreeNode<T>>>>;
1880
1881    struct TestRewriter<T> {
1882        f_down: TestRewriterF<T>,
1883        f_up: TestRewriterF<T>,
1884    }
1885
1886    impl<T> TestRewriter<T> {
1887        fn new(f_down: TestRewriterF<T>, f_up: TestRewriterF<T>) -> Self {
1888            Self { f_down, f_up }
1889        }
1890    }
1891
1892    impl<T: Display> TreeNodeRewriter for TestRewriter<T> {
1893        type Node = TestTreeNode<T>;
1894
1895        fn f_down(&mut self, node: Self::Node) -> Result<Transformed<Self::Node>> {
1896            (*self.f_down)(node)
1897        }
1898
1899        fn f_up(&mut self, node: Self::Node) -> Result<Transformed<Self::Node>> {
1900            (*self.f_up)(node)
1901        }
1902    }
1903
1904    fn transform_yes<N: Display, T: Display + From<String>>(
1905        transformation_name: N,
1906    ) -> impl FnMut(TestTreeNode<T>) -> Result<Transformed<TestTreeNode<T>>> {
1907        move |node| {
1908            Ok(Transformed::yes(TestTreeNode::new(
1909                node.children,
1910                format!("{}({})", transformation_name, node.data).into(),
1911            )))
1912        }
1913    }
1914
1915    fn transform_and_event_on<
1916        N: Display,
1917        T: PartialEq + Display + From<String>,
1918        D: Into<T>,
1919    >(
1920        transformation_name: N,
1921        data: D,
1922        event: TreeNodeRecursion,
1923    ) -> impl FnMut(TestTreeNode<T>) -> Result<Transformed<TestTreeNode<T>>> {
1924        let d = data.into();
1925        move |node| {
1926            let new_node = TestTreeNode::new(
1927                node.children,
1928                format!("{}({})", transformation_name, node.data).into(),
1929            );
1930            Ok(if node.data == d {
1931                Transformed::new(new_node, true, event)
1932            } else {
1933                Transformed::yes(new_node)
1934            })
1935        }
1936    }
1937
1938    macro_rules! rewrite_test {
1939        ($NAME:ident, $F_DOWN:expr, $F_UP:expr, $EXPECTED_TREE:expr) => {
1940            #[test]
1941            fn $NAME() -> Result<()> {
1942                let tree = test_tree();
1943                let mut rewriter = TestRewriter::new(Box::new($F_DOWN), Box::new($F_UP));
1944                assert_eq!(tree.rewrite(&mut rewriter)?, $EXPECTED_TREE);
1945
1946                Ok(())
1947            }
1948        };
1949    }
1950
1951    macro_rules! transform_test {
1952        ($NAME:ident, $F_DOWN:expr, $F_UP:expr, $EXPECTED_TREE:expr) => {
1953            #[test]
1954            fn $NAME() -> Result<()> {
1955                let tree = test_tree();
1956                assert_eq!(tree.transform_down_up($F_DOWN, $F_UP,)?, $EXPECTED_TREE);
1957
1958                Ok(())
1959            }
1960        };
1961    }
1962
1963    macro_rules! transform_down_test {
1964        ($NAME:ident, $F:expr, $EXPECTED_TREE:expr) => {
1965            #[test]
1966            fn $NAME() -> Result<()> {
1967                let tree = test_tree();
1968                assert_eq!(tree.transform_down($F)?, $EXPECTED_TREE);
1969
1970                Ok(())
1971            }
1972        };
1973    }
1974
1975    macro_rules! transform_up_test {
1976        ($NAME:ident, $F:expr, $EXPECTED_TREE:expr) => {
1977            #[test]
1978            fn $NAME() -> Result<()> {
1979                let tree = test_tree();
1980                assert_eq!(tree.transform_up($F)?, $EXPECTED_TREE);
1981
1982                Ok(())
1983            }
1984        };
1985    }
1986
1987    visit_test!(test_visit, visit_continue, visit_continue, all_visits());
1988    visit_test!(
1989        test_visit_f_down_jump_on_a,
1990        visit_event_on("a", TreeNodeRecursion::Jump),
1991        visit_continue,
1992        f_down_jump_on_a_visits()
1993    );
1994    visit_test!(
1995        test_visit_f_down_jump_on_e,
1996        visit_event_on("e", TreeNodeRecursion::Jump),
1997        visit_continue,
1998        f_down_jump_on_e_visits()
1999    );
2000    visit_test!(
2001        test_visit_f_up_jump_on_a,
2002        visit_continue,
2003        visit_event_on("a", TreeNodeRecursion::Jump),
2004        f_up_jump_on_a_visits()
2005    );
2006    visit_test!(
2007        test_visit_f_up_jump_on_e,
2008        visit_continue,
2009        visit_event_on("e", TreeNodeRecursion::Jump),
2010        f_up_jump_on_e_visits()
2011    );
2012    visit_test!(
2013        test_visit_f_down_stop_on_a,
2014        visit_event_on("a", TreeNodeRecursion::Stop),
2015        visit_continue,
2016        f_down_stop_on_a_visits()
2017    );
2018    visit_test!(
2019        test_visit_f_down_stop_on_e,
2020        visit_event_on("e", TreeNodeRecursion::Stop),
2021        visit_continue,
2022        f_down_stop_on_e_visits()
2023    );
2024    visit_test!(
2025        test_visit_f_up_stop_on_a,
2026        visit_continue,
2027        visit_event_on("a", TreeNodeRecursion::Stop),
2028        f_up_stop_on_a_visits()
2029    );
2030    visit_test!(
2031        test_visit_f_up_stop_on_e,
2032        visit_continue,
2033        visit_event_on("e", TreeNodeRecursion::Stop),
2034        f_up_stop_on_e_visits()
2035    );
2036
2037    test_apply!(test_apply, visit_continue, down_visits(all_visits()));
2038    test_apply!(
2039        test_apply_f_down_jump_on_a,
2040        visit_event_on("a", TreeNodeRecursion::Jump),
2041        down_visits(f_down_jump_on_a_visits())
2042    );
2043    test_apply!(
2044        test_apply_f_down_jump_on_e,
2045        visit_event_on("e", TreeNodeRecursion::Jump),
2046        down_visits(f_down_jump_on_e_visits())
2047    );
2048    test_apply!(
2049        test_apply_f_down_stop_on_a,
2050        visit_event_on("a", TreeNodeRecursion::Stop),
2051        down_visits(f_down_stop_on_a_visits())
2052    );
2053    test_apply!(
2054        test_apply_f_down_stop_on_e,
2055        visit_event_on("e", TreeNodeRecursion::Stop),
2056        down_visits(f_down_stop_on_e_visits())
2057    );
2058
2059    rewrite_test!(
2060        test_rewrite,
2061        transform_yes("f_down"),
2062        transform_yes("f_up"),
2063        Transformed::yes(transformed_tree())
2064    );
2065    rewrite_test!(
2066        test_rewrite_f_down_jump_on_a,
2067        transform_and_event_on("f_down", "a", TreeNodeRecursion::Jump),
2068        transform_yes("f_up"),
2069        Transformed::yes(transformed_tree())
2070    );
2071    rewrite_test!(
2072        test_rewrite_f_down_jump_on_e,
2073        transform_and_event_on("f_down", "e", TreeNodeRecursion::Jump),
2074        transform_yes("f_up"),
2075        Transformed::yes(f_down_jump_on_e_transformed_tree())
2076    );
2077    rewrite_test!(
2078        test_rewrite_f_up_jump_on_a,
2079        transform_yes("f_down"),
2080        transform_and_event_on("f_up", "f_down(a)", TreeNodeRecursion::Jump),
2081        Transformed::yes(f_up_jump_on_a_transformed_tree())
2082    );
2083    rewrite_test!(
2084        test_rewrite_f_up_jump_on_e,
2085        transform_yes("f_down"),
2086        transform_and_event_on("f_up", "f_down(e)", TreeNodeRecursion::Jump),
2087        Transformed::yes(f_up_jump_on_e_transformed_tree())
2088    );
2089    rewrite_test!(
2090        test_rewrite_f_down_stop_on_a,
2091        transform_and_event_on("f_down", "a", TreeNodeRecursion::Stop),
2092        transform_yes("f_up"),
2093        Transformed::new(
2094            f_down_stop_on_a_transformed_tree(),
2095            true,
2096            TreeNodeRecursion::Stop
2097        )
2098    );
2099    rewrite_test!(
2100        test_rewrite_f_down_stop_on_e,
2101        transform_and_event_on("f_down", "e", TreeNodeRecursion::Stop),
2102        transform_yes("f_up"),
2103        Transformed::new(
2104            f_down_stop_on_e_transformed_tree(),
2105            true,
2106            TreeNodeRecursion::Stop
2107        )
2108    );
2109    rewrite_test!(
2110        test_rewrite_f_up_stop_on_a,
2111        transform_yes("f_down"),
2112        transform_and_event_on("f_up", "f_down(a)", TreeNodeRecursion::Stop),
2113        Transformed::new(
2114            f_up_stop_on_a_transformed_tree(),
2115            true,
2116            TreeNodeRecursion::Stop
2117        )
2118    );
2119    rewrite_test!(
2120        test_rewrite_f_up_stop_on_e,
2121        transform_yes("f_down"),
2122        transform_and_event_on("f_up", "f_down(e)", TreeNodeRecursion::Stop),
2123        Transformed::new(
2124            f_up_stop_on_e_transformed_tree(),
2125            true,
2126            TreeNodeRecursion::Stop
2127        )
2128    );
2129
2130    transform_test!(
2131        test_transform,
2132        transform_yes("f_down"),
2133        transform_yes("f_up"),
2134        Transformed::yes(transformed_tree())
2135    );
2136    transform_test!(
2137        test_transform_f_down_jump_on_a,
2138        transform_and_event_on("f_down", "a", TreeNodeRecursion::Jump),
2139        transform_yes("f_up"),
2140        Transformed::yes(transformed_tree())
2141    );
2142    transform_test!(
2143        test_transform_f_down_jump_on_e,
2144        transform_and_event_on("f_down", "e", TreeNodeRecursion::Jump),
2145        transform_yes("f_up"),
2146        Transformed::yes(f_down_jump_on_e_transformed_tree())
2147    );
2148    transform_test!(
2149        test_transform_f_up_jump_on_a,
2150        transform_yes("f_down"),
2151        transform_and_event_on("f_up", "f_down(a)", TreeNodeRecursion::Jump),
2152        Transformed::yes(f_up_jump_on_a_transformed_tree())
2153    );
2154    transform_test!(
2155        test_transform_f_up_jump_on_e,
2156        transform_yes("f_down"),
2157        transform_and_event_on("f_up", "f_down(e)", TreeNodeRecursion::Jump),
2158        Transformed::yes(f_up_jump_on_e_transformed_tree())
2159    );
2160    transform_test!(
2161        test_transform_f_down_stop_on_a,
2162        transform_and_event_on("f_down", "a", TreeNodeRecursion::Stop),
2163        transform_yes("f_up"),
2164        Transformed::new(
2165            f_down_stop_on_a_transformed_tree(),
2166            true,
2167            TreeNodeRecursion::Stop
2168        )
2169    );
2170    transform_test!(
2171        test_transform_f_down_stop_on_e,
2172        transform_and_event_on("f_down", "e", TreeNodeRecursion::Stop),
2173        transform_yes("f_up"),
2174        Transformed::new(
2175            f_down_stop_on_e_transformed_tree(),
2176            true,
2177            TreeNodeRecursion::Stop
2178        )
2179    );
2180    transform_test!(
2181        test_transform_f_up_stop_on_a,
2182        transform_yes("f_down"),
2183        transform_and_event_on("f_up", "f_down(a)", TreeNodeRecursion::Stop),
2184        Transformed::new(
2185            f_up_stop_on_a_transformed_tree(),
2186            true,
2187            TreeNodeRecursion::Stop
2188        )
2189    );
2190    transform_test!(
2191        test_transform_f_up_stop_on_e,
2192        transform_yes("f_down"),
2193        transform_and_event_on("f_up", "f_down(e)", TreeNodeRecursion::Stop),
2194        Transformed::new(
2195            f_up_stop_on_e_transformed_tree(),
2196            true,
2197            TreeNodeRecursion::Stop
2198        )
2199    );
2200
2201    transform_down_test!(
2202        test_transform_down,
2203        transform_yes("f_down"),
2204        Transformed::yes(transformed_down_tree())
2205    );
2206    transform_down_test!(
2207        test_transform_down_f_down_jump_on_a,
2208        transform_and_event_on("f_down", "a", TreeNodeRecursion::Jump),
2209        Transformed::yes(f_down_jump_on_a_transformed_down_tree())
2210    );
2211    transform_down_test!(
2212        test_transform_down_f_down_jump_on_e,
2213        transform_and_event_on("f_down", "e", TreeNodeRecursion::Jump),
2214        Transformed::yes(f_down_jump_on_e_transformed_down_tree())
2215    );
2216    transform_down_test!(
2217        test_transform_down_f_down_stop_on_a,
2218        transform_and_event_on("f_down", "a", TreeNodeRecursion::Stop),
2219        Transformed::new(
2220            f_down_stop_on_a_transformed_down_tree(),
2221            true,
2222            TreeNodeRecursion::Stop
2223        )
2224    );
2225    transform_down_test!(
2226        test_transform_down_f_down_stop_on_e,
2227        transform_and_event_on("f_down", "e", TreeNodeRecursion::Stop),
2228        Transformed::new(
2229            f_down_stop_on_e_transformed_down_tree(),
2230            true,
2231            TreeNodeRecursion::Stop
2232        )
2233    );
2234
2235    transform_up_test!(
2236        test_transform_up,
2237        transform_yes("f_up"),
2238        Transformed::yes(transformed_up_tree())
2239    );
2240    transform_up_test!(
2241        test_transform_up_f_up_jump_on_a,
2242        transform_and_event_on("f_up", "a", TreeNodeRecursion::Jump),
2243        Transformed::yes(f_up_jump_on_a_transformed_up_tree())
2244    );
2245    transform_up_test!(
2246        test_transform_up_f_up_jump_on_e,
2247        transform_and_event_on("f_up", "e", TreeNodeRecursion::Jump),
2248        Transformed::yes(f_up_jump_on_e_transformed_up_tree())
2249    );
2250    transform_up_test!(
2251        test_transform_up_f_up_stop_on_a,
2252        transform_and_event_on("f_up", "a", TreeNodeRecursion::Stop),
2253        Transformed::new(
2254            f_up_stop_on_a_transformed_up_tree(),
2255            true,
2256            TreeNodeRecursion::Stop
2257        )
2258    );
2259    transform_up_test!(
2260        test_transform_up_f_up_stop_on_e,
2261        transform_and_event_on("f_up", "e", TreeNodeRecursion::Stop),
2262        Transformed::new(
2263            f_up_stop_on_e_transformed_up_tree(),
2264            true,
2265            TreeNodeRecursion::Stop
2266        )
2267    );
2268
2269    //             F
2270    //          /  |  \
2271    //       /     |     \
2272    //    E        C        A
2273    //    |      /   \
2274    //    C     B     D
2275    //  /   \         |
2276    // B     D        A
2277    //       |
2278    //       A
2279    #[test]
2280    fn test_apply_and_visit_references() -> Result<()> {
2281        let node_a = TestTreeNode::new_leaf("a".to_string());
2282        let node_b = TestTreeNode::new_leaf("b".to_string());
2283        let node_d = TestTreeNode::new(vec![node_a], "d".to_string());
2284        let node_c = TestTreeNode::new(vec![node_b, node_d], "c".to_string());
2285        let node_e = TestTreeNode::new(vec![node_c], "e".to_string());
2286        let node_a_2 = TestTreeNode::new_leaf("a".to_string());
2287        let node_b_2 = TestTreeNode::new_leaf("b".to_string());
2288        let node_d_2 = TestTreeNode::new(vec![node_a_2], "d".to_string());
2289        let node_c_2 = TestTreeNode::new(vec![node_b_2, node_d_2], "c".to_string());
2290        let node_a_3 = TestTreeNode::new_leaf("a".to_string());
2291        let tree = TestTreeNode::new(vec![node_e, node_c_2, node_a_3], "f".to_string());
2292
2293        let node_f_ref = &tree;
2294        let node_e_ref = &node_f_ref.children[0];
2295        let node_c_ref = &node_e_ref.children[0];
2296        let node_b_ref = &node_c_ref.children[0];
2297        let node_d_ref = &node_c_ref.children[1];
2298        let node_a_ref = &node_d_ref.children[0];
2299
2300        let mut m: HashMap<&TestTreeNode<String>, usize> = HashMap::new();
2301        tree.apply(|e| {
2302            *m.entry(e).or_insert(0) += 1;
2303            Ok(TreeNodeRecursion::Continue)
2304        })?;
2305
2306        let expected = HashMap::from([
2307            (node_f_ref, 1),
2308            (node_e_ref, 1),
2309            (node_c_ref, 2),
2310            (node_d_ref, 2),
2311            (node_b_ref, 2),
2312            (node_a_ref, 3),
2313        ]);
2314        assert_eq!(m, expected);
2315
2316        struct TestVisitor<'n> {
2317            m: HashMap<&'n TestTreeNode<String>, (usize, usize)>,
2318        }
2319
2320        impl<'n> TreeNodeVisitor<'n> for TestVisitor<'n> {
2321            type Node = TestTreeNode<String>;
2322
2323            fn f_down(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> {
2324                let (down_count, _) = self.m.entry(node).or_insert((0, 0));
2325                *down_count += 1;
2326                Ok(TreeNodeRecursion::Continue)
2327            }
2328
2329            fn f_up(&mut self, node: &'n Self::Node) -> Result<TreeNodeRecursion> {
2330                let (_, up_count) = self.m.entry(node).or_insert((0, 0));
2331                *up_count += 1;
2332                Ok(TreeNodeRecursion::Continue)
2333            }
2334        }
2335
2336        let mut visitor = TestVisitor { m: HashMap::new() };
2337        tree.visit(&mut visitor)?;
2338
2339        let expected = HashMap::from([
2340            (node_f_ref, (1, 1)),
2341            (node_e_ref, (1, 1)),
2342            (node_c_ref, (2, 2)),
2343            (node_d_ref, (2, 2)),
2344            (node_b_ref, (2, 2)),
2345            (node_a_ref, (3, 3)),
2346        ]);
2347        assert_eq!(visitor.m, expected);
2348
2349        Ok(())
2350    }
2351
2352    #[cfg(feature = "recursive_protection")]
2353    #[test]
2354    fn test_large_tree() {
2355        let mut item = TestTreeNode::new_leaf("initial".to_string());
2356        for i in 0..3000 {
2357            item = TestTreeNode::new(vec![item], format!("parent-{}", i));
2358        }
2359
2360        let mut visitor =
2361            TestVisitor::new(Box::new(visit_continue), Box::new(visit_continue));
2362
2363        item.visit(&mut visitor).unwrap();
2364    }
2365}