icydb_core/db/query/predicate/
ast.rs1use crate::{db::query::predicate::coercion::CoercionSpec, value::Value};
2use std::ops::{BitAnd, BitOr};
3
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
22pub enum CompareOp {
23 Eq,
24 Ne,
25 Lt,
26 Lte,
27 Gt,
28 Gte,
29 In,
30 NotIn,
31 AnyIn,
32 AllIn,
33 Contains,
34 StartsWith,
35 EndsWith,
36}
37
38#[derive(Clone, Debug, Eq, PartialEq)]
43pub struct ComparePredicate {
44 pub field: String,
45 pub op: CompareOp,
46 pub value: Value,
47 pub coercion: CoercionSpec,
48}
49
50impl ComparePredicate {
51 fn new(field: String, op: CompareOp, value: Value) -> Self {
52 Self {
53 field,
54 op,
55 value,
56 coercion: CoercionSpec::default(),
57 }
58 }
59
60 #[must_use]
61 pub fn eq(field: String, value: Value) -> Self {
62 Self::new(field, CompareOp::Eq, value)
63 }
64
65 #[must_use]
66 pub fn ne(field: String, value: Value) -> Self {
67 Self::new(field, CompareOp::Ne, value)
68 }
69
70 #[must_use]
71 pub fn lt(field: String, value: Value) -> Self {
72 Self::new(field, CompareOp::Lt, value)
73 }
74
75 #[must_use]
76 pub fn lte(field: String, value: Value) -> Self {
77 Self::new(field, CompareOp::Lte, value)
78 }
79
80 #[must_use]
81 pub fn gt(field: String, value: Value) -> Self {
82 Self::new(field, CompareOp::Gt, value)
83 }
84
85 #[must_use]
86 pub fn gte(field: String, value: Value) -> Self {
87 Self::new(field, CompareOp::Gte, value)
88 }
89
90 #[must_use]
91 pub fn in_(field: String, values: Vec<Value>) -> Self {
92 Self::new(field, CompareOp::In, Value::List(values))
93 }
94
95 #[must_use]
96 pub fn not_in(field: String, values: Vec<Value>) -> Self {
97 Self::new(field, CompareOp::NotIn, Value::List(values))
98 }
99}
100
101#[derive(Clone, Debug, Eq, PartialEq)]
106pub enum Predicate {
107 True,
108 False,
109 And(Vec<Self>),
110 Or(Vec<Self>),
111 Not(Box<Self>),
112 Compare(ComparePredicate),
113 IsNull {
114 field: String,
115 },
116 IsMissing {
117 field: String,
118 },
119 IsEmpty {
120 field: String,
121 },
122 IsNotEmpty {
123 field: String,
124 },
125 MapContainsKey {
126 field: String,
127 key: Value,
128 coercion: CoercionSpec,
129 },
130 MapContainsValue {
131 field: String,
132 value: Value,
133 coercion: CoercionSpec,
134 },
135 MapContainsEntry {
136 field: String,
137 key: Value,
138 value: Value,
139 coercion: CoercionSpec,
140 },
141 TextContains {
142 field: String,
143 value: Value,
144 },
145 TextContainsCi {
146 field: String,
147 value: Value,
148 },
149}
150
151impl Predicate {
152 #[must_use]
153 pub const fn and(preds: Vec<Self>) -> Self {
154 Self::And(preds)
155 }
156
157 #[must_use]
158 pub const fn or(preds: Vec<Self>) -> Self {
159 Self::Or(preds)
160 }
161
162 #[allow(clippy::should_implement_trait)]
163 #[must_use]
164 pub fn not(pred: Self) -> Self {
165 Self::Not(Box::new(pred))
166 }
167
168 #[must_use]
169 pub fn eq(field: String, value: Value) -> Self {
170 Self::Compare(ComparePredicate::eq(field, value))
171 }
172
173 #[must_use]
174 pub fn ne(field: String, value: Value) -> Self {
175 Self::Compare(ComparePredicate::ne(field, value))
176 }
177
178 #[must_use]
179 pub fn lt(field: String, value: Value) -> Self {
180 Self::Compare(ComparePredicate::lt(field, value))
181 }
182
183 #[must_use]
184 pub fn lte(field: String, value: Value) -> Self {
185 Self::Compare(ComparePredicate::lte(field, value))
186 }
187
188 #[must_use]
189 pub fn gt(field: String, value: Value) -> Self {
190 Self::Compare(ComparePredicate::gt(field, value))
191 }
192
193 #[must_use]
194 pub fn gte(field: String, value: Value) -> Self {
195 Self::Compare(ComparePredicate::gte(field, value))
196 }
197
198 #[must_use]
199 pub fn in_(field: String, values: Vec<Value>) -> Self {
200 Self::Compare(ComparePredicate::in_(field, values))
201 }
202
203 #[must_use]
204 pub fn not_in(field: String, values: Vec<Value>) -> Self {
205 Self::Compare(ComparePredicate::not_in(field, values))
206 }
207}
208
209impl BitAnd for Predicate {
210 type Output = Self;
211
212 fn bitand(self, rhs: Self) -> Self::Output {
213 Self::And(vec![self, rhs])
214 }
215}
216
217impl BitAnd for &Predicate {
218 type Output = Predicate;
219
220 fn bitand(self, rhs: Self) -> Self::Output {
221 Predicate::And(vec![self.clone(), rhs.clone()])
222 }
223}
224
225impl BitOr for Predicate {
226 type Output = Self;
227
228 fn bitor(self, rhs: Self) -> Self::Output {
229 Self::Or(vec![self, rhs])
230 }
231}
232
233impl BitOr for &Predicate {
234 type Output = Predicate;
235
236 fn bitor(self, rhs: Self) -> Self::Output {
237 Predicate::Or(vec![self.clone(), rhs.clone()])
238 }
239}