1use qubit_value::{Value, ValueConstructor};
12
13use crate::{
14 Condition, FilterMatchOptions, MetadataFilter, MetadataResult, MetadataSchema,
15 MissingKeyPolicy, NumberComparisonPolicy, metadata_filter::FilterExpr,
16};
17
18#[derive(Debug, Clone, PartialEq, Default)]
24pub struct MetadataFilterBuilder {
25 pub(crate) expr: Option<FilterExpr>,
27 pub(crate) options: FilterMatchOptions,
29}
30
31impl MetadataFilterBuilder {
32 #[inline]
34 #[must_use]
35 pub fn build(self) -> MetadataFilter {
36 MetadataFilter::new(self.expr, self.options)
37 }
38
39 #[inline]
47 pub fn build_checked(self, schema: &MetadataSchema) -> MetadataResult<MetadataFilter> {
48 let filter = self.build();
49 schema.validate_filter(&filter)?;
50 Ok(filter)
51 }
52
53 #[inline]
55 #[must_use]
56 pub fn with_options(mut self, options: FilterMatchOptions) -> Self {
57 self.options = options;
58 self
59 }
60
61 #[inline]
63 #[must_use]
64 pub fn missing_key_policy(mut self, missing_key_policy: MissingKeyPolicy) -> Self {
65 self.options.missing_key_policy = missing_key_policy;
66 self
67 }
68
69 #[inline]
71 #[must_use]
72 pub fn number_comparison_policy(
73 mut self,
74 number_comparison_policy: NumberComparisonPolicy,
75 ) -> Self {
76 self.options.number_comparison_policy = number_comparison_policy;
77 self
78 }
79
80 #[inline]
82 #[must_use]
83 pub fn eq<T>(self, key: &str, value: T) -> Self
84 where
85 Value: ValueConstructor<T>,
86 {
87 self.and_eq(key, value)
88 }
89
90 #[inline]
92 #[must_use]
93 pub fn ne<T>(self, key: &str, value: T) -> Self
94 where
95 Value: ValueConstructor<T>,
96 {
97 self.and_ne(key, value)
98 }
99
100 #[inline]
102 #[must_use]
103 pub fn lt<T>(self, key: &str, value: T) -> Self
104 where
105 Value: ValueConstructor<T>,
106 {
107 self.and_lt(key, value)
108 }
109
110 #[inline]
112 #[must_use]
113 pub fn le<T>(self, key: &str, value: T) -> Self
114 where
115 Value: ValueConstructor<T>,
116 {
117 self.and_le(key, value)
118 }
119
120 #[inline]
122 #[must_use]
123 pub fn gt<T>(self, key: &str, value: T) -> Self
124 where
125 Value: ValueConstructor<T>,
126 {
127 self.and_gt(key, value)
128 }
129
130 #[inline]
132 #[must_use]
133 pub fn ge<T>(self, key: &str, value: T) -> Self
134 where
135 Value: ValueConstructor<T>,
136 {
137 self.and_ge(key, value)
138 }
139
140 #[inline]
142 #[must_use]
143 pub fn in_set<I, T>(self, key: &str, values: I) -> Self
144 where
145 I: IntoIterator<Item = T>,
146 Value: ValueConstructor<T>,
147 {
148 self.and_in_set(key, values)
149 }
150
151 #[inline]
153 #[must_use]
154 pub fn not_in_set<I, T>(self, key: &str, values: I) -> Self
155 where
156 I: IntoIterator<Item = T>,
157 Value: ValueConstructor<T>,
158 {
159 self.and_not_in_set(key, values)
160 }
161
162 #[inline]
164 #[must_use]
165 pub fn exists(self, key: &str) -> Self {
166 self.and_exists(key)
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn not_exists(self, key: &str) -> Self {
173 self.and_not_exists(key)
174 }
175
176 #[inline]
178 #[must_use]
179 pub fn and_eq<T>(self, key: &str, value: T) -> Self
180 where
181 Value: ValueConstructor<T>,
182 {
183 self.and_condition(Condition::Equal {
184 key: key.to_string(),
185 value: to_value(value),
186 })
187 }
188
189 #[inline]
191 #[must_use]
192 pub fn and_ne<T>(self, key: &str, value: T) -> Self
193 where
194 Value: ValueConstructor<T>,
195 {
196 self.and_condition(Condition::NotEqual {
197 key: key.to_string(),
198 value: to_value(value),
199 })
200 }
201
202 #[inline]
204 #[must_use]
205 pub fn and_lt<T>(self, key: &str, value: T) -> Self
206 where
207 Value: ValueConstructor<T>,
208 {
209 self.and_condition(Condition::Less {
210 key: key.to_string(),
211 value: to_value(value),
212 })
213 }
214
215 #[inline]
217 #[must_use]
218 pub fn and_le<T>(self, key: &str, value: T) -> Self
219 where
220 Value: ValueConstructor<T>,
221 {
222 self.and_condition(Condition::LessEqual {
223 key: key.to_string(),
224 value: to_value(value),
225 })
226 }
227
228 #[inline]
230 #[must_use]
231 pub fn and_gt<T>(self, key: &str, value: T) -> Self
232 where
233 Value: ValueConstructor<T>,
234 {
235 self.and_condition(Condition::Greater {
236 key: key.to_string(),
237 value: to_value(value),
238 })
239 }
240
241 #[inline]
243 #[must_use]
244 pub fn and_ge<T>(self, key: &str, value: T) -> Self
245 where
246 Value: ValueConstructor<T>,
247 {
248 self.and_condition(Condition::GreaterEqual {
249 key: key.to_string(),
250 value: to_value(value),
251 })
252 }
253
254 #[inline]
256 #[must_use]
257 pub fn and_in_set<I, T>(self, key: &str, values: I) -> Self
258 where
259 I: IntoIterator<Item = T>,
260 Value: ValueConstructor<T>,
261 {
262 self.and_condition(Condition::In {
263 key: key.to_string(),
264 values: Self::collect_values(values),
265 })
266 }
267
268 #[inline]
270 #[must_use]
271 pub fn and_not_in_set<I, T>(self, key: &str, values: I) -> Self
272 where
273 I: IntoIterator<Item = T>,
274 Value: ValueConstructor<T>,
275 {
276 self.and_condition(Condition::NotIn {
277 key: key.to_string(),
278 values: Self::collect_values(values),
279 })
280 }
281
282 #[inline]
284 #[must_use]
285 pub fn and_exists(self, key: &str) -> Self {
286 self.and_condition(Condition::Exists {
287 key: key.to_string(),
288 })
289 }
290
291 #[inline]
293 #[must_use]
294 pub fn and_not_exists(self, key: &str) -> Self {
295 self.and_condition(Condition::NotExists {
296 key: key.to_string(),
297 })
298 }
299
300 #[inline]
302 #[must_use]
303 pub fn or_eq<T>(self, key: &str, value: T) -> Self
304 where
305 Value: ValueConstructor<T>,
306 {
307 self.or_condition(Condition::Equal {
308 key: key.to_string(),
309 value: to_value(value),
310 })
311 }
312
313 #[inline]
315 #[must_use]
316 pub fn or_ne<T>(self, key: &str, value: T) -> Self
317 where
318 Value: ValueConstructor<T>,
319 {
320 self.or_condition(Condition::NotEqual {
321 key: key.to_string(),
322 value: to_value(value),
323 })
324 }
325
326 #[inline]
328 #[must_use]
329 pub fn or_lt<T>(self, key: &str, value: T) -> Self
330 where
331 Value: ValueConstructor<T>,
332 {
333 self.or_condition(Condition::Less {
334 key: key.to_string(),
335 value: to_value(value),
336 })
337 }
338
339 #[inline]
341 #[must_use]
342 pub fn or_le<T>(self, key: &str, value: T) -> Self
343 where
344 Value: ValueConstructor<T>,
345 {
346 self.or_condition(Condition::LessEqual {
347 key: key.to_string(),
348 value: to_value(value),
349 })
350 }
351
352 #[inline]
354 #[must_use]
355 pub fn or_gt<T>(self, key: &str, value: T) -> Self
356 where
357 Value: ValueConstructor<T>,
358 {
359 self.or_condition(Condition::Greater {
360 key: key.to_string(),
361 value: to_value(value),
362 })
363 }
364
365 #[inline]
367 #[must_use]
368 pub fn or_ge<T>(self, key: &str, value: T) -> Self
369 where
370 Value: ValueConstructor<T>,
371 {
372 self.or_condition(Condition::GreaterEqual {
373 key: key.to_string(),
374 value: to_value(value),
375 })
376 }
377
378 #[inline]
380 #[must_use]
381 pub fn or_in_set<I, T>(self, key: &str, values: I) -> Self
382 where
383 I: IntoIterator<Item = T>,
384 Value: ValueConstructor<T>,
385 {
386 self.or_condition(Condition::In {
387 key: key.to_string(),
388 values: Self::collect_values(values),
389 })
390 }
391
392 #[inline]
394 #[must_use]
395 pub fn or_not_in_set<I, T>(self, key: &str, values: I) -> Self
396 where
397 I: IntoIterator<Item = T>,
398 Value: ValueConstructor<T>,
399 {
400 self.or_condition(Condition::NotIn {
401 key: key.to_string(),
402 values: Self::collect_values(values),
403 })
404 }
405
406 #[inline]
408 #[must_use]
409 pub fn or_exists(self, key: &str) -> Self {
410 self.or_condition(Condition::Exists {
411 key: key.to_string(),
412 })
413 }
414
415 #[inline]
417 #[must_use]
418 pub fn or_not_exists(self, key: &str) -> Self {
419 self.or_condition(Condition::NotExists {
420 key: key.to_string(),
421 })
422 }
423
424 #[inline]
429 #[must_use]
430 pub fn and<F>(self, build: F) -> Self
431 where
432 F: FnOnce(Self) -> Self,
433 {
434 let group = build(Self::default()).expr;
435 self.and_expr(group)
436 }
437
438 #[inline]
443 #[must_use]
444 pub fn or<F>(self, build: F) -> Self
445 where
446 F: FnOnce(Self) -> Self,
447 {
448 let group = build(Self::default()).expr;
449 self.or_expr(group)
450 }
451
452 #[inline]
454 #[must_use]
455 pub fn and_not<F>(self, build: F) -> Self
456 where
457 F: FnOnce(Self) -> Self,
458 {
459 let group = build(Self::default()).expr;
460 self.and_expr(Self::negate_expr(group))
461 }
462
463 #[inline]
465 #[must_use]
466 pub fn or_not<F>(self, build: F) -> Self
467 where
468 F: FnOnce(Self) -> Self,
469 {
470 let group = build(Self::default()).expr;
471 self.or_expr(Self::negate_expr(group))
472 }
473
474 #[allow(clippy::should_implement_trait)]
476 #[inline]
477 #[must_use]
478 pub fn not(mut self) -> Self {
479 self.expr = Self::negate_expr(self.expr);
480 self
481 }
482
483 #[inline]
485 fn collect_values<I, T>(values: I) -> Vec<Value>
486 where
487 I: IntoIterator<Item = T>,
488 Value: ValueConstructor<T>,
489 {
490 values.into_iter().map(to_value).collect()
491 }
492
493 #[inline]
495 fn and_expr(mut self, expr: Option<FilterExpr>) -> Self {
496 self.expr = match (self.expr, expr) {
497 (None, rhs) => rhs,
498 (lhs, None) => lhs,
499 (Some(lhs), Some(rhs)) => Some(FilterExpr::and(lhs, rhs)),
500 };
501 self
502 }
503
504 #[inline]
506 fn or_expr(mut self, expr: Option<FilterExpr>) -> Self {
507 self.expr = match (self.expr, expr) {
508 (None, rhs) => rhs,
509 (lhs, None) => lhs,
510 (Some(lhs), Some(rhs)) => Some(FilterExpr::or(lhs, rhs)),
511 };
512 self
513 }
514
515 #[inline]
517 fn and_condition(self, condition: Condition) -> Self {
518 self.and_expr(Some(FilterExpr::Condition(condition)))
519 }
520
521 #[inline]
523 fn or_condition(self, condition: Condition) -> Self {
524 self.or_expr(Some(FilterExpr::Condition(condition)))
525 }
526
527 #[inline]
529 pub(crate) fn negate_expr(expr: Option<FilterExpr>) -> Option<FilterExpr> {
530 match expr {
531 None => Some(FilterExpr::False),
532 Some(FilterExpr::False) => None,
533 Some(FilterExpr::Not(inner)) => Some(*inner),
534 Some(other) => Some(FilterExpr::Not(Box::new(other))),
535 }
536 }
537}
538
539#[inline]
540fn to_value<T>(value: T) -> Value
541where
542 Value: ValueConstructor<T>,
543{
544 <Value as ValueConstructor<T>>::from_type(value)
545}