sqlexpr-congo-rust 1.0.0

Parser for SqlExprParser - Generated by CongoCC
Documentation
//! Visitor for depth-first AST traversal. Generated by CongoCC Parser Generator. Do not edit.

use std::any::Any;
use crate::arena::{Arena, NodeId, AstNode};

/// Controls visitor traversal behavior
pub enum VisitControl {
    /// Visit children, then continue with siblings
    Continue,
    /// Skip this node's children, continue with siblings
    SkipChildren,
    /// Stop traversal entirely
    Stop,
}

impl Arena {
    /// Visit all nodes depth-first starting from `root`.
    ///
    /// The closure `f` receives `(node_id, node, arena, depth, options)` and returns
    /// a `VisitControl` to guide traversal. `options` is an optional caller-supplied
    /// context passed through to every invocation.
    pub fn visit<F>(&self, root: NodeId, f: &mut F, options: Option<&dyn Any>) -> VisitControl
    where
        F: FnMut(NodeId, &AstNode, &Arena, usize, Option<&dyn Any>) -> VisitControl,
    {
        self.visit_impl(root, 0, f, options)
    }

    fn visit_impl<F>(
        &self,
        node_id: NodeId,
        depth: usize,
        f: &mut F,
        options: Option<&dyn Any>,
    ) -> VisitControl
    where
        F: FnMut(NodeId, &AstNode, &Arena, usize, Option<&dyn Any>) -> VisitControl,
    {
        let node = self.get_node(node_id);
        let children: Vec<NodeId> = match node {
            AstNode::JmsSelector(n) => n.children.clone(),
            AstNode::OrExpression(n) => n.children.clone(),
            AstNode::AndExpression(n) => n.children.clone(),
            AstNode::EqualityExpression(n) => n.children.clone(),
            AstNode::ComparisonExpression(n) => n.children.clone(),
            AstNode::AddExpression(n) => n.children.clone(),
            AstNode::MultExpr(n) => n.children.clone(),
            AstNode::UnaryExpr(n) => n.children.clone(),
            AstNode::PrimaryExpr(n) => n.children.clone(),
            AstNode::Literal(n) => n.children.clone(),
            AstNode::StringLiteral(n) => n.children.clone(),
            AstNode::Variable(n) => n.children.clone(),
        };
        match f(node_id, node, self, depth, options) {
            VisitControl::Stop => return VisitControl::Stop,
            VisitControl::SkipChildren => return VisitControl::Continue,
            VisitControl::Continue => {}
        }
        for child in children {
            if matches!(
                self.visit_impl(child, depth + 1, f, options),
                VisitControl::Stop
            ) {
                return VisitControl::Stop;
            }
        }
        VisitControl::Continue
    }
}