Path: blob/main/crates/polars-plan/src/plans/visitor/visitors.rs
6940 views
use recursive::recursive;12use super::*;34/// An implementor of this trait decides how and in which order its nodes get traversed5/// Implemented for [`crate::dsl::Expr`] and [`AexprNode`].6pub trait TreeWalker: Sized {7type Arena;8fn apply_children<F: FnMut(&Self, &Self::Arena) -> PolarsResult<VisitRecursion>>(9&self,10op: &mut F,11arena: &Self::Arena,12) -> PolarsResult<VisitRecursion>;1314fn map_children<F: FnMut(Self, &mut Self::Arena) -> PolarsResult<Self>>(15self,16op: &mut F,17arena: &mut Self::Arena,18) -> PolarsResult<Self>;1920/// Walks all nodes in depth-first-order.21#[recursive]22fn visit<V: Visitor<Node = Self, Arena = Self::Arena>>(23&self,24visitor: &mut V,25arena: &Self::Arena,26) -> PolarsResult<VisitRecursion> {27match visitor.pre_visit(self, arena)? {28VisitRecursion::Continue => {},29// If the recursion should skip, do not apply to its children. And let the recursion continue30VisitRecursion::Skip => return Ok(VisitRecursion::Continue),31// If the recursion should stop, do not apply to its children32VisitRecursion::Stop => return Ok(VisitRecursion::Stop),33};3435match self.apply_children(&mut |node, arena| node.visit(visitor, arena), arena)? {36// let the recursion continue37VisitRecursion::Continue | VisitRecursion::Skip => {},38// If the recursion should stop, no further post visit will be performed39VisitRecursion::Stop => return Ok(VisitRecursion::Stop),40}4142visitor.post_visit(self, arena)43}4445#[recursive]46fn rewrite<R: RewritingVisitor<Node = Self, Arena = Self::Arena>>(47self,48rewriter: &mut R,49arena: &mut Self::Arena,50) -> PolarsResult<Self> {51let mutate_this_node = match rewriter.pre_visit(&self, arena)? {52RewriteRecursion::MutateAndStop => return rewriter.mutate(self, arena),53RewriteRecursion::Stop => return Ok(self),54RewriteRecursion::MutateAndContinue => true,55RewriteRecursion::NoMutateAndContinue => false,56};5758let after_applied_children =59self.map_children(&mut |node, arena| node.rewrite(rewriter, arena), arena)?;6061if mutate_this_node {62rewriter.mutate(after_applied_children, arena)63} else {64Ok(after_applied_children)65}66}67}6869pub trait Visitor {70type Node;71type Arena;7273/// Invoked before any children of `node` are visited.74fn pre_visit(75&mut self,76_node: &Self::Node,77_arena: &Self::Arena,78) -> PolarsResult<VisitRecursion> {79Ok(VisitRecursion::Continue)80}8182/// Invoked after all children of `node` are visited. Default83/// implementation does nothing.84fn post_visit(85&mut self,86_node: &Self::Node,87_arena: &Self::Arena,88) -> PolarsResult<VisitRecursion> {89Ok(VisitRecursion::Continue)90}91}9293pub trait RewritingVisitor {94type Node;95type Arena;9697/// Invoked before any children of `node` are visited.98fn pre_visit(99&mut self,100_node: &Self::Node,101_arena: &mut Self::Arena,102) -> PolarsResult<RewriteRecursion> {103Ok(RewriteRecursion::MutateAndContinue)104}105106fn mutate(&mut self, node: Self::Node, _arena: &mut Self::Arena) -> PolarsResult<Self::Node>;107}108109110