tonbo_predicate/core/
visitor.rs1use super::{Predicate, PredicateNode};
2
3#[derive(Clone, Debug, Default)]
5pub struct VisitOutcome<T> {
6 pub value: Option<T>,
8 pub residual: Option<Predicate>,
10}
11
12impl<T> VisitOutcome<T> {
13 pub fn value(value: T) -> Self {
15 Self {
16 value: Some(value),
17 residual: None,
18 }
19 }
20
21 pub fn residual(residual: Predicate) -> Self {
23 Self {
24 value: None,
25 residual: Some(residual),
26 }
27 }
28
29 pub fn empty() -> Self {
31 Self {
32 value: None,
33 residual: None,
34 }
35 }
36}
37
38pub trait PredicateVisitor {
40 type Error;
42 type Value;
44
45 fn visit_leaf(
47 &mut self,
48 leaf: &PredicateNode,
49 ) -> Result<VisitOutcome<Self::Value>, Self::Error>;
50
51 fn combine_not(
53 &mut self,
54 original: &Predicate,
55 child: VisitOutcome<Self::Value>,
56 ) -> Result<VisitOutcome<Self::Value>, Self::Error>;
57
58 fn combine_and(
60 &mut self,
61 original: &Predicate,
62 children: Vec<VisitOutcome<Self::Value>>,
63 ) -> Result<VisitOutcome<Self::Value>, Self::Error>;
64
65 fn combine_or(
67 &mut self,
68 original: &Predicate,
69 children: Vec<VisitOutcome<Self::Value>>,
70 ) -> Result<VisitOutcome<Self::Value>, Self::Error>;
71
72 fn visit_predicate(
74 &mut self,
75 predicate: &Predicate,
76 ) -> Result<VisitOutcome<Self::Value>, Self::Error> {
77 self.visit_node(predicate.kind(), predicate)
78 }
79
80 fn visit_node(
82 &mut self,
83 node: &PredicateNode,
84 original: &Predicate,
85 ) -> Result<VisitOutcome<Self::Value>, Self::Error> {
86 match node {
87 PredicateNode::Not(inner) => {
88 let child = self.visit_predicate(inner)?;
89 self.combine_not(original, child)
90 }
91 PredicateNode::And(clauses) => {
92 debug_assert!(
93 !clauses.is_empty(),
94 "Predicate::make_and enforces at least one clause"
95 );
96 let mut children = Vec::with_capacity(clauses.len());
97 for clause in clauses {
98 children.push(self.visit_predicate(clause)?);
99 }
100 self.combine_and(original, children)
101 }
102 PredicateNode::Or(clauses) => {
103 debug_assert!(
104 !clauses.is_empty(),
105 "Predicate::make_or enforces at least one clause"
106 );
107 let mut children = Vec::with_capacity(clauses.len());
108 for clause in clauses {
109 children.push(self.visit_predicate(clause)?);
110 }
111 self.combine_or(original, children)
112 }
113 leaf => {
114 debug_assert!(leaf.is_leaf(), "non-leaf nodes handled earlier");
115 self.visit_leaf(leaf)
116 }
117 }
118 }
119}