Skip to main content

tonbo_predicate/core/
builder.rs

1//! Small helpers for building predicates.
2use super::{ComparisonOp, Operand, Predicate, PredicateNode, ScalarValue};
3
4/// Convenience constructors mirroring DataFusion-style expression helpers.
5impl Predicate {
6    /// Returns a predicate that always evaluates to true (matches all rows).
7    #[must_use]
8    pub fn always() -> Self {
9        Predicate::from_kind(PredicateNode::True)
10    }
11
12    /// Create a comparison predicate.
13    #[must_use]
14    pub fn compare<L, R>(left: L, op: ComparisonOp, right: R) -> Self
15    where
16        L: Into<Operand>,
17        R: Into<Operand>,
18    {
19        Predicate::from_kind(PredicateNode::Compare {
20            left: left.into(),
21            op,
22            right: right.into(),
23        })
24    }
25
26    /// Equality predicate.
27    #[must_use]
28    pub fn eq<L, R>(left: L, right: R) -> Self
29    where
30        L: Into<Operand>,
31        R: Into<Operand>,
32    {
33        Self::compare(left, ComparisonOp::Equal, right)
34    }
35
36    /// Inequality predicate.
37    #[must_use]
38    pub fn neq<L, R>(left: L, right: R) -> Self
39    where
40        L: Into<Operand>,
41        R: Into<Operand>,
42    {
43        Self::compare(left, ComparisonOp::NotEqual, right)
44    }
45
46    /// Less-than predicate.
47    #[must_use]
48    pub fn lt<L, R>(left: L, right: R) -> Self
49    where
50        L: Into<Operand>,
51        R: Into<Operand>,
52    {
53        Self::compare(left, ComparisonOp::LessThan, right)
54    }
55
56    /// Less-than-or-equal predicate.
57    #[must_use]
58    pub fn lte<L, R>(left: L, right: R) -> Self
59    where
60        L: Into<Operand>,
61        R: Into<Operand>,
62    {
63        Self::compare(left, ComparisonOp::LessThanOrEqual, right)
64    }
65
66    /// Greater-than predicate.
67    #[must_use]
68    pub fn gt<L, R>(left: L, right: R) -> Self
69    where
70        L: Into<Operand>,
71        R: Into<Operand>,
72    {
73        Self::compare(left, ComparisonOp::GreaterThan, right)
74    }
75
76    /// Greater-than-or-equal predicate.
77    #[must_use]
78    pub fn gte<L, R>(left: L, right: R) -> Self
79    where
80        L: Into<Operand>,
81        R: Into<Operand>,
82    {
83        Self::compare(left, ComparisonOp::GreaterThanOrEqual, right)
84    }
85
86    /// `IN` list predicate.
87    #[must_use]
88    pub fn in_list<O, I>(expr: O, list: I) -> Self
89    where
90        O: Into<Operand>,
91        I: IntoIterator<Item = ScalarValue>,
92    {
93        Predicate::from_kind(PredicateNode::InList {
94            expr: expr.into(),
95            list: list.into_iter().collect(),
96            negated: false,
97        })
98    }
99
100    /// `NOT IN` list predicate.
101    #[must_use]
102    pub fn not_in_list<O, I>(expr: O, list: I) -> Self
103    where
104        O: Into<Operand>,
105        I: IntoIterator<Item = ScalarValue>,
106    {
107        Predicate::from_kind(PredicateNode::InList {
108            expr: expr.into(),
109            list: list.into_iter().collect(),
110            negated: true,
111        })
112    }
113
114    /// `IS NULL` predicate.
115    #[must_use]
116    pub fn is_null<O>(expr: O) -> Self
117    where
118        O: Into<Operand>,
119    {
120        Predicate::from_kind(PredicateNode::IsNull {
121            expr: expr.into(),
122            negated: false,
123        })
124    }
125
126    /// `IS NOT NULL` predicate.
127    #[must_use]
128    pub fn is_not_null<O>(expr: O) -> Self
129    where
130        O: Into<Operand>,
131    {
132        Predicate::from_kind(PredicateNode::IsNull {
133            expr: expr.into(),
134            negated: true,
135        })
136    }
137
138    /// Logical negation.
139    #[must_use]
140    #[allow(clippy::should_implement_trait)]
141    pub fn not(self) -> Self {
142        Predicate::from_kind(PredicateNode::Not(Box::new(self)))
143    }
144}