entity/ent/query/predicate.rs
1use crate::{Value, ValueLike};
2use derivative::Derivative;
3use std::{
4 collections::{HashMap, HashSet},
5 marker::PhantomData,
6 ops::RangeInclusive,
7 rc::Rc,
8};
9
10/// Represents an untyped predicate that can be used to inspect a value for
11/// some specified condition
12#[derive(Clone, Derivative)]
13#[derivative(Debug, PartialEq)]
14pub enum Predicate {
15 /// Will always be true (not same as equals(true))
16 ///
17 /// ### Examples
18 ///
19 /// ```
20 /// use entity::{Predicate, ValueLike};
21 /// let v = 123.into_value();
22 ///
23 /// let p = Predicate::Always;
24 /// assert_eq!(p.check(&v), true);
25 /// ```
26 Always,
27
28 /// Will always be false (not same as equals(false))
29 ///
30 /// ```
31 /// use entity::{Predicate, ValueLike};
32 /// let v = 123.into_value();
33 ///
34 /// let p = Predicate::Never;
35 /// assert_eq!(p.check(&v), false);
36 /// ```
37 Never,
38
39 /// Will be true if all predicates return true against the checked value
40 ///
41 /// ### Examples
42 ///
43 /// ```
44 /// use entity::{Predicate, Value, ValueLike};
45 /// let v = 123.into_value();
46 ///
47 /// let p = Predicate::And(vec![
48 /// Predicate::GreaterThan(122.into_value()),
49 /// Predicate::LessThan(124.into_value()),
50 /// ]);
51 /// assert_eq!(p.check(&v), true);
52 ///
53 /// let p = Predicate::And(vec![
54 /// Predicate::GreaterThan(122.into_value()),
55 /// Predicate::Never,
56 /// ]);
57 /// assert_eq!(p.check(&v), false);
58 ///
59 /// let p = Predicate::And(vec![
60 /// Predicate::Never,
61 /// Predicate::GreaterThan(122.into_value()),
62 /// ]);
63 /// assert_eq!(p.check(&v), false);
64 ///
65 /// let p = Predicate::And(vec![
66 /// Predicate::Never,
67 /// Predicate::Never,
68 /// ]);
69 /// assert_eq!(p.check(&v), false);
70 /// ```
71 And(Vec<Predicate>),
72
73 /// Will be true if checked value is a collection where any element
74 /// satisifies the predicate
75 ///
76 /// ### Examples
77 ///
78 /// ```
79 /// use entity::{Predicate, Value, ValueLike};
80 /// let v = vec![1, 2, 3].into_value();
81 ///
82 /// let p = Predicate::Any(Box::new(Predicate::Equals(2.into_value())));
83 /// assert_eq!(p.check(&v), true);
84 ///
85 /// let p = Predicate::Any(Box::new(Predicate::Equals(999.into_value())));
86 /// assert_eq!(p.check(&v), false);
87 /// ```
88 ///
89 /// Also supports checking values of a map:
90 ///
91 /// ```
92 /// use entity::{Predicate, Value, ValueLike};
93 /// use std::collections::HashMap;
94 /// let map: HashMap<String, u32> = vec![
95 /// (String::from("a"), 1),
96 /// (String::from("b"), 2),
97 /// (String::from("c"), 3),
98 /// ].into_iter().collect();
99 /// let v = map.into_value();
100 ///
101 /// let p = Predicate::Any(Box::new(Predicate::Equals(2.into_value())));
102 /// assert_eq!(p.check(&v), true);
103 ///
104 /// let p = Predicate::Any(Box::new(Predicate::Equals(999.into_value())));
105 /// assert_eq!(p.check(&v), false);
106 /// ```
107 Any(Box<Predicate>),
108
109 /// Will be true if checked value is a collection that contains the
110 /// specified value
111 ///
112 /// ### Examples
113 ///
114 /// ```
115 /// use entity::{Predicate, Value, ValueLike};
116 /// let v = vec![1, 2, 3].into_value();
117 ///
118 /// let p = Predicate::Contains(2.into_value());
119 /// assert_eq!(p.check(&v), true);
120 ///
121 /// let p = Predicate::Contains(999.into_value());
122 /// assert_eq!(p.check(&v), false);
123 /// ```
124 ///
125 /// Also supports checking values of a map:
126 ///
127 /// ```
128 /// use entity::{Predicate, Value, ValueLike};
129 /// use std::collections::HashMap;
130 /// let map: HashMap<String, u32> = vec![
131 /// (String::from("a"), 1),
132 /// (String::from("b"), 2),
133 /// (String::from("c"), 3),
134 /// ].into_iter().collect();
135 /// let v = map.into_value();
136 ///
137 /// let p = Predicate::Contains(2.into_value());
138 /// assert_eq!(p.check(&v), true);
139 ///
140 /// let p = Predicate::Contains(999.into_value());
141 /// assert_eq!(p.check(&v), false);
142 /// ```
143 Contains(Value),
144
145 /// Will be true if checked value is a collection that contains all of
146 /// the specified values
147 ///
148 /// ### Examples
149 ///
150 /// ```
151 /// use entity::{Predicate, Value, ValueLike};
152 /// let v = vec![1, 2, 3].into_value();
153 ///
154 /// let p = Predicate::ContainsAll(vec![2.into_value(), 3.into_value()]);
155 /// assert_eq!(p.check(&v), true);
156 ///
157 /// let p = Predicate::ContainsAll(vec![2.into_value(), 999.into_value()]);
158 /// assert_eq!(p.check(&v), false);
159 /// ```
160 ///
161 /// Also supports checking values of a map:
162 ///
163 /// ```
164 /// use entity::{Predicate, Value, ValueLike};
165 /// use std::collections::HashMap;
166 /// let map: HashMap<String, u32> = vec![
167 /// (String::from("a"), 1),
168 /// (String::from("b"), 2),
169 /// (String::from("c"), 3),
170 /// ].into_iter().collect();
171 /// let v = map.into_value();
172 ///
173 /// let p = Predicate::ContainsAll(vec![2.into_value(), 3.into_value()]);
174 /// assert_eq!(p.check(&v), true);
175 ///
176 /// let p = Predicate::ContainsAll(vec![2.into_value(), 999.into_value()]);
177 /// assert_eq!(p.check(&v), false);
178 /// ```
179 ContainsAll(Vec<Value>),
180
181 /// Will be true if checked value is a collection that contains any of
182 /// the specified values
183 ///
184 /// ### Examples
185 ///
186 /// ```
187 /// use entity::{Predicate, Value, ValueLike};
188 /// let v = vec![1, 2, 3].into_value();
189 ///
190 /// let p = Predicate::ContainsAny(vec![2.into_value(), 999.into_value()]);
191 /// assert_eq!(p.check(&v), true);
192 ///
193 /// let p = Predicate::ContainsAny(vec![998.into_value(), 999.into_value()]);
194 /// assert_eq!(p.check(&v), false);
195 /// ```
196 ///
197 /// Also supports checking values of a map:
198 ///
199 /// ```
200 /// use entity::{Predicate, Value, ValueLike};
201 /// use std::collections::HashMap;
202 /// let map: HashMap<String, u32> = vec![
203 /// (String::from("a"), 1),
204 /// (String::from("b"), 2),
205 /// (String::from("c"), 3),
206 /// ].into_iter().collect();
207 /// let v = map.into_value();
208 ///
209 /// let p = Predicate::ContainsAny(vec![2.into_value(), 999.into_value()]);
210 /// assert_eq!(p.check(&v), true);
211 ///
212 /// let p = Predicate::ContainsAny(vec![998.into_value(), 999.into_value()]);
213 /// assert_eq!(p.check(&v), false);
214 /// ```
215 ContainsAny(Vec<Value>),
216
217 /// Will be true if checked value equals the specified value
218 ///
219 /// ### Examples
220 ///
221 /// ```
222 /// use entity::{Predicate, Value, ValueLike};
223 /// let v = 123.into_value();
224 ///
225 /// let p = Predicate::Equals(123.into_value());
226 /// assert_eq!(p.check(&v), true);
227 ///
228 /// let p = Predicate::Equals(456.into_value());
229 /// assert_eq!(p.check(&v), false);
230 /// ```
231 Equals(Value),
232
233 /// Will be true if checked value is greater than the specified value
234 ///
235 /// ### Examples
236 ///
237 /// ```
238 /// use entity::{Predicate, Value, ValueLike};
239 /// let v = 123.into_value();
240 ///
241 /// let p = Predicate::GreaterThan(100.into_value());
242 /// assert_eq!(p.check(&v), true);
243 ///
244 /// let p = Predicate::GreaterThan(123.into_value());
245 /// assert_eq!(p.check(&v), false);
246 ///
247 /// let p = Predicate::GreaterThan(456.into_value());
248 /// assert_eq!(p.check(&v), false);
249 /// ```
250 GreaterThan(Value),
251
252 /// Will be true if checked value is greater than or equals the specified
253 /// value
254 ///
255 /// ### Examples
256 ///
257 /// ```
258 /// use entity::{Predicate, Value, ValueLike};
259 /// let v = 123.into_value();
260 ///
261 /// let p = Predicate::GreaterThanOrEquals(100.into_value());
262 /// assert_eq!(p.check(&v), true);
263 ///
264 /// let p = Predicate::GreaterThanOrEquals(123.into_value());
265 /// assert_eq!(p.check(&v), true);
266 ///
267 /// let p = Predicate::GreaterThanOrEquals(456.into_value());
268 /// assert_eq!(p.check(&v), false);
269 /// ```
270 GreaterThanOrEquals(Value),
271
272 /// Will be true if checked value is a map that contains the specified key
273 ///
274 /// ### Examples
275 ///
276 /// ```
277 /// use entity::{Predicate, Value, ValueLike};
278 /// use std::collections::HashMap;
279 /// let map: HashMap<String, u32> = vec![
280 /// (String::from("a"), 1),
281 /// (String::from("b"), 2),
282 /// (String::from("c"), 3),
283 /// ].into_iter().collect();
284 /// let v = map.into_value();
285 ///
286 /// let p = Predicate::HasKey(String::from("a"));
287 /// assert_eq!(p.check(&v), true);
288 ///
289 /// let p = Predicate::HasKey(String::from("d"));
290 /// assert_eq!(p.check(&v), false);
291 /// ```
292 HasKey(String),
293
294 /// Will be true if checked value is a map that contains the specified key
295 /// and corresponding value meets the specified predicate
296 ///
297 /// ### Examples
298 ///
299 /// ```
300 /// use entity::{Predicate, Value, ValueLike};
301 /// use std::collections::HashMap;
302 /// let map: HashMap<String, u32> = vec![
303 /// (String::from("a"), 1),
304 /// (String::from("b"), 2),
305 /// (String::from("c"), 3),
306 /// ].into_iter().collect();
307 /// let v = map.into_value();
308 ///
309 /// let p = Predicate::HasKeyWhereValue(
310 /// String::from("a"),
311 /// Box::new(Predicate::Equals(1.into_value())),
312 /// );
313 /// assert_eq!(p.check(&v), true);
314 ///
315 /// let p = Predicate::HasKeyWhereValue(
316 /// String::from("b"),
317 /// Box::new(Predicate::Equals(1.into_value())),
318 /// );
319 /// assert_eq!(p.check(&v), false);
320 ///
321 /// let p = Predicate::HasKeyWhereValue(
322 /// String::from("d"),
323 /// Box::new(Predicate::Equals(1.into_value())),
324 /// );
325 /// assert_eq!(p.check(&v), false);
326 /// ```
327 HasKeyWhereValue(String, Box<Predicate>),
328
329 /// Will be true if checked value is within the specified range
330 ///
331 /// ### Examples
332 ///
333 /// ```
334 /// use entity::{Predicate, Value, ValueLike};
335 /// let v = 123.into_value();
336 ///
337 /// let p = Predicate::InRange(100.into_value()..=200.into_value());
338 /// assert_eq!(p.check(&v), true);
339 ///
340 /// let p = Predicate::InRange(200.into_value()..=300.into_value());
341 /// assert_eq!(p.check(&v), false);
342 /// ```
343 InRange(RangeInclusive<Value>),
344
345 /// Will be true if checked value is within the specified set
346 ///
347 /// ### Examples
348 ///
349 /// ```
350 /// use entity::{Predicate, Value, ValueLike};
351 /// let v = 123.into_value();
352 ///
353 /// let p = Predicate::InSet(vec![
354 /// 122.into_value(),
355 /// 123.into_value(),
356 /// 124.into_value(),
357 /// ].into_iter().collect());
358 /// assert_eq!(p.check(&v), true);
359 ///
360 /// let p = Predicate::InSet(vec![
361 /// 222.into_value(),
362 /// 223.into_value(),
363 /// 224.into_value(),
364 /// ].into_iter().collect());
365 /// assert_eq!(p.check(&v), false);
366 /// ```
367 InSet(HashSet<Value>),
368
369 /// Will be true if checked value optional and is none
370 ///
371 /// ### Examples
372 ///
373 /// ```
374 /// use entity::{Predicate, Value, ValueLike};
375 ///
376 /// let v = None::<u8>.into_value();
377 /// let p = Predicate::IsNone;
378 /// assert_eq!(p.check(&v), true);
379 ///
380 /// let v = Some(123).into_value();
381 /// let p = Predicate::IsNone;
382 /// assert_eq!(p.check(&v), false);
383 /// ```
384 IsNone,
385
386 /// Will be true if checked value passes the lambda function by having
387 /// it return true
388 ///
389 /// ### Examples
390 ///
391 /// ```
392 /// use entity::{Predicate, Value, ValueLike};
393 /// use std::rc::Rc;
394 /// let v = 123.into_value();
395 ///
396 /// let p = Predicate::Lambda(Rc::new(|v| v == &123.into_value()));
397 /// assert_eq!(p.check(&v), true);
398 ///
399 /// let p = Predicate::Lambda(Rc::new(|v| v == &456.into_value()));
400 /// assert_eq!(p.check(&v), false);
401 /// ```
402 Lambda(#[derivative(Debug = "ignore", PartialEq = "ignore")] Rc<dyn Fn(&Value) -> bool>),
403
404 /// Will be true if checked value is less than the specified value
405 ///
406 /// ### Examples
407 ///
408 /// ```
409 /// use entity::{Predicate, Value, ValueLike};
410 /// let v = 123.into_value();
411 ///
412 /// let p = Predicate::LessThan(200.into_value());
413 /// assert_eq!(p.check(&v), true);
414 ///
415 /// let p = Predicate::LessThan(123.into_value());
416 /// assert_eq!(p.check(&v), false);
417 ///
418 /// let p = Predicate::LessThan(100.into_value());
419 /// assert_eq!(p.check(&v), false);
420 /// ```
421 LessThan(Value),
422
423 /// Will be true if checked value is less than or equals the specified
424 /// value
425 ///
426 /// ### Examples
427 ///
428 /// ```
429 /// use entity::{Predicate, Value, ValueLike};
430 /// let v = 123.into_value();
431 ///
432 /// let p = Predicate::LessThanOrEquals(200.into_value());
433 /// assert_eq!(p.check(&v), true);
434 ///
435 /// let p = Predicate::LessThanOrEquals(123.into_value());
436 /// assert_eq!(p.check(&v), true);
437 ///
438 /// let p = Predicate::LessThanOrEquals(100.into_value());
439 /// assert_eq!(p.check(&v), false);
440 /// ```
441 LessThanOrEquals(Value),
442
443 /// Will be true if checked value is does not pass the specified predicate
444 ///
445 /// ### Examples
446 ///
447 /// ```
448 /// use entity::{Predicate, Value, ValueLike};
449 /// let v = 123.into_value();
450 ///
451 /// let p = Predicate::Not(Box::new(Predicate::Equals(200.into_value())));
452 /// assert_eq!(p.check(&v), true);
453 ///
454 /// let p = Predicate::Not(Box::new(Predicate::Equals(123.into_value())));
455 /// assert_eq!(p.check(&v), false);
456 /// ```
457 Not(Box<Predicate>),
458
459 /// Will be true if checked value does not equal the specified value
460 ///
461 /// ### Examples
462 ///
463 /// ```
464 /// use entity::{Predicate, Value, ValueLike};
465 /// let v = 123.into_value();
466 ///
467 /// let p = Predicate::NotEquals(456.into_value());
468 /// assert_eq!(p.check(&v), true);
469 ///
470 /// let p = Predicate::NotEquals(123.into_value());
471 /// assert_eq!(p.check(&v), false);
472 /// ```
473 NotEquals(Value),
474
475 /// Will be true if checked value is not within the specified range
476 ///
477 /// ### Examples
478 ///
479 /// ```
480 /// use entity::{Predicate, Value, ValueLike};
481 /// let v = 123.into_value();
482 ///
483 /// let p = Predicate::NotInRange(200.into_value()..=300.into_value());
484 /// assert_eq!(p.check(&v), true);
485 ///
486 /// let p = Predicate::NotInRange(100.into_value()..=200.into_value());
487 /// assert_eq!(p.check(&v), false);
488 /// ```
489 NotInRange(RangeInclusive<Value>),
490
491 /// Will be true if checked value is not within the specified set
492 ///
493 /// ### Examples
494 ///
495 /// ```
496 /// use entity::{Predicate, Value, ValueLike};
497 /// let v = 123.into_value();
498 ///
499 /// let p = Predicate::NotInSet(vec![
500 /// 222.into_value(),
501 /// 223.into_value(),
502 /// 224.into_value(),
503 /// ].into_iter().collect());
504 /// assert_eq!(p.check(&v), true);
505 ///
506 /// let p = Predicate::NotInSet(vec![
507 /// 122.into_value(),
508 /// 123.into_value(),
509 /// 124.into_value(),
510 /// ].into_iter().collect());
511 /// assert_eq!(p.check(&v), false);
512 /// ```
513 NotInSet(HashSet<Value>),
514
515 /// Will be true if checked value is not none and passes the specified
516 /// predicate
517 ///
518 /// ### Examples
519 ///
520 /// ```
521 /// use entity::{Predicate, Value, ValueLike};
522 ///
523 /// let v = Some(123).into_value();
524 /// let p = Predicate::NotNoneAnd(Box::new(Predicate::Equals(123.into_value())));
525 /// assert_eq!(p.check(&v), true);
526 ///
527 /// let v = 123.into_value();
528 /// let p = Predicate::NotNoneAnd(Box::new(Predicate::Equals(123.into_value())));
529 /// assert_eq!(p.check(&v), true);
530 ///
531 /// let v = Some(456).into_value();
532 /// let p = Predicate::NotNoneAnd(Box::new(Predicate::Equals(123.into_value())));
533 /// assert_eq!(p.check(&v), false);
534 ///
535 /// let v = 456.into_value();
536 /// let p = Predicate::NotNoneAnd(Box::new(Predicate::Equals(123.into_value())));
537 /// assert_eq!(p.check(&v), false);
538 ///
539 /// let v = None::<u8>.into_value();
540 /// let p = Predicate::NotNoneAnd(Box::new(Predicate::Equals(123.into_value())));
541 /// assert_eq!(p.check(&v), false);
542 /// ```
543 NotNoneAnd(Box<Predicate>),
544
545 /// Will be true if checked value is either none or passes the specified
546 /// predicate
547 ///
548 /// ### Examples
549 ///
550 /// ```
551 /// use entity::{Predicate, Value, ValueLike};
552 ///
553 /// let v = None::<u8>.into_value();
554 /// let p = Predicate::NoneOr(Box::new(Predicate::Equals(123.into_value())));
555 /// assert_eq!(p.check(&v), true);
556 ///
557 /// let v = Some(123).into_value();
558 /// let p = Predicate::NoneOr(Box::new(Predicate::Equals(123.into_value())));
559 /// assert_eq!(p.check(&v), true);
560 ///
561 /// let v = 123.into_value();
562 /// let p = Predicate::NoneOr(Box::new(Predicate::Equals(123.into_value())));
563 /// assert_eq!(p.check(&v), true);
564 ///
565 /// let v = Some(456).into_value();
566 /// let p = Predicate::NoneOr(Box::new(Predicate::Equals(123.into_value())));
567 /// assert_eq!(p.check(&v), false);
568 /// ```
569 NoneOr(Box<Predicate>),
570
571 /// Will be true if any predicate returns true against the checked value
572 ///
573 /// ### Examples
574 ///
575 /// ```
576 /// use entity::{Predicate, Value, ValueLike};
577 /// let v = 123.into_value();
578 ///
579 /// let p = Predicate::Or(vec![
580 /// Predicate::GreaterThan(122.into_value()),
581 /// Predicate::LessThan(124.into_value()),
582 /// ]);
583 /// assert_eq!(p.check(&v), true);
584 ///
585 /// let p = Predicate::Or(vec![
586 /// Predicate::Equals(123.into_value()),
587 /// Predicate::Never,
588 /// ]);
589 /// assert_eq!(p.check(&v), true);
590 ///
591 /// let p = Predicate::Or(vec![
592 /// Predicate::Never,
593 /// Predicate::Equals(123.into_value()),
594 /// ]);
595 /// assert_eq!(p.check(&v), true);
596 ///
597 /// let p = Predicate::Or(vec![
598 /// Predicate::Never,
599 /// Predicate::Never,
600 /// ]);
601 /// assert_eq!(p.check(&v), false);
602 /// ```
603 Or(Vec<Predicate>),
604
605 /// Will be true if checked value is text that is a substring if the
606 /// specified string (case sensitive)
607 ///
608 /// ### Examples
609 ///
610 /// ```
611 /// use entity::{Predicate, Value};
612 /// let v = Value::from("substring");
613 ///
614 /// let p = Predicate::TextContainedIn(String::from("my substring of text"));
615 /// assert_eq!(p.check(&v), true);
616 ///
617 /// let p = Predicate::TextContainedIn(String::from("my string of text"));
618 /// assert_eq!(p.check(&v), false);
619 /// ```
620 TextContainedIn(String),
621
622 /// Will be true if checked value is text that is a substring if the
623 /// specified string (case insensitive)
624 ///
625 /// ### Examples
626 ///
627 /// ```
628 /// use entity::{Predicate, Value};
629 /// let v = Value::from("substring");
630 ///
631 /// let p = Predicate::TextContainedInCaseInsensitive(String::from("MY SUBSTRING OF TEXT"));
632 /// assert_eq!(p.check(&v), true);
633 ///
634 /// let p = Predicate::TextContainedInCaseInsensitive(String::from("my string of text"));
635 /// assert_eq!(p.check(&v), false);
636 /// ```
637 TextContainedInCaseInsensitive(String),
638
639 /// Will be true if checked value is text that contains all of the
640 /// specified strings as substrings (case sensitive)
641 ///
642 /// ### Examples
643 ///
644 /// ```
645 /// use entity::{Predicate, Value};
646 /// let v = Value::from("my text that is compared");
647 ///
648 /// let p = Predicate::TextContainsAll(vec![
649 /// String::from("my"),
650 /// String::from("text"),
651 /// String::from("compared"),
652 /// ]);
653 /// assert_eq!(p.check(&v), true);
654 ///
655 /// let p = Predicate::TextContainsAll(vec![
656 /// String::from("my"),
657 /// String::from("other"),
658 /// String::from("compared"),
659 /// ]);
660 /// assert_eq!(p.check(&v), false);
661 /// ```
662 TextContainsAll(Vec<String>),
663
664 /// Will be true if checked value is text that contains all of the
665 /// specified strings as substrings (case insensitive)
666 ///
667 /// ### Examples
668 ///
669 /// ```
670 /// use entity::{Predicate, Value};
671 /// let v = Value::from("my text that is compared");
672 ///
673 /// let p = Predicate::TextContainsAllCaseInsensitive(vec![
674 /// String::from("MY"),
675 /// String::from("TEXT"),
676 /// String::from("COMPARED"),
677 /// ]);
678 /// assert_eq!(p.check(&v), true);
679 ///
680 /// let p = Predicate::TextContainsAllCaseInsensitive(vec![
681 /// String::from("my"),
682 /// String::from("other"),
683 /// String::from("compared"),
684 /// ]);
685 /// assert_eq!(p.check(&v), false);
686 /// ```
687 TextContainsAllCaseInsensitive(Vec<String>),
688
689 /// Will be true if checked value is text that contains any of the
690 /// specified strings as substrings (case sensitive)
691 ///
692 /// ### Examples
693 ///
694 /// ```
695 /// use entity::{Predicate, Value};
696 /// let v = Value::from("my text that is compared");
697 ///
698 /// let p = Predicate::TextContainsAny(vec![
699 /// String::from("something"),
700 /// String::from("text"),
701 /// String::from("other"),
702 /// ]);
703 /// assert_eq!(p.check(&v), true);
704 ///
705 /// let p = Predicate::TextContainsAny(vec![
706 /// String::from("something"),
707 /// String::from("not"),
708 /// String::from("other"),
709 /// ]);
710 /// assert_eq!(p.check(&v), false);
711 /// ```
712 TextContainsAny(Vec<String>),
713
714 /// Will be true if checked value is text that contains any of the
715 /// specified strings as substrings (case insensitive)
716 ///
717 /// ### Examples
718 ///
719 /// ```
720 /// use entity::{Predicate, Value};
721 /// let v = Value::from("my text that is compared");
722 ///
723 /// let p = Predicate::TextContainsAnyCaseInsensitive(vec![
724 /// String::from("SOMETHING"),
725 /// String::from("TEXT"),
726 /// String::from("OTHER"),
727 /// ]);
728 /// assert_eq!(p.check(&v), true);
729 ///
730 /// let p = Predicate::TextContainsAnyCaseInsensitive(vec![
731 /// String::from("something"),
732 /// String::from("not"),
733 /// String::from("other"),
734 /// ]);
735 /// assert_eq!(p.check(&v), false);
736 /// ```
737 TextContainsAnyCaseInsensitive(Vec<String>),
738
739 /// Will be true if checked value is text that ends with the specified string
740 /// (case sensitive)
741 ///
742 /// ### Examples
743 ///
744 /// ```
745 /// use entity::{Predicate, Value};
746 /// let v = Value::from("some text");
747 ///
748 /// let p = Predicate::TextEndsWith(String::from("text"));
749 /// assert_eq!(p.check(&v), true);
750 ///
751 /// let p = Predicate::TextEndsWith(String::from("TEXT"));
752 /// assert_eq!(p.check(&v), false);
753 /// ```
754 TextEndsWith(String),
755
756 /// Will be true if checked value is text that ends with the specified string
757 /// (case insensitive)
758 ///
759 /// ### Examples
760 ///
761 /// ```
762 /// use entity::{Predicate, Value};
763 /// let v = Value::from("some text");
764 ///
765 /// let p = Predicate::TextEndsWithCaseInsensitive(String::from("TEXT"));
766 /// assert_eq!(p.check(&v), true);
767 ///
768 /// let p = Predicate::TextEndsWithCaseInsensitive(String::from("some"));
769 /// assert_eq!(p.check(&v), false);
770 /// ```
771 TextEndsWithCaseInsensitive(String),
772
773 /// Will be true if checked value is text that ends with any of the
774 /// specified strings (case sensitive)
775 ///
776 /// ### Examples
777 ///
778 /// ```
779 /// use entity::{Predicate, Value};
780 /// let v = Value::from("my text that is compared");
781 ///
782 /// let p = Predicate::TextEndsWithAny(vec![
783 /// String::from("something"),
784 /// String::from("compared"),
785 /// String::from("other"),
786 /// ]);
787 /// assert_eq!(p.check(&v), true);
788 ///
789 /// let p = Predicate::TextEndsWithAny(vec![
790 /// String::from("something"),
791 /// String::from("COMPARED"),
792 /// String::from("other"),
793 /// ]);
794 /// assert_eq!(p.check(&v), false);
795 /// ```
796 TextEndsWithAny(Vec<String>),
797
798 /// Will be true if checked value is text that ends with any of the
799 /// specified strings (case insensitive)
800 ///
801 /// ### Examples
802 ///
803 /// ```
804 /// use entity::{Predicate, Value};
805 /// let v = Value::from("my text that is compared");
806 ///
807 /// let p = Predicate::TextEndsWithAnyCaseInsensitive(vec![
808 /// String::from("SOMETHING"),
809 /// String::from("COMPARED"),
810 /// String::from("OTHER"),
811 /// ]);
812 /// assert_eq!(p.check(&v), true);
813 ///
814 /// let p = Predicate::TextEndsWithAnyCaseInsensitive(vec![
815 /// String::from("something"),
816 /// String::from("text"),
817 /// String::from("other"),
818 /// ]);
819 /// assert_eq!(p.check(&v), false);
820 /// ```
821 TextEndsWithAnyCaseInsensitive(Vec<String>),
822
823 /// Will be true if checked value is text that equals the specified string
824 /// (case insensitive)
825 ///
826 /// ### Examples
827 ///
828 /// ```
829 /// use entity::{Predicate, Value};
830 /// let v = Value::from("some text");
831 ///
832 /// let p = Predicate::TextEqualsCaseInsensitive(String::from("SOME TEXT"));
833 /// assert_eq!(p.check(&v), true);
834 ///
835 /// let p = Predicate::TextEqualsCaseInsensitive(String::from("other text"));
836 /// assert_eq!(p.check(&v), false);
837 /// ```
838 TextEqualsCaseInsensitive(String),
839
840 /// Will be true if checked value is text that does not equal the specified
841 /// string (case insensitive); or if any other type than text
842 ///
843 /// ### Examples
844 ///
845 /// ```
846 /// use entity::{Predicate, Value};
847 /// let v = Value::from("some text");
848 ///
849 /// let p = Predicate::TextNotEqualsCaseInsensitive(String::from("other text"));
850 /// assert_eq!(p.check(&v), true);
851 ///
852 /// let p = Predicate::TextNotEqualsCaseInsensitive(String::from("SOME TEXT"));
853 /// assert_eq!(p.check(&v), false);
854 /// ```
855 TextNotEqualsCaseInsensitive(String),
856
857 /// Will be true if checked value is text that is found within the
858 /// specified set of strings
859 ///
860 /// ### Examples
861 ///
862 /// ```
863 /// use entity::{Predicate, Value};
864 /// let v = Value::from("some text");
865 ///
866 /// let p = Predicate::TextInSetCaseInsensitive(vec![
867 /// String::from("SOME"),
868 /// String::from("SOME TEXT"),
869 /// String::from("TEXT"),
870 /// ].into_iter().collect());
871 /// assert_eq!(p.check(&v), true);
872 ///
873 /// let p = Predicate::TextInSetCaseInsensitive(vec![
874 /// String::from("OTHER"),
875 /// String::from("OTHER TEXT"),
876 /// String::from("TEXT"),
877 /// ].into_iter().collect());
878 /// assert_eq!(p.check(&v), false);
879 /// ```
880 TextInSetCaseInsensitive(HashSet<String>),
881
882 /// Will be true if checked value is text that starts with the specified string
883 /// (case sensitive)
884 ///
885 /// ### Examples
886 ///
887 /// ```
888 /// use entity::{Predicate, Value};
889 /// let v = Value::from("some text");
890 ///
891 /// let p = Predicate::TextStartsWith(String::from("some"));
892 /// assert_eq!(p.check(&v), true);
893 ///
894 /// let p = Predicate::TextStartsWith(String::from("SOME"));
895 /// assert_eq!(p.check(&v), false);
896 /// ```
897 TextStartsWith(String),
898
899 /// Will be true if checked value is text that starts with the specified string
900 /// (case insensitive)
901 ///
902 /// ### Examples
903 ///
904 /// ```
905 /// use entity::{Predicate, Value};
906 /// let v = Value::from("some text");
907 ///
908 /// let p = Predicate::TextStartsWithCaseInsensitive(String::from("SOME"));
909 /// assert_eq!(p.check(&v), true);
910 ///
911 /// let p = Predicate::TextStartsWithCaseInsensitive(String::from("text"));
912 /// assert_eq!(p.check(&v), false);
913 /// ```
914 TextStartsWithCaseInsensitive(String),
915
916 /// Will be true if checked value is text that starts with any of the
917 /// specified strings as substrings (case sensitive)
918 ///
919 /// ### Examples
920 ///
921 /// ```
922 /// use entity::{Predicate, Value};
923 /// let v = Value::from("my text that is compared");
924 ///
925 /// let p = Predicate::TextStartsWithAny(vec![
926 /// String::from("something"),
927 /// String::from("my"),
928 /// String::from("other"),
929 /// ]);
930 /// assert_eq!(p.check(&v), true);
931 ///
932 /// let p = Predicate::TextStartsWithAny(vec![
933 /// String::from("something"),
934 /// String::from("MY"),
935 /// String::from("other"),
936 /// ]);
937 /// assert_eq!(p.check(&v), false);
938 /// ```
939 TextStartsWithAny(Vec<String>),
940
941 /// Will be true if checked value is text that starts with any of the
942 /// specified strings as substrings (case insensitive)
943 ///
944 /// ### Examples
945 ///
946 /// ```
947 /// use entity::{Predicate, Value};
948 /// let v = Value::from("my text that is compared");
949 ///
950 /// let p = Predicate::TextStartsWithAnyCaseInsensitive(vec![
951 /// String::from("SOMETHING"),
952 /// String::from("MY"),
953 /// String::from("OTHER"),
954 /// ]);
955 /// assert_eq!(p.check(&v), true);
956 ///
957 /// let p = Predicate::TextStartsWithAnyCaseInsensitive(vec![
958 /// String::from("something"),
959 /// String::from("not"),
960 /// String::from("other"),
961 /// ]);
962 /// assert_eq!(p.check(&v), false);
963 /// ```
964 TextStartsWithAnyCaseInsensitive(Vec<String>),
965
966 /// Will be true if only one predicate returns true against the checked value
967 ///
968 /// ### Examples
969 ///
970 /// ```
971 /// use entity::{Predicate, Value, ValueLike};
972 /// let v = 123.into_value();
973 ///
974 /// let p = Predicate::Xor(vec![
975 /// Predicate::Never,
976 /// Predicate::Equals(123.into_value()),
977 /// ]);
978 /// assert_eq!(p.check(&v), true);
979 ///
980 /// let p = Predicate::Xor(vec![
981 /// Predicate::Equals(123.into_value()),
982 /// Predicate::Never,
983 /// ]);
984 /// assert_eq!(p.check(&v), true);
985 ///
986 /// let p = Predicate::Xor(vec![
987 /// Predicate::GreaterThan(122.into_value()),
988 /// Predicate::LessThan(124.into_value()),
989 /// ]);
990 /// assert_eq!(p.check(&v), false);
991 ///
992 /// let p = Predicate::Xor(vec![
993 /// Predicate::Never,
994 /// Predicate::Never,
995 /// ]);
996 /// assert_eq!(p.check(&v), false);
997 /// ```
998 Xor(Vec<Predicate>),
999}
1000
1001impl Predicate {
1002 /// Checks if the predicate is satisfied by the given value
1003 pub fn check(&self, value: &Value) -> bool {
1004 match self {
1005 Self::Always => true,
1006 Self::Never => false,
1007 Self::And(list) => list.iter().all(|p| p.check(value)),
1008 Self::Any(p) => match value {
1009 Value::List(x) => x.iter().any(|v| p.check(v)),
1010 Value::Map(x) => x.iter().any(|(_, v)| p.check(v)),
1011 _ => false,
1012 },
1013 Self::Contains(v) => match value {
1014 Value::List(x) => x.contains(v),
1015 Value::Map(x) => x.iter().any(|(_, vv)| v == vv),
1016 _ => false,
1017 },
1018 Self::ContainsAll(list) => match value {
1019 Value::List(x) => list.iter().all(|v| x.contains(v)),
1020 Value::Map(x) => list.iter().all(|v| x.iter().any(|(_, vv)| v == vv)),
1021 _ => false,
1022 },
1023 Self::ContainsAny(list) => match value {
1024 Value::List(x) => list.iter().any(|v| x.contains(v)),
1025 Value::Map(x) => list.iter().any(|v| x.iter().any(|(_, vv)| v == vv)),
1026 _ => false,
1027 },
1028 Self::TextEndsWith(s) => match value {
1029 Value::Text(t) => t.ends_with(s),
1030 _ => false,
1031 },
1032 Self::TextEndsWithCaseInsensitive(s) => match value {
1033 Value::Text(t) => t.to_lowercase().ends_with(&s.to_lowercase()),
1034 _ => false,
1035 },
1036 Self::Equals(v) => value == v,
1037 Self::TextEqualsCaseInsensitive(s) => match value {
1038 Value::Text(t) => t.to_lowercase() == s.to_lowercase(),
1039 _ => false,
1040 },
1041 Self::GreaterThan(v) => value > v,
1042 Self::GreaterThanOrEquals(v) => value >= v,
1043 Self::HasKey(k) => match value {
1044 Value::Map(x) => x.contains_key(k),
1045 _ => false,
1046 },
1047 Self::HasKeyWhereValue(k, p) => match value {
1048 Value::Map(x) => x.get(k).map(|v| p.check(v)).unwrap_or_default(),
1049 _ => false,
1050 },
1051 Self::InRange(r) => value >= r.start() && value <= r.end(),
1052 Self::InSet(v) => v.contains(value),
1053 Self::TextInSetCaseInsensitive(list) => match value {
1054 Value::Text(t) => list.iter().any(|s| t.to_lowercase() == s.to_lowercase()),
1055 _ => false,
1056 },
1057 Self::IsNone => matches!(value, Value::Optional(None)),
1058 Self::Lambda(f) => f(value),
1059 Self::LessThan(v) => value < v,
1060 Self::LessThanOrEquals(v) => value <= v,
1061 Self::Not(p) => !p.check(value),
1062 Self::NotEquals(v) => value != v,
1063 Self::TextNotEqualsCaseInsensitive(s) => match value {
1064 Value::Text(t) => t.to_lowercase() != s.to_lowercase(),
1065 _ => false,
1066 },
1067 Self::NotInRange(r) => value < r.start() || value > r.end(),
1068 Self::NotInSet(list) => !list.contains(value),
1069 Self::NotNoneAnd(p) => match value {
1070 Value::Optional(Some(v)) => p.check(v),
1071 v => p.check(v),
1072 },
1073 Self::NoneOr(p) => match value {
1074 Value::Optional(None) => true,
1075 v => p.check(v),
1076 },
1077 Self::Or(list) => list.iter().any(|p| p.check(value)),
1078 Self::TextStartsWith(s) => match value {
1079 Value::Text(t) => t.starts_with(s),
1080 _ => false,
1081 },
1082 Self::TextStartsWithCaseInsensitive(s) => match value {
1083 Value::Text(t) => t.to_lowercase().starts_with(&s.to_lowercase()),
1084 _ => false,
1085 },
1086 Self::TextContainedIn(s) => match value {
1087 Value::Text(t) => s.contains(t),
1088 _ => false,
1089 },
1090 Self::TextContainedInCaseInsensitive(s) => match value {
1091 Value::Text(t) => s.to_lowercase().contains(&t.to_lowercase()),
1092 _ => false,
1093 },
1094 Self::TextContainsAll(list) => match value {
1095 Value::Text(t) => list.iter().all(|s| t.contains(s)),
1096 _ => false,
1097 },
1098 Self::TextContainsAllCaseInsensitive(list) => match value {
1099 Value::Text(t) => list
1100 .iter()
1101 .all(|s| t.to_lowercase().contains(&s.to_lowercase())),
1102 _ => false,
1103 },
1104 Self::TextContainsAny(list) => match value {
1105 Value::Text(t) => list.iter().any(|s| t.contains(s)),
1106 _ => false,
1107 },
1108 Self::TextContainsAnyCaseInsensitive(list) => match value {
1109 Value::Text(t) => list
1110 .iter()
1111 .any(|s| t.to_lowercase().contains(&s.to_lowercase())),
1112 _ => false,
1113 },
1114 Self::TextEndsWithAny(list) => match value {
1115 Value::Text(t) => list.iter().any(|s| t.ends_with(s)),
1116 _ => false,
1117 },
1118 Self::TextEndsWithAnyCaseInsensitive(list) => match value {
1119 Value::Text(t) => list
1120 .iter()
1121 .any(|s| t.to_lowercase().ends_with(&s.to_lowercase())),
1122 _ => false,
1123 },
1124 Self::TextStartsWithAny(list) => match value {
1125 Value::Text(t) => list.iter().any(|s| t.starts_with(s)),
1126 _ => false,
1127 },
1128 Self::TextStartsWithAnyCaseInsensitive(list) => match value {
1129 Value::Text(t) => list
1130 .iter()
1131 .any(|s| t.to_lowercase().starts_with(&s.to_lowercase())),
1132 _ => false,
1133 },
1134 Self::Xor(list) => {
1135 list.iter()
1136 .fold(0, |acc, p| if p.check(value) { acc + 1 } else { acc })
1137 == 1
1138 }
1139 }
1140 }
1141
1142 /// Creates a new predicate for [`Predicate::Always`]
1143 ///
1144 /// ### Examples
1145 ///
1146 /// ```
1147 /// use entity::{Predicate as P, Value as V};
1148 ///
1149 /// let p = P::always();
1150 /// assert_eq!(p.check(&V::from(1)), true);
1151 /// ```
1152 #[inline]
1153 pub fn always() -> Self {
1154 Self::Always
1155 }
1156
1157 /// Creates a new predicate for [`Predicate::Never`]
1158 ///
1159 /// ### Examples
1160 ///
1161 /// ```
1162 /// use entity::{Predicate as P, Value as V};
1163 ///
1164 /// let p = P::never();
1165 /// assert_eq!(p.check(&V::from(1)), false);
1166 /// ```
1167 #[inline]
1168 pub fn never() -> Self {
1169 Self::Never
1170 }
1171
1172 /// Creates a new predicate for [`Predicate::Lambda`]
1173 ///
1174 /// ### Examples
1175 ///
1176 /// ```
1177 /// use entity::{Predicate as P, Value as V};
1178 ///
1179 /// let p = P::lambda(|v| v > &V::from(3));
1180 /// assert_eq!(p.check(&V::from(4)), true);
1181 /// assert_eq!(p.check(&V::from(1)), false);
1182 /// ```
1183 pub fn lambda<F: 'static + Fn(&Value) -> bool>(f: F) -> Self {
1184 Self::Lambda(Rc::new(f))
1185 }
1186
1187 /// Creates a new predicate for [`Predicate::And`]
1188 ///
1189 /// ### Examples
1190 ///
1191 /// ```
1192 /// use entity::{Predicate as P, Value as V};
1193 ///
1194 /// let p = P::and(vec![
1195 /// P::greater_than(1),
1196 /// P::less_than(3),
1197 /// ]);
1198 /// assert_eq!(p.check(&V::from(2)), true);
1199 /// assert_eq!(p.check(&V::from(1)), false);
1200 /// ```
1201 pub fn and<P: Into<Predicate>, I: IntoIterator<Item = P>>(i: I) -> Self {
1202 Self::And(i.into_iter().map(|p| p.into()).collect())
1203 }
1204
1205 /// Creates a new predicate for [`Predicate::Not`]
1206 ///
1207 /// ### Examples
1208 ///
1209 /// ```
1210 /// use entity::{Predicate as P, Value as V};
1211 ///
1212 /// let p = P::not(P::greater_than(1));
1213 /// assert_eq!(p.check(&V::from(1)), true);
1214 /// assert_eq!(p.check(&V::from(2)), false);
1215 /// ```
1216 pub fn not<P: Into<Predicate>>(p: P) -> Self {
1217 Self::Not(Box::new(p.into()))
1218 }
1219
1220 /// Creates a new predicate for [`Predicate::Or`]
1221 ///
1222 /// ### Examples
1223 ///
1224 /// ```
1225 /// use entity::{Predicate as P, Value as V};
1226 ///
1227 /// let p = P::or(vec![P::greater_than(1), P::equals(1)]);
1228 /// assert_eq!(p.check(&V::from(1)), true);
1229 /// assert_eq!(p.check(&V::from(2)), true);
1230 /// assert_eq!(p.check(&V::from(0)), false);
1231 /// ```
1232 pub fn or<P: Into<Predicate>, I: IntoIterator<Item = P>>(i: I) -> Self {
1233 Self::Or(i.into_iter().map(|p| p.into()).collect())
1234 }
1235
1236 /// Creates a new predicate for [`Predicate::Xor`]
1237 ///
1238 /// ### Examples
1239 ///
1240 /// ```
1241 /// use entity::{Predicate as P, Value as V};
1242 ///
1243 /// let p = P::xor(vec![P::greater_than(1), P::greater_than(2)]);
1244 /// assert_eq!(p.check(&V::from(2)), true);
1245 /// assert_eq!(p.check(&V::from(3)), false);
1246 /// assert_eq!(p.check(&V::from(1)), false);
1247 /// ```
1248 pub fn xor<P: Into<Predicate>, I: IntoIterator<Item = P>>(i: I) -> Self {
1249 Self::Xor(i.into_iter().map(|p| p.into()).collect())
1250 }
1251
1252 /// Creates a new predicate for [`Predicate::Any`]
1253 ///
1254 /// ### Examples
1255 ///
1256 /// ```
1257 /// use entity::{Predicate as P, Value as V};
1258 ///
1259 /// let p = P::any(P::equals(3));
1260 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), true);
1261 ///
1262 /// let p = P::any(P::equals(4));
1263 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), false);
1264 /// ```
1265 pub fn any<P: Into<Predicate>>(p: P) -> Self {
1266 Self::Any(Box::new(p.into()))
1267 }
1268
1269 /// Creates a new predicate for [`Predicate::Contains`]
1270 ///
1271 /// ### Examples
1272 ///
1273 /// ```
1274 /// use entity::{Predicate as P, Value as V};
1275 ///
1276 /// let p = P::contains(3);
1277 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), true);
1278 ///
1279 /// let p = P::contains(4);
1280 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), false);
1281 /// ```
1282 pub fn contains<T: ValueLike>(value: T) -> Self {
1283 Self::Contains(value.into_value())
1284 }
1285
1286 /// Creates a new predicate for [`Predicate::ContainsAll`]
1287 ///
1288 /// ### Examples
1289 ///
1290 /// ```
1291 /// use entity::{Predicate as P, Value as V};
1292 ///
1293 /// let p = P::contains_all(vec![1, 3]);
1294 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), true);
1295 ///
1296 /// let p = P::contains_all(vec![1, 4]);
1297 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), false);
1298 /// ```
1299 pub fn contains_all<T: ValueLike, I: IntoIterator<Item = T>>(i: I) -> Self {
1300 Self::ContainsAll(i.into_iter().map(|p| p.into_value()).collect())
1301 }
1302
1303 /// Creates a new predicate for [`Predicate::ContainsAny`]
1304 ///
1305 /// ### Examples
1306 ///
1307 /// ```
1308 /// use entity::{Predicate as P, Value as V};
1309 ///
1310 /// let p = P::contains_any(vec![1, 4]);
1311 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), true);
1312 ///
1313 /// let p = P::contains_any(vec![4, 5]);
1314 /// assert_eq!(p.check(&V::from(vec![1, 2, 3])), false);
1315 /// ```
1316 pub fn contains_any<T: ValueLike, I: IntoIterator<Item = T>>(i: I) -> Self {
1317 Self::ContainsAny(i.into_iter().map(|p| p.into_value()).collect())
1318 }
1319
1320 /// Creates a new predicate for [`Predicate::Equals`]
1321 ///
1322 /// ### Examples
1323 ///
1324 /// ```
1325 /// use entity::{Predicate as P, Value as V};
1326 ///
1327 /// let p = P::equals(3);
1328 /// assert_eq!(p.check(&V::from(3)), true);
1329 /// assert_eq!(p.check(&V::from(2)), false);
1330 /// ```
1331 pub fn equals<T: ValueLike>(value: T) -> Self {
1332 Self::Equals(value.into_value())
1333 }
1334
1335 /// Creates a new predicate for [`Predicate::GreaterThan`]
1336 ///
1337 /// ### Examples
1338 ///
1339 /// ```
1340 /// use entity::{Predicate as P, Value as V};
1341 ///
1342 /// let p = P::greater_than(3);
1343 /// assert_eq!(p.check(&V::from(4)), true);
1344 /// assert_eq!(p.check(&V::from(3)), false);
1345 /// ```
1346 pub fn greater_than<T: ValueLike>(value: T) -> Self {
1347 Self::GreaterThan(value.into_value())
1348 }
1349
1350 /// Creates a new predicate for [`Predicate::GreaterThanOrEquals`]
1351 ///
1352 /// ### Examples
1353 ///
1354 /// ```
1355 /// use entity::{Predicate as P, Value as V};
1356 ///
1357 /// let p = P::greater_than_or_equals(3);
1358 /// assert_eq!(p.check(&V::from(4)), true);
1359 /// assert_eq!(p.check(&V::from(3)), true);
1360 /// assert_eq!(p.check(&V::from(2)), false);
1361 /// ```
1362 pub fn greater_than_or_equals<T: ValueLike>(value: T) -> Self {
1363 Self::GreaterThanOrEquals(value.into_value())
1364 }
1365
1366 /// Creates a new predicate for [`Predicate::InRange`]
1367 ///
1368 /// ### Examples
1369 ///
1370 /// ```
1371 /// use entity::{Predicate as P, Value as V};
1372 ///
1373 /// let p = P::in_range(3..=5);
1374 /// assert_eq!(p.check(&V::from(2)), false);
1375 /// assert_eq!(p.check(&V::from(3)), true);
1376 /// assert_eq!(p.check(&V::from(4)), true);
1377 /// assert_eq!(p.check(&V::from(5)), true);
1378 /// assert_eq!(p.check(&V::from(6)), false);
1379 /// ```
1380 pub fn in_range<T: ValueLike>(range: RangeInclusive<T>) -> Self {
1381 let (start, end) = range.into_inner();
1382 Self::InRange(RangeInclusive::new(start.into_value(), end.into_value()))
1383 }
1384
1385 /// Creates a new predicate for [`Predicate::InSet`]
1386 ///
1387 /// ### Examples
1388 ///
1389 /// ```
1390 /// use entity::{Predicate as P, Value as V};
1391 ///
1392 /// let p = P::in_set(vec![1, 2, 3]);
1393 /// assert_eq!(p.check(&V::from(0)), false);
1394 /// assert_eq!(p.check(&V::from(1)), true);
1395 /// assert_eq!(p.check(&V::from(2)), true);
1396 /// assert_eq!(p.check(&V::from(3)), true);
1397 /// assert_eq!(p.check(&V::from(4)), false);
1398 /// ```
1399 pub fn in_set<T: ValueLike, I: IntoIterator<Item = T>>(set: I) -> Self {
1400 Self::InSet(set.into_iter().map(|v| v.into_value()).collect())
1401 }
1402
1403 /// Creates a new predicate for [`Predicate::LessThan`]
1404 ///
1405 /// ### Examples
1406 ///
1407 /// ```
1408 /// use entity::{Predicate as P, Value as V};
1409 ///
1410 /// let p = P::less_than(3);
1411 /// assert_eq!(p.check(&V::from(2)), true);
1412 /// assert_eq!(p.check(&V::from(3)), false);
1413 /// ```
1414 pub fn less_than<T: ValueLike>(value: T) -> Self {
1415 Self::LessThan(value.into_value())
1416 }
1417
1418 /// Creates a new predicate for [`Predicate::LessThanOrEquals`]
1419 ///
1420 /// ### Examples
1421 ///
1422 /// ```
1423 /// use entity::{Predicate as P, Value as V};
1424 ///
1425 /// let p = P::less_than_or_equals(3);
1426 /// assert_eq!(p.check(&V::from(2)), true);
1427 /// assert_eq!(p.check(&V::from(3)), true);
1428 /// assert_eq!(p.check(&V::from(4)), false);
1429 /// ```
1430 pub fn less_than_or_equals<T: ValueLike>(value: T) -> Self {
1431 Self::LessThanOrEquals(value.into_value())
1432 }
1433
1434 /// Creates a new predicate for [`Predicate::NotEquals`]
1435 ///
1436 /// ```
1437 /// use entity::{Predicate as P, Value as V};
1438 ///
1439 /// let p = P::not_equals(3);
1440 /// assert_eq!(p.check(&V::from(2)), true);
1441 /// assert_eq!(p.check(&V::from(3)), false);
1442 /// ```
1443 pub fn not_equals<T: ValueLike>(value: T) -> Self {
1444 Self::NotEquals(value.into_value())
1445 }
1446
1447 /// Creates a new predicate for [`Predicate::NotInRange`]
1448 ///
1449 /// ### Examples
1450 ///
1451 /// ```
1452 /// use entity::{Predicate as P, Value as V};
1453 ///
1454 /// let p = P::not_in_range(3..=5);
1455 /// assert_eq!(p.check(&V::from(2)), true);
1456 /// assert_eq!(p.check(&V::from(3)), false);
1457 /// assert_eq!(p.check(&V::from(4)), false);
1458 /// assert_eq!(p.check(&V::from(5)), false);
1459 /// assert_eq!(p.check(&V::from(6)), true);
1460 /// ```
1461 pub fn not_in_range<T: ValueLike>(range: RangeInclusive<T>) -> Self {
1462 let (start, end) = range.into_inner();
1463 Self::NotInRange(RangeInclusive::new(start.into_value(), end.into_value()))
1464 }
1465
1466 /// Creates a new predicate for [`Predicate::NotInSet`]
1467 ///
1468 /// ### Examples
1469 ///
1470 /// ```
1471 /// use entity::{Predicate as P, Value as V};
1472 ///
1473 /// let p = P::not_in_set(vec![1, 2, 3]);
1474 /// assert_eq!(p.check(&V::from(0)), true);
1475 /// assert_eq!(p.check(&V::from(1)), false);
1476 /// assert_eq!(p.check(&V::from(2)), false);
1477 /// assert_eq!(p.check(&V::from(3)), false);
1478 /// assert_eq!(p.check(&V::from(4)), true);
1479 /// ```
1480 pub fn not_in_set<T: ValueLike, I: IntoIterator<Item = T>>(set: I) -> Self {
1481 Self::NotInSet(set.into_iter().map(|v| v.into_value()).collect())
1482 }
1483
1484 /// Creates a new predicate for [`Predicate::HasKey`]
1485 ///
1486 /// ### Examples
1487 ///
1488 /// ```
1489 /// use entity::{Predicate as P, Value as V};
1490 /// use std::collections::HashMap;
1491 ///
1492 /// let map: HashMap<String, u32> = vec![
1493 /// (String::from("a"), 1),
1494 /// (String::from("b"), 2),
1495 /// (String::from("c"), 3),
1496 /// ].into_iter().collect();
1497 ///
1498 /// let p = P::has_key("a");
1499 /// assert_eq!(p.check(&V::from(map.clone())), true);
1500 ///
1501 /// let p = P::has_key("d");
1502 /// assert_eq!(p.check(&V::from(map)), false);
1503 /// ```
1504 pub fn has_key<K: Into<String>>(k: K) -> Self {
1505 Self::HasKey(k.into())
1506 }
1507
1508 /// Creates a new typed predicate for [`Predicate::HasKeyWhereValue`]
1509 ///
1510 /// ### Examples
1511 ///
1512 /// ```
1513 /// use entity::{Predicate as P, Value as V};
1514 /// use std::collections::HashMap;
1515 ///
1516 /// let map: HashMap<String, u32> = vec![
1517 /// (String::from("a"), 1),
1518 /// (String::from("b"), 2),
1519 /// (String::from("c"), 3),
1520 /// ].into_iter().collect();
1521 ///
1522 /// let p = P::has_key_where_value("a", P::equals(1));
1523 /// assert_eq!(p.check(&V::from(map.clone())), true);
1524 ///
1525 /// let p = P::has_key_where_value("b", P::equals(1));
1526 /// assert_eq!(p.check(&V::from(map.clone())), false);
1527 ///
1528 /// let p = P::has_key_where_value("d", P::equals(1));
1529 /// assert_eq!(p.check(&V::from(map)), false);
1530 /// ```
1531 pub fn has_key_where_value<K: Into<String>, P: Into<Predicate>>(k: K, p: P) -> Self {
1532 Self::HasKeyWhereValue(k.into(), Box::new(p.into()))
1533 }
1534
1535 /// Creates a new predicate for [`Predicate::IsNone`]
1536 ///
1537 /// ### Examples
1538 ///
1539 /// ```
1540 /// use entity::{Predicate as P, Value as V};
1541 ///
1542 /// let p = P::is_none();
1543 /// assert_eq!(p.check(&V::from(None::<u32>)), true);
1544 /// assert_eq!(p.check(&V::from(Some(3))), false);
1545 /// ```
1546 #[inline]
1547 pub fn is_none() -> Self {
1548 Self::IsNone
1549 }
1550
1551 /// Creates a new predicate for [`Predicate::NotNoneAnd`]
1552 ///
1553 /// ### Examples
1554 ///
1555 /// ```
1556 /// use entity::{Predicate as P, Value as V};
1557 ///
1558 /// let p = P::not_none_and(P::equals(3));
1559 /// assert_eq!(p.check(&V::from(Some(3))), true);
1560 /// assert_eq!(p.check(&V::from(Some(2))), false);
1561 /// assert_eq!(p.check(&V::from(None::<u32>)), false);
1562 /// ```
1563 pub fn not_none_and<P: Into<Predicate>>(p: P) -> Self {
1564 Self::NotNoneAnd(Box::new(p.into()))
1565 }
1566
1567 /// Creates a new predicate for [`Predicate::NoneOr`]
1568 ///
1569 /// ### Examples
1570 ///
1571 /// ```
1572 /// use entity::{Predicate as P, Value as V};
1573 ///
1574 /// let p = P::none_or(P::equals(3));
1575 /// assert_eq!(p.check(&V::from(Some(3))), true);
1576 /// assert_eq!(p.check(&V::from(None::<u32>)), true);
1577 /// assert_eq!(p.check(&V::from(Some(2))), false);
1578 /// ```
1579 pub fn none_or<P: Into<Predicate>>(p: P) -> Self {
1580 Self::NoneOr(Box::new(p.into()))
1581 }
1582
1583 /// Creates a new predicate for [`Predicate::TextEndsWith`]
1584 ///
1585 /// ### Examples
1586 ///
1587 /// ```
1588 /// use entity::{Predicate as P, Value as V};
1589 ///
1590 /// let p = P::text_ends_with("text");
1591 ///
1592 /// assert_eq!(p.check(&V::from("some text")), true);
1593 /// assert_eq!(p.check(&V::from("text some")), false);
1594 /// ```
1595 pub fn text_ends_with<S: Into<String>>(s: S) -> Self {
1596 Self::TextEndsWith(s.into())
1597 }
1598
1599 /// Creates a new predicate for [`Predicate::TextEndsWithCaseInsensitive`]
1600 ///
1601 /// ### Examples
1602 ///
1603 /// ```
1604 /// use entity::{Predicate as P, Value as V};
1605 ///
1606 /// let p = P::text_ends_with_case_insensitive("text");
1607 ///
1608 /// assert_eq!(p.check(&V::from("SOME TEXT")), true);
1609 /// assert_eq!(p.check(&V::from("TEXT SOME")), false);
1610 /// ```
1611 pub fn text_ends_with_case_insensitive<S: Into<String>>(s: S) -> Self {
1612 Self::TextEndsWithCaseInsensitive(s.into())
1613 }
1614
1615 /// Creates a new predicate for [`Predicate::TextEqualsCaseInsensitive`]
1616 ///
1617 /// ### Examples
1618 ///
1619 /// ```
1620 /// use entity::{Predicate as P, Value as V};
1621 ///
1622 /// let p = P::text_equals_case_insensitive("text");
1623 ///
1624 /// assert_eq!(p.check(&V::from("TEXT")), true);
1625 /// assert_eq!(p.check(&V::from("OTHER")), false);
1626 /// ```
1627 pub fn text_equals_case_insensitive<S: Into<String>>(s: S) -> Self {
1628 Self::TextEqualsCaseInsensitive(s.into())
1629 }
1630
1631 /// Creates a new predicate for [`Predicate::TextInSetCaseInsensitive`]
1632 ///
1633 /// ### Examples
1634 ///
1635 /// ```
1636 /// use entity::{Predicate as P, Value as V};
1637 ///
1638 /// let p = P::text_in_set_case_insensitive(vec!["one", "two", "three"]);
1639 ///
1640 /// assert_eq!(p.check(&V::from("TWO")), true);
1641 /// assert_eq!(p.check(&V::from("FOUR")), false);
1642 /// ```
1643 pub fn text_in_set_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
1644 Self::TextInSetCaseInsensitive(i.into_iter().map(|s| s.into()).collect())
1645 }
1646
1647 /// Creates a new predicate for [`Predicate::TextNotEqualsCaseInsensitive`]
1648 ///
1649 /// ### Examples
1650 ///
1651 /// ```
1652 /// use entity::{Predicate as P, Value as V};
1653 ///
1654 /// let p = P::text_not_equals_case_insensitive("text");
1655 ///
1656 /// assert_eq!(p.check(&V::from("OTHER")), true);
1657 /// assert_eq!(p.check(&V::from("TEXT")), false);
1658 /// ```
1659 pub fn text_not_equals_case_insensitive<S: Into<String>>(s: S) -> Self {
1660 Self::TextNotEqualsCaseInsensitive(s.into())
1661 }
1662
1663 /// Creates a new predicate for [`Predicate::TextStartsWith`]
1664 ///
1665 /// ### Examples
1666 ///
1667 /// ```
1668 /// use entity::{Predicate as P, Value as V};
1669 ///
1670 /// let p = P::text_starts_with("text");
1671 ///
1672 /// assert_eq!(p.check(&V::from("text some")), true);
1673 /// assert_eq!(p.check(&V::from("some text")), false);
1674 /// ```
1675 pub fn text_starts_with<S: Into<String>>(s: S) -> Self {
1676 Self::TextStartsWith(s.into())
1677 }
1678
1679 /// Creates a new predicate for [`Predicate::TextStartsWithCaseInsensitive`]
1680 ///
1681 /// ### Examples
1682 ///
1683 /// ```
1684 /// use entity::{Predicate as P, Value as V};
1685 ///
1686 /// let p = P::text_starts_with_case_insensitive("text");
1687 ///
1688 /// assert_eq!(p.check(&V::from("TEXT SOME")), true);
1689 /// assert_eq!(p.check(&V::from("SOME TEXT")), false);
1690 /// ```
1691 pub fn text_starts_with_case_insensitive<S: Into<String>>(s: S) -> Self {
1692 Self::TextStartsWithCaseInsensitive(s.into())
1693 }
1694
1695 /// Creates a new predicate for [`Predicate::TextContainedIn`]
1696 ///
1697 /// ### Examples
1698 ///
1699 /// ```
1700 /// use entity::{Predicate as P, Value as V};
1701 ///
1702 /// let p = P::text_contained_in("text");
1703 ///
1704 /// assert_eq!(p.check(&V::from("ex")), true);
1705 /// assert_eq!(p.check(&V::from("tt")), false);
1706 /// ```
1707 pub fn text_contained_in<S: Into<String>>(s: S) -> Self {
1708 Self::TextContainedIn(s.into())
1709 }
1710
1711 /// Creates a new predicate for [`Predicate::TextContainedInCaseInsensitive`]
1712 ///
1713 /// ### Examples
1714 ///
1715 /// ```
1716 /// use entity::{Predicate as P, Value as V};
1717 ///
1718 /// let p = P::text_contained_in_case_insensitive("text");
1719 ///
1720 /// assert_eq!(p.check(&V::from("EX")), true);
1721 /// assert_eq!(p.check(&V::from("TT")), false);
1722 /// ```
1723 pub fn text_contained_in_case_insensitive<S: Into<String>>(s: S) -> Self {
1724 Self::TextContainedInCaseInsensitive(s.into())
1725 }
1726
1727 /// Creates a new predicate for [`Predicate::TextContainsAll`]
1728 ///
1729 /// ### Examples
1730 ///
1731 /// ```
1732 /// use entity::{Predicate as P, Value as V};
1733 ///
1734 /// let p = P::text_contains_all(vec!["one", "two", "three"]);
1735 ///
1736 /// assert_eq!(p.check(&V::from("my one and two and three text")), true);
1737 /// assert_eq!(p.check(&V::from("my one and two text")), false);
1738 /// ```
1739 pub fn text_contains_all<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
1740 Self::TextContainsAll(i.into_iter().map(|s| s.into()).collect())
1741 }
1742
1743 /// Creates a new predicate for [`Predicate::TextContainsAllCaseInsensitive`]
1744 ///
1745 /// ### Examples
1746 ///
1747 /// ```
1748 /// use entity::{Predicate as P, Value as V};
1749 ///
1750 /// let p = P::text_contains_all_case_insensitive(vec!["one", "two", "three"]);
1751 ///
1752 /// assert_eq!(p.check(&V::from("MY ONE AND TWO AND THREE TEXT")), true);
1753 /// assert_eq!(p.check(&V::from("MY ONE AND TWO TEXT")), false);
1754 /// ```
1755 pub fn text_contains_all_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
1756 i: I,
1757 ) -> Self {
1758 Self::TextContainsAllCaseInsensitive(i.into_iter().map(|s| s.into()).collect())
1759 }
1760
1761 /// Creates a new predicate for [`Predicate::TextContainsAny`]
1762 ///
1763 /// ### Examples
1764 ///
1765 /// ```
1766 /// use entity::{Predicate as P, Value as V};
1767 ///
1768 /// let p = P::text_contains_any(vec!["one", "two", "three"]);
1769 ///
1770 /// assert_eq!(p.check(&V::from("my one text")), true);
1771 /// assert_eq!(p.check(&V::from("my four text")), false);
1772 /// ```
1773 pub fn text_contains_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
1774 Self::TextContainsAny(i.into_iter().map(|s| s.into()).collect())
1775 }
1776
1777 /// Creates a new predicate for [`Predicate::TextContainsAnyCaseInsensitive`]
1778 ///
1779 /// ### Examples
1780 ///
1781 /// ```
1782 /// use entity::{Predicate as P, Value as V};
1783 ///
1784 /// let p = P::text_contains_any_case_insensitive(vec!["one", "two", "three"]);
1785 ///
1786 /// assert_eq!(p.check(&V::from("MY ONE TEXT")), true);
1787 /// assert_eq!(p.check(&V::from("MY FOUR TEXT")), false);
1788 /// ```
1789 pub fn text_contains_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
1790 i: I,
1791 ) -> Self {
1792 Self::TextContainsAnyCaseInsensitive(i.into_iter().map(|s| s.into()).collect())
1793 }
1794
1795 /// Creates a new predicate for [`Predicate::TextEndsWithAny`]
1796 ///
1797 /// ### Examples
1798 ///
1799 /// ```
1800 /// use entity::{Predicate as P, Value as V};
1801 ///
1802 /// let p = P::text_ends_with_any(vec!["one", "two", "three"]);
1803 ///
1804 /// assert_eq!(p.check(&V::from("my text one")), true);
1805 /// assert_eq!(p.check(&V::from("one my text")), false);
1806 /// ```
1807 pub fn text_ends_with_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
1808 Self::TextEndsWithAny(i.into_iter().map(|s| s.into()).collect())
1809 }
1810
1811 /// Creates a new predicate for [`Predicate::TextEndsWithAnyCaseInsensitive`]
1812 ///
1813 /// ### Examples
1814 ///
1815 /// ```
1816 /// use entity::{Predicate as P, Value as V};
1817 ///
1818 /// let p = P::text_ends_with_any_case_insensitive(vec!["one", "two", "three"]);
1819 ///
1820 /// assert_eq!(p.check(&V::from("MY TEXT ONE")), true);
1821 /// assert_eq!(p.check(&V::from("ONE MY TEXT")), false);
1822 /// ```
1823 pub fn text_ends_with_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
1824 i: I,
1825 ) -> Self {
1826 Self::TextEndsWithAnyCaseInsensitive(i.into_iter().map(|s| s.into()).collect())
1827 }
1828
1829 /// Creates a new predicate for [`Predicate::TextStartsWithAny`]
1830 ///
1831 /// ### Examples
1832 ///
1833 /// ```
1834 /// use entity::{Predicate as P, Value as V};
1835 ///
1836 /// let p = P::text_starts_with_any(vec!["one", "two", "three"]);
1837 ///
1838 /// assert_eq!(p.check(&V::from("one my text")), true);
1839 /// assert_eq!(p.check(&V::from("my text one")), false);
1840 /// ```
1841 pub fn text_starts_with_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
1842 Self::TextStartsWithAny(i.into_iter().map(|s| s.into()).collect())
1843 }
1844
1845 /// Creates a new predicate for [`Predicate::TextStartsWithAnyCaseInsensitive`]
1846 ///
1847 /// ### Examples
1848 ///
1849 /// ```
1850 /// use entity::{Predicate as P, Value as V};
1851 ///
1852 /// let p = P::text_starts_with_any_case_insensitive(vec!["one", "two", "three"]);
1853 ///
1854 /// assert_eq!(p.check(&V::from("ONE MY TEXT")), true);
1855 /// assert_eq!(p.check(&V::from("MY TEXT ONE")), false);
1856 /// ```
1857 pub fn text_starts_with_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
1858 i: I,
1859 ) -> Self {
1860 Self::TextStartsWithAnyCaseInsensitive(i.into_iter().map(|s| s.into()).collect())
1861 }
1862}
1863
1864impl<T: ValueLike> PartialEq<TypedPredicate<T>> for Predicate {
1865 fn eq(&self, other: &TypedPredicate<T>) -> bool {
1866 self == other.as_untyped()
1867 }
1868}
1869
1870impl<T: ValueLike> From<TypedPredicate<T>> for Predicate {
1871 fn from(typed_predicate: TypedPredicate<T>) -> Self {
1872 typed_predicate.0
1873 }
1874}
1875
1876impl std::ops::BitXor for Predicate {
1877 type Output = Self;
1878
1879 /// Shorthand to produce [`Predicate::Xor`]
1880 ///
1881 /// ### Examples
1882 ///
1883 /// ```
1884 /// use entity::{Predicate, Value, ValueLike};
1885 ///
1886 /// assert_eq!(
1887 /// Predicate::Equals(123.into_value()) ^ Predicate::Equals(124.into_value()),
1888 /// Predicate::Xor(vec![
1889 /// Predicate::Equals(123.into_value()),
1890 /// Predicate::Equals(124.into_value()),
1891 /// ]),
1892 /// );
1893 /// ```
1894 ///
1895 /// If the left-hand side is already a [`Predicate::Xor`], the returned
1896 /// predicate will be an updated instance:
1897 ///
1898 /// ```
1899 /// use entity::{Predicate, Value, ValueLike};
1900 ///
1901 /// assert_eq!(
1902 /// Predicate::Xor(vec![
1903 /// Predicate::Equals(122.into_value()),
1904 /// Predicate::Equals(123.into_value()),
1905 /// ]) ^ Predicate::Equals(124.into_value()),
1906 /// Predicate::Xor(vec![
1907 /// Predicate::Equals(122.into_value()),
1908 /// Predicate::Equals(123.into_value()),
1909 /// Predicate::Equals(124.into_value()),
1910 /// ]),
1911 /// );
1912 /// ```
1913 ///
1914 /// If the right-hand side is already a [`Predicate::Xor`], the returned
1915 /// predicate will be an updated instance:
1916 ///
1917 /// ```
1918 /// use entity::{Predicate, Value, ValueLike};
1919 ///
1920 /// assert_eq!(
1921 /// Predicate::Equals(122.into_value()) ^ Predicate::Xor(vec![
1922 /// Predicate::Equals(123.into_value()),
1923 /// Predicate::Equals(124.into_value()),
1924 /// ]),
1925 /// Predicate::Xor(vec![
1926 /// Predicate::Equals(122.into_value()),
1927 /// Predicate::Equals(123.into_value()),
1928 /// Predicate::Equals(124.into_value()),
1929 /// ]),
1930 /// );
1931 /// ```
1932 ///
1933 /// If both sides are already a [`Predicate::Xor`], the returned
1934 /// predicate will be a merge:
1935 ///
1936 /// ```
1937 /// use entity::{Predicate, Value, ValueLike};
1938 ///
1939 /// assert_eq!(
1940 /// Predicate::Xor(vec![
1941 /// Predicate::Equals(121.into_value()),
1942 /// Predicate::Equals(122.into_value()),
1943 /// ]) ^ Predicate::Xor(vec![
1944 /// Predicate::Equals(123.into_value()),
1945 /// Predicate::Equals(124.into_value()),
1946 /// ]),
1947 /// Predicate::Xor(vec![
1948 /// Predicate::Equals(121.into_value()),
1949 /// Predicate::Equals(122.into_value()),
1950 /// Predicate::Equals(123.into_value()),
1951 /// Predicate::Equals(124.into_value()),
1952 /// ]),
1953 /// );
1954 /// ```
1955 fn bitxor(self, rhs: Self) -> Self {
1956 let inner = match (self, rhs) {
1957 (Self::Xor(mut list1), Self::Xor(mut list2)) => {
1958 list1.append(&mut list2);
1959 list1
1960 }
1961 (x, Self::Xor(mut list)) => {
1962 list.insert(0, x);
1963 list
1964 }
1965 (Self::Xor(mut list), x) => {
1966 list.push(x);
1967 list
1968 }
1969 (x1, x2) => vec![x1, x2],
1970 };
1971 Self::Xor(inner)
1972 }
1973}
1974
1975impl std::ops::BitAnd for Predicate {
1976 type Output = Self;
1977
1978 /// Shorthand to produce [`Predicate::And`]
1979 ///
1980 /// ### Examples
1981 ///
1982 /// ```
1983 /// use entity::{Predicate, Value, ValueLike};
1984 ///
1985 /// assert_eq!(
1986 /// Predicate::Equals(123.into_value()) & Predicate::Equals(124.into_value()),
1987 /// Predicate::And(vec![
1988 /// Predicate::Equals(123.into_value()),
1989 /// Predicate::Equals(124.into_value()),
1990 /// ]),
1991 /// );
1992 /// ```
1993 ///
1994 /// If the left-hand side is already a [`Predicate::And`], the returned
1995 /// predicate will be an updated instance:
1996 ///
1997 /// ```
1998 /// use entity::{Predicate, Value, ValueLike};
1999 ///
2000 /// assert_eq!(
2001 /// Predicate::And(vec![
2002 /// Predicate::Equals(122.into_value()),
2003 /// Predicate::Equals(123.into_value()),
2004 /// ]) & Predicate::Equals(124.into_value()),
2005 /// Predicate::And(vec![
2006 /// Predicate::Equals(122.into_value()),
2007 /// Predicate::Equals(123.into_value()),
2008 /// Predicate::Equals(124.into_value()),
2009 /// ]),
2010 /// );
2011 /// ```
2012 ///
2013 /// If the right-hand side is already a [`Predicate::And`], the returned
2014 /// predicate will be an updated instance:
2015 ///
2016 /// ```
2017 /// use entity::{Predicate, Value, ValueLike};
2018 ///
2019 /// assert_eq!(
2020 /// Predicate::Equals(122.into_value()) & Predicate::And(vec![
2021 /// Predicate::Equals(123.into_value()),
2022 /// Predicate::Equals(124.into_value()),
2023 /// ]),
2024 /// Predicate::And(vec![
2025 /// Predicate::Equals(122.into_value()),
2026 /// Predicate::Equals(123.into_value()),
2027 /// Predicate::Equals(124.into_value()),
2028 /// ]),
2029 /// );
2030 /// ```
2031 ///
2032 /// If both sides are already a [`Predicate::And`], the returned
2033 /// predicate will be a merge:
2034 ///
2035 /// ```
2036 /// use entity::{Predicate, Value, ValueLike};
2037 ///
2038 /// assert_eq!(
2039 /// Predicate::And(vec![
2040 /// Predicate::Equals(121.into_value()),
2041 /// Predicate::Equals(122.into_value()),
2042 /// ]) & Predicate::And(vec![
2043 /// Predicate::Equals(123.into_value()),
2044 /// Predicate::Equals(124.into_value()),
2045 /// ]),
2046 /// Predicate::And(vec![
2047 /// Predicate::Equals(121.into_value()),
2048 /// Predicate::Equals(122.into_value()),
2049 /// Predicate::Equals(123.into_value()),
2050 /// Predicate::Equals(124.into_value()),
2051 /// ]),
2052 /// );
2053 /// ```
2054 fn bitand(self, rhs: Self) -> Self {
2055 let inner = match (self, rhs) {
2056 (Self::And(mut list1), Self::And(mut list2)) => {
2057 list1.append(&mut list2);
2058 list1
2059 }
2060 (x, Self::And(mut list)) => {
2061 list.insert(0, x);
2062 list
2063 }
2064 (Self::And(mut list), x) => {
2065 list.push(x);
2066 list
2067 }
2068 (x1, x2) => vec![x1, x2],
2069 };
2070 Self::And(inner)
2071 }
2072}
2073
2074impl std::ops::BitOr for Predicate {
2075 type Output = Self;
2076
2077 /// Shorthand to produce [`Predicate::Or`]
2078 ///
2079 /// ### Examples
2080 ///
2081 /// ```
2082 /// use entity::{Predicate, Value, ValueLike};
2083 ///
2084 /// assert_eq!(
2085 /// Predicate::Equals(123.into_value()) | Predicate::Equals(124.into_value()),
2086 /// Predicate::Or(vec![
2087 /// Predicate::Equals(123.into_value()),
2088 /// Predicate::Equals(124.into_value()),
2089 /// ]),
2090 /// );
2091 /// ```
2092 ///
2093 /// If the left-hand side is already a [`Predicate::Or`], the returned
2094 /// predicate will be an updated instance:
2095 ///
2096 /// ```
2097 /// use entity::{Predicate, Value, ValueLike};
2098 ///
2099 /// assert_eq!(
2100 /// Predicate::Or(vec![
2101 /// Predicate::Equals(122.into_value()),
2102 /// Predicate::Equals(123.into_value()),
2103 /// ]) | Predicate::Equals(124.into_value()),
2104 /// Predicate::Or(vec![
2105 /// Predicate::Equals(122.into_value()),
2106 /// Predicate::Equals(123.into_value()),
2107 /// Predicate::Equals(124.into_value()),
2108 /// ]),
2109 /// );
2110 /// ```
2111 ///
2112 /// If the right-hand side is already a [`Predicate::Or`], the returned
2113 /// predicate will be an updated instance:
2114 ///
2115 /// ```
2116 /// use entity::{Predicate, Value, ValueLike};
2117 ///
2118 /// assert_eq!(
2119 /// Predicate::Equals(122.into_value()) | Predicate::Or(vec![
2120 /// Predicate::Equals(123.into_value()),
2121 /// Predicate::Equals(124.into_value()),
2122 /// ]),
2123 /// Predicate::Or(vec![
2124 /// Predicate::Equals(122.into_value()),
2125 /// Predicate::Equals(123.into_value()),
2126 /// Predicate::Equals(124.into_value()),
2127 /// ]),
2128 /// );
2129 /// ```
2130 ///
2131 /// If both sides are already a [`Predicate::Or`], the returned
2132 /// predicate will be a merge:
2133 ///
2134 /// ```
2135 /// use entity::{Predicate, Value, ValueLike};
2136 ///
2137 /// assert_eq!(
2138 /// Predicate::Or(vec![
2139 /// Predicate::Equals(121.into_value()),
2140 /// Predicate::Equals(122.into_value()),
2141 /// ]) | Predicate::Or(vec![
2142 /// Predicate::Equals(123.into_value()),
2143 /// Predicate::Equals(124.into_value()),
2144 /// ]),
2145 /// Predicate::Or(vec![
2146 /// Predicate::Equals(121.into_value()),
2147 /// Predicate::Equals(122.into_value()),
2148 /// Predicate::Equals(123.into_value()),
2149 /// Predicate::Equals(124.into_value()),
2150 /// ]),
2151 /// );
2152 /// ```
2153 fn bitor(self, rhs: Self) -> Self {
2154 let inner = match (self, rhs) {
2155 (Self::Or(mut list1), Self::Or(mut list2)) => {
2156 list1.append(&mut list2);
2157 list1
2158 }
2159 (x, Self::Or(mut list)) => {
2160 list.insert(0, x);
2161 list
2162 }
2163 (Self::Or(mut list), x) => {
2164 list.push(x);
2165 list
2166 }
2167 (x1, x2) => vec![x1, x2],
2168 };
2169 Self::Or(inner)
2170 }
2171}
2172
2173impl std::ops::Not for Predicate {
2174 type Output = Self;
2175
2176 /// Shorthand to produce [`Predicate::Not`]
2177 ///
2178 /// ### Examples
2179 ///
2180 /// ```
2181 /// use entity::{Predicate, Value, ValueLike};
2182 ///
2183 /// assert_eq!(
2184 /// !Predicate::Equals(123.into_value()),
2185 /// Predicate::Not(Box::new(Predicate::Equals(123.into_value()))),
2186 /// );
2187 /// ```
2188 fn not(self) -> Self::Output {
2189 Self::Not(Box::new(self))
2190 }
2191}
2192
2193/// Represents a typed [`Predicate`], ensuring that only valid conditions are
2194/// used for a given type
2195#[derive(Clone, Debug, PartialEq)]
2196pub struct TypedPredicate<T: ValueLike>(Predicate, PhantomData<T>);
2197
2198impl<T: ValueLike> PartialEq<Predicate> for TypedPredicate<T> {
2199 fn eq(&self, other: &Predicate) -> bool {
2200 self.as_untyped() == other
2201 }
2202}
2203
2204impl<T: ValueLike> From<Predicate> for TypedPredicate<T> {
2205 fn from(predicate: Predicate) -> Self {
2206 Self(predicate, PhantomData)
2207 }
2208}
2209
2210impl<T: ValueLike> std::ops::BitXor for TypedPredicate<T> {
2211 type Output = Self;
2212
2213 /// Shorthand to produce [`Predicate::Xor`]
2214 fn bitxor(self, rhs: Self) -> Self {
2215 Self::new(self.0 ^ rhs.0)
2216 }
2217}
2218
2219impl<T: ValueLike> std::ops::BitAnd for TypedPredicate<T> {
2220 type Output = Self;
2221
2222 /// Shorthand to produce [`Predicate::And`]
2223 fn bitand(self, rhs: Self) -> Self {
2224 Self::new(self.0 & rhs.0)
2225 }
2226}
2227
2228impl<T: ValueLike> std::ops::BitOr for TypedPredicate<T> {
2229 type Output = Self;
2230
2231 /// Shorthand to produce [`Predicate::Or`]
2232 fn bitor(self, rhs: Self) -> Self {
2233 Self::new(self.0 | rhs.0)
2234 }
2235}
2236
2237impl<T: ValueLike> std::ops::Not for TypedPredicate<T> {
2238 type Output = Self;
2239
2240 /// Shorthand to produce [`Predicate::Not`]
2241 fn not(self) -> Self::Output {
2242 Self::new(!self.0)
2243 }
2244}
2245
2246impl<T: ValueLike> TypedPredicate<T> {
2247 /// Creates a new typed predicate for [`Predicate::Lambda`]
2248 ///
2249 /// ### Examples
2250 ///
2251 /// ```
2252 /// use entity::TypedPredicate as P;
2253 ///
2254 /// let p = P::lambda(|x| x > 3);
2255 /// assert_eq!(p.check(4), true);
2256 /// assert_eq!(p.check(1), false);
2257 /// ```
2258 pub fn lambda<F: 'static + Fn(T) -> bool>(f: F) -> Self {
2259 Self::new(Predicate::Lambda(Rc::new(
2260 move |v| match T::try_from_value(v.clone()) {
2261 Ok(x) => f(x),
2262 Err(_) => false,
2263 },
2264 )))
2265 }
2266}
2267
2268impl<T: ValueLike> TypedPredicate<T> {
2269 /// Creates a new typed predicate from an untyped predicate
2270 pub fn new(predicate: Predicate) -> Self {
2271 Self::from(predicate)
2272 }
2273
2274 /// Returns a reference to the untyped [`Predicate`] wrapped by this
2275 /// typed instance
2276 #[inline]
2277 pub fn as_untyped(&self) -> &Predicate {
2278 &self.0
2279 }
2280
2281 /// Checks if the typed predicate is satisfied by the given value
2282 ///
2283 /// NOTE: This consumes the value instead of the untyped version that
2284 /// merely references the value
2285 pub fn check(&self, value: T) -> bool {
2286 self.0.check(&value.into_value())
2287 }
2288
2289 /// Creates a new typed predicate for [`Predicate::Always`]
2290 ///
2291 /// ### Examples
2292 ///
2293 /// ```
2294 /// use entity::TypedPredicate as P;
2295 ///
2296 /// let p = P::always();
2297 /// assert_eq!(p.check(1), true);
2298 /// ```
2299 pub fn always() -> Self {
2300 Self::new(Predicate::always())
2301 }
2302
2303 /// Creates a new typed predicate for [`Predicate::Never`]
2304 ///
2305 /// ### Examples
2306 ///
2307 /// ```
2308 /// use entity::TypedPredicate as P;
2309 ///
2310 /// let p = P::never();
2311 /// assert_eq!(p.check(1), false);
2312 /// ```
2313 pub fn never() -> Self {
2314 Self::new(Predicate::never())
2315 }
2316
2317 /// Creates a new typed predicate for [`Predicate::And`]
2318 ///
2319 /// ### Examples
2320 ///
2321 /// ```
2322 /// use entity::TypedPredicate as P;
2323 ///
2324 /// let p = P::and(vec![
2325 /// P::greater_than(1),
2326 /// P::less_than(3),
2327 /// ]);
2328 /// assert_eq!(p.check(2), true);
2329 /// assert_eq!(p.check(1), false);
2330 /// ```
2331 pub fn and<P: Into<TypedPredicate<T>>, I: IntoIterator<Item = P>>(i: I) -> Self {
2332 Self::new(Predicate::and::<TypedPredicate<T>, Vec<TypedPredicate<T>>>(
2333 i.into_iter().map(|p| p.into()).collect(),
2334 ))
2335 }
2336
2337 /// Creates a new typed predicate for [`Predicate::Not`]
2338 ///
2339 /// ### Examples
2340 ///
2341 /// ```
2342 /// use entity::TypedPredicate as P;
2343 ///
2344 /// let p = P::not(P::greater_than(1));
2345 /// assert_eq!(p.check(1), true);
2346 /// assert_eq!(p.check(2), false);
2347 /// ```
2348 pub fn not<P: Into<TypedPredicate<T>>>(p: P) -> Self {
2349 Self::new(Predicate::not(p.into()))
2350 }
2351
2352 /// Creates a new typed predicate for [`Predicate::Or`]
2353 ///
2354 /// ### Examples
2355 ///
2356 /// ```
2357 /// use entity::TypedPredicate as P;
2358 ///
2359 /// let p = P::or(vec![P::greater_than(1), P::equals(1)]);
2360 /// assert_eq!(p.check(1), true);
2361 /// assert_eq!(p.check(2), true);
2362 /// assert_eq!(p.check(0), false);
2363 /// ```
2364 pub fn or<P: Into<TypedPredicate<T>>, I: IntoIterator<Item = P>>(i: I) -> Self {
2365 Self::new(Predicate::or::<TypedPredicate<T>, Vec<TypedPredicate<T>>>(
2366 i.into_iter().map(|p| p.into()).collect(),
2367 ))
2368 }
2369
2370 /// Creates a new typed predicate for [`Predicate::Xor`]
2371 ///
2372 /// ### Examples
2373 ///
2374 /// ```
2375 /// use entity::TypedPredicate as P;
2376 ///
2377 /// let p = P::xor(vec![P::greater_than(1), P::greater_than(2)]);
2378 /// assert_eq!(p.check(2), true);
2379 /// assert_eq!(p.check(3), false);
2380 /// assert_eq!(p.check(1), false);
2381 /// ```
2382 pub fn xor<P: Into<TypedPredicate<T>>, I: IntoIterator<Item = P>>(i: I) -> Self {
2383 Self::new(Predicate::xor::<TypedPredicate<T>, Vec<TypedPredicate<T>>>(
2384 i.into_iter().map(|p| p.into()).collect(),
2385 ))
2386 }
2387}
2388
2389/// Implementation for collections with a singular type. For
2390/// [`std::collections::HashMap`] and similar types, use the
2391/// [`MapTypedPredicate`] instead.
2392impl<T: ValueLike, C: IntoIterator<Item = T> + ValueLike> TypedPredicate<C> {
2393 /// Creates a new typed predicate for [`Predicate::Any`]
2394 ///
2395 /// ### Examples
2396 ///
2397 /// ```
2398 /// use entity::TypedPredicate as P;
2399 ///
2400 /// let p = P::any(P::equals(3));
2401 /// assert_eq!(p.check(vec![1, 2, 3]), true);
2402 ///
2403 /// let p = P::any(P::equals(4));
2404 /// assert_eq!(p.check(vec![1, 2, 3]), false);
2405 /// ```
2406 pub fn any<P: Into<TypedPredicate<T>>>(p: P) -> Self {
2407 Self::new(Predicate::any(p.into()))
2408 }
2409
2410 /// Creates a new typed predicate for [`Predicate::Contains`]
2411 ///
2412 /// ### Examples
2413 ///
2414 /// ```
2415 /// use entity::TypedPredicate as P;
2416 ///
2417 /// let p = P::contains(3);
2418 /// assert_eq!(p.check(vec![1, 2, 3]), true);
2419 ///
2420 /// let p = P::contains(4);
2421 /// assert_eq!(p.check(vec![1, 2, 3]), false);
2422 /// ```
2423 pub fn contains(value: T) -> Self {
2424 Self::new(Predicate::contains(value))
2425 }
2426
2427 /// Creates a new typed predicate for [`Predicate::ContainsAll`]
2428 ///
2429 /// ### Examples
2430 ///
2431 /// ```
2432 /// use entity::TypedPredicate as P;
2433 ///
2434 /// let p = P::contains_all(vec![1, 3]);
2435 /// assert_eq!(p.check(vec![1, 2, 3]), true);
2436 ///
2437 /// let p = P::contains_all(vec![1, 4]);
2438 /// assert_eq!(p.check(vec![1, 2, 3]), false);
2439 /// ```
2440 pub fn contains_all<I: IntoIterator<Item = T>>(i: I) -> Self {
2441 Self::new(Predicate::contains_all(i))
2442 }
2443
2444 /// Creates a new typed predicate for [`Predicate::ContainsAny`]
2445 ///
2446 /// ### Examples
2447 ///
2448 /// ```
2449 /// use entity::TypedPredicate as P;
2450 ///
2451 /// let p = P::contains_any(vec![1, 4]);
2452 /// assert_eq!(p.check(vec![1, 2, 3]), true);
2453 ///
2454 /// let p = P::contains_any(vec![4, 5]);
2455 /// assert_eq!(p.check(vec![1, 2, 3]), false);
2456 /// ```
2457 pub fn contains_any<I: IntoIterator<Item = T>>(i: I) -> Self {
2458 Self::new(Predicate::contains_any(i))
2459 }
2460}
2461
2462impl<T: ValueLike> TypedPredicate<T> {
2463 /// Creates a new typed predicate for [`Predicate::Equals`]
2464 ///
2465 /// ### Examples
2466 ///
2467 /// ```
2468 /// use entity::TypedPredicate as P;
2469 ///
2470 /// let p = P::equals(3);
2471 /// assert_eq!(p.check(3), true);
2472 /// assert_eq!(p.check(2), false);
2473 /// ```
2474 pub fn equals(value: T) -> Self {
2475 Self::new(Predicate::equals(value))
2476 }
2477
2478 /// Creates a new typed predicate for [`Predicate::GreaterThan`]
2479 ///
2480 /// ### Examples
2481 ///
2482 /// ```
2483 /// use entity::TypedPredicate as P;
2484 ///
2485 /// let p = P::greater_than(3);
2486 /// assert_eq!(p.check(4), true);
2487 /// assert_eq!(p.check(3), false);
2488 /// ```
2489 pub fn greater_than(value: T) -> Self {
2490 Self::new(Predicate::greater_than(value))
2491 }
2492
2493 /// Creates a new typed predicate for [`Predicate::GreaterThanOrEquals`]
2494 ///
2495 /// ### Examples
2496 ///
2497 /// ```
2498 /// use entity::TypedPredicate as P;
2499 ///
2500 /// let p = P::greater_than_or_equals(3);
2501 /// assert_eq!(p.check(4), true);
2502 /// assert_eq!(p.check(3), true);
2503 /// assert_eq!(p.check(2), false);
2504 /// ```
2505 pub fn greater_than_or_equals(value: T) -> Self {
2506 Self::new(Predicate::greater_than_or_equals(value))
2507 }
2508
2509 /// Creates a new typed predicate for [`Predicate::InRange`]
2510 ///
2511 /// ### Examples
2512 ///
2513 /// ```
2514 /// use entity::TypedPredicate as P;
2515 ///
2516 /// let p = P::in_range(3..=5);
2517 /// assert_eq!(p.check(2), false);
2518 /// assert_eq!(p.check(3), true);
2519 /// assert_eq!(p.check(4), true);
2520 /// assert_eq!(p.check(5), true);
2521 /// assert_eq!(p.check(6), false);
2522 /// ```
2523 pub fn in_range(range: RangeInclusive<T>) -> Self {
2524 Self::new(Predicate::in_range(range))
2525 }
2526
2527 /// Creates a new typed predicate for [`Predicate::InSet`]
2528 ///
2529 /// ### Examples
2530 ///
2531 /// ```
2532 /// use entity::TypedPredicate as P;
2533 ///
2534 /// let p = P::in_set(vec![1, 2, 3]);
2535 /// assert_eq!(p.check(0), false);
2536 /// assert_eq!(p.check(1), true);
2537 /// assert_eq!(p.check(2), true);
2538 /// assert_eq!(p.check(3), true);
2539 /// assert_eq!(p.check(4), false);
2540 /// ```
2541 pub fn in_set<I: IntoIterator<Item = T>>(set: I) -> Self {
2542 Self::new(Predicate::in_set(set))
2543 }
2544
2545 /// Creates a new typed predicate for [`Predicate::LessThan`]
2546 ///
2547 /// ### Examples
2548 ///
2549 /// ```
2550 /// use entity::TypedPredicate as P;
2551 ///
2552 /// let p = P::less_than(3);
2553 /// assert_eq!(p.check(2), true);
2554 /// assert_eq!(p.check(3), false);
2555 /// ```
2556 pub fn less_than(value: T) -> Self {
2557 Self::new(Predicate::less_than(value))
2558 }
2559
2560 /// Creates a new typed predicate for [`Predicate::LessThanOrEquals`]
2561 ///
2562 /// ### Examples
2563 ///
2564 /// ```
2565 /// use entity::TypedPredicate as P;
2566 ///
2567 /// let p = P::less_than_or_equals(3);
2568 /// assert_eq!(p.check(2), true);
2569 /// assert_eq!(p.check(3), true);
2570 /// assert_eq!(p.check(4), false);
2571 /// ```
2572 pub fn less_than_or_equals(value: T) -> Self {
2573 Self::new(Predicate::less_than_or_equals(value))
2574 }
2575
2576 /// Creates a new typed predicate for [`Predicate::NotEquals`]
2577 ///
2578 /// ```
2579 /// use entity::TypedPredicate as P;
2580 ///
2581 /// let p = P::not_equals(3);
2582 /// assert_eq!(p.check(2), true);
2583 /// assert_eq!(p.check(3), false);
2584 /// ```
2585 pub fn not_equals(value: T) -> Self {
2586 Self::new(Predicate::not_equals(value))
2587 }
2588
2589 /// Creates a new typed predicate for [`Predicate::NotInRange`]
2590 ///
2591 /// ### Examples
2592 ///
2593 /// ```
2594 /// use entity::TypedPredicate as P;
2595 ///
2596 /// let p = P::not_in_range(3..=5);
2597 /// assert_eq!(p.check(2), true);
2598 /// assert_eq!(p.check(3), false);
2599 /// assert_eq!(p.check(4), false);
2600 /// assert_eq!(p.check(5), false);
2601 /// assert_eq!(p.check(6), true);
2602 /// ```
2603 pub fn not_in_range(range: RangeInclusive<T>) -> Self {
2604 Self::new(Predicate::not_in_range(range))
2605 }
2606
2607 /// Creates a new typed predicate for [`Predicate::NotInSet`]
2608 ///
2609 /// ### Examples
2610 ///
2611 /// ```
2612 /// use entity::TypedPredicate as P;
2613 ///
2614 /// let p = P::not_in_set(vec![1, 2, 3]);
2615 /// assert_eq!(p.check(0), true);
2616 /// assert_eq!(p.check(1), false);
2617 /// assert_eq!(p.check(2), false);
2618 /// assert_eq!(p.check(3), false);
2619 /// assert_eq!(p.check(4), true);
2620 /// ```
2621 pub fn not_in_set<I: IntoIterator<Item = T>>(set: I) -> Self {
2622 Self::new(Predicate::not_in_set(set))
2623 }
2624}
2625
2626impl<T: ValueLike> TypedPredicate<HashMap<String, T>> {
2627 /// Creates a new typed predicate for [`Predicate::HasKey`]
2628 ///
2629 /// ### Examples
2630 ///
2631 /// ```
2632 /// use entity::TypedPredicate as P;
2633 /// use std::collections::HashMap;
2634 ///
2635 /// let map: HashMap<String, u32> = vec![
2636 /// (String::from("a"), 1),
2637 /// (String::from("b"), 2),
2638 /// (String::from("c"), 3),
2639 /// ].into_iter().collect();
2640 ///
2641 /// let p = P::has_key("a");
2642 /// assert_eq!(p.check(map.clone()), true);
2643 ///
2644 /// let p = P::has_key("d");
2645 /// assert_eq!(p.check(map), false);
2646 /// ```
2647 pub fn has_key<K: Into<String>>(k: K) -> Self {
2648 Self::new(Predicate::has_key(k))
2649 }
2650
2651 /// Creates a new typed predicate for [`Predicate::HasKeyWhereValue`]
2652 ///
2653 /// ### Examples
2654 ///
2655 /// ```
2656 /// use entity::TypedPredicate as P;
2657 /// use std::collections::HashMap;
2658 ///
2659 /// let map: HashMap<String, u32> = vec![
2660 /// (String::from("a"), 1),
2661 /// (String::from("b"), 2),
2662 /// (String::from("c"), 3),
2663 /// ].into_iter().collect();
2664 ///
2665 /// let p = P::has_key_where_value("a", P::equals(1));
2666 /// assert_eq!(p.check(map.clone()), true);
2667 ///
2668 /// let p = P::has_key_where_value("b", P::equals(1));
2669 /// assert_eq!(p.check(map.clone()), false);
2670 ///
2671 /// let p = P::has_key_where_value("d", P::equals(1));
2672 /// assert_eq!(p.check(map), false);
2673 /// ```
2674 pub fn has_key_where_value<K: Into<String>, P: Into<TypedPredicate<T>>>(k: K, p: P) -> Self {
2675 Self::new(Predicate::has_key_where_value(k.into(), p.into()))
2676 }
2677}
2678
2679impl<T: ValueLike> TypedPredicate<Option<T>> {
2680 /// Creates a new typed predicate for [`Predicate::IsNone`]
2681 ///
2682 /// ### Examples
2683 ///
2684 /// ```
2685 /// use entity::TypedPredicate as P;
2686 ///
2687 /// let p = P::is_none();
2688 ///
2689 /// let v = None::<u32>;
2690 /// assert_eq!(p.check(v), true);
2691 ///
2692 /// let v = Some(3);
2693 /// assert_eq!(p.check(v), false);
2694 /// ```
2695 pub fn is_none() -> Self {
2696 Self::new(Predicate::IsNone)
2697 }
2698
2699 /// Creates a new typed predicate for [`Predicate::NotNoneAnd`]
2700 ///
2701 /// ### Examples
2702 ///
2703 /// ```
2704 /// use entity::TypedPredicate as P;
2705 ///
2706 /// let p = P::not_none_and(P::equals(3));
2707 ///
2708 /// let v = Some(3);
2709 /// assert_eq!(p.check(v), true);
2710 ///
2711 /// let v = Some(2);
2712 /// assert_eq!(p.check(v), false);
2713 ///
2714 /// let v = None::<u32>;
2715 /// assert_eq!(p.check(v), false);
2716 /// ```
2717 pub fn not_none_and<P: Into<TypedPredicate<T>>>(p: P) -> Self {
2718 Self::new(Predicate::not_none_and(p.into()))
2719 }
2720
2721 /// Creates a new typed predicate for [`Predicate::NoneOr`]
2722 ///
2723 /// ### Examples
2724 ///
2725 /// ```
2726 /// use entity::TypedPredicate as P;
2727 ///
2728 /// let p = P::none_or(P::equals(3));
2729 ///
2730 /// let v = Some(3);
2731 /// assert_eq!(p.check(v), true);
2732 ///
2733 /// let v = None::<u32>;
2734 /// assert_eq!(p.check(v), true);
2735 ///
2736 /// let v = Some(2);
2737 /// assert_eq!(p.check(v), false);
2738 /// ```
2739 pub fn none_or<P: Into<TypedPredicate<T>>>(p: P) -> Self {
2740 Self::new(Predicate::none_or(p.into()))
2741 }
2742}
2743
2744impl TypedPredicate<String> {
2745 /// Creates a new typed predicate for [`Predicate::TextEndsWith`]
2746 ///
2747 /// ### Examples
2748 ///
2749 /// ```
2750 /// use entity::TypedPredicate as P;
2751 ///
2752 /// let p = P::text_ends_with("text");
2753 ///
2754 /// assert_eq!(p.check(String::from("some text")), true);
2755 /// assert_eq!(p.check(String::from("text some")), false);
2756 /// ```
2757 pub fn text_ends_with<S: Into<String>>(s: S) -> Self {
2758 Self::new(Predicate::text_ends_with(s))
2759 }
2760
2761 /// Creates a new typed predicate for [`Predicate::TextEndsWithCaseInsensitive`]
2762 ///
2763 /// ### Examples
2764 ///
2765 /// ```
2766 /// use entity::TypedPredicate as P;
2767 ///
2768 /// let p = P::text_ends_with_case_insensitive("text");
2769 ///
2770 /// assert_eq!(p.check(String::from("SOME TEXT")), true);
2771 /// assert_eq!(p.check(String::from("TEXT SOME")), false);
2772 /// ```
2773 pub fn text_ends_with_case_insensitive<S: Into<String>>(s: S) -> Self {
2774 Self::new(Predicate::text_ends_with_case_insensitive(s))
2775 }
2776
2777 /// Creates a new typed predicate for [`Predicate::TextEqualsCaseInsensitive`]
2778 ///
2779 /// ### Examples
2780 ///
2781 /// ```
2782 /// use entity::TypedPredicate as P;
2783 ///
2784 /// let p = P::text_equals_case_insensitive("text");
2785 ///
2786 /// assert_eq!(p.check(String::from("TEXT")), true);
2787 /// assert_eq!(p.check(String::from("OTHER")), false);
2788 /// ```
2789 pub fn text_equals_case_insensitive<S: Into<String>>(s: S) -> Self {
2790 Self::new(Predicate::text_equals_case_insensitive(s))
2791 }
2792
2793 /// Creates a new typed predicate for [`Predicate::TextInSetCaseInsensitive`]
2794 ///
2795 /// ### Examples
2796 ///
2797 /// ```
2798 /// use entity::TypedPredicate as P;
2799 ///
2800 /// let p = P::text_in_set_case_insensitive(vec!["one", "two", "three"]);
2801 ///
2802 /// assert_eq!(p.check(String::from("TWO")), true);
2803 /// assert_eq!(p.check(String::from("FOUR")), false);
2804 /// ```
2805 pub fn text_in_set_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
2806 Self::new(Predicate::text_in_set_case_insensitive(i))
2807 }
2808
2809 /// Creates a new typed predicate for [`Predicate::TextNotEqualsCaseInsensitive`]
2810 ///
2811 /// ### Examples
2812 ///
2813 /// ```
2814 /// use entity::TypedPredicate as P;
2815 ///
2816 /// let p = P::text_not_equals_case_insensitive("text");
2817 ///
2818 /// assert_eq!(p.check(String::from("OTHER")), true);
2819 /// assert_eq!(p.check(String::from("TEXT")), false);
2820 /// ```
2821 pub fn text_not_equals_case_insensitive<S: Into<String>>(s: S) -> Self {
2822 Self::new(Predicate::text_not_equals_case_insensitive(s))
2823 }
2824
2825 /// Creates a new typed predicate for [`Predicate::TextStartsWith`]
2826 ///
2827 /// ### Examples
2828 ///
2829 /// ```
2830 /// use entity::TypedPredicate as P;
2831 ///
2832 /// let p = P::text_starts_with("text");
2833 ///
2834 /// assert_eq!(p.check(String::from("text some")), true);
2835 /// assert_eq!(p.check(String::from("some text")), false);
2836 /// ```
2837 pub fn text_starts_with<S: Into<String>>(s: S) -> Self {
2838 Self::new(Predicate::text_starts_with(s))
2839 }
2840
2841 /// Creates a new typed predicate for [`Predicate::TextStartsWithCaseInsensitive`]
2842 ///
2843 /// ### Examples
2844 ///
2845 /// ```
2846 /// use entity::TypedPredicate as P;
2847 ///
2848 /// let p = P::text_starts_with_case_insensitive("text");
2849 ///
2850 /// assert_eq!(p.check(String::from("TEXT SOME")), true);
2851 /// assert_eq!(p.check(String::from("SOME TEXT")), false);
2852 /// ```
2853 pub fn text_starts_with_case_insensitive<S: Into<String>>(s: S) -> Self {
2854 Self::new(Predicate::text_starts_with_case_insensitive(s))
2855 }
2856
2857 /// Creates a new typed predicate for [`Predicate::TextContainedIn`]
2858 ///
2859 /// ### Examples
2860 ///
2861 /// ```
2862 /// use entity::TypedPredicate as P;
2863 ///
2864 /// let p = P::text_contained_in("text");
2865 ///
2866 /// assert_eq!(p.check(String::from("ex")), true);
2867 /// assert_eq!(p.check(String::from("tt")), false);
2868 /// ```
2869 pub fn text_contained_in<S: Into<String>>(s: S) -> Self {
2870 Self::new(Predicate::text_contained_in(s))
2871 }
2872
2873 /// Creates a new typed predicate for [`Predicate::TextContainedInCaseInsensitive`]
2874 ///
2875 /// ### Examples
2876 ///
2877 /// ```
2878 /// use entity::TypedPredicate as P;
2879 ///
2880 /// let p = P::text_contained_in_case_insensitive("text");
2881 ///
2882 /// assert_eq!(p.check(String::from("EX")), true);
2883 /// assert_eq!(p.check(String::from("TT")), false);
2884 /// ```
2885 pub fn text_contained_in_case_insensitive<S: Into<String>>(s: S) -> Self {
2886 Self::new(Predicate::text_contained_in_case_insensitive(s))
2887 }
2888
2889 /// Creates a new typed predicate for [`Predicate::TextContainsAll`]
2890 ///
2891 /// ### Examples
2892 ///
2893 /// ```
2894 /// use entity::TypedPredicate as P;
2895 ///
2896 /// let p = P::text_contains_all(vec!["one", "two", "three"]);
2897 ///
2898 /// assert_eq!(p.check(String::from("my one and two and three text")), true);
2899 /// assert_eq!(p.check(String::from("my one and two text")), false);
2900 /// ```
2901 pub fn text_contains_all<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
2902 Self::new(Predicate::text_contains_all(i))
2903 }
2904
2905 /// Creates a new typed predicate for [`Predicate::TextContainsAllCaseInsensitive`]
2906 ///
2907 /// ### Examples
2908 ///
2909 /// ```
2910 /// use entity::TypedPredicate as P;
2911 ///
2912 /// let p = P::text_contains_all_case_insensitive(vec!["one", "two", "three"]);
2913 ///
2914 /// assert_eq!(p.check(String::from("MY ONE AND TWO AND THREE TEXT")), true);
2915 /// assert_eq!(p.check(String::from("MY ONE AND TWO TEXT")), false);
2916 /// ```
2917 pub fn text_contains_all_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
2918 i: I,
2919 ) -> Self {
2920 Self::new(Predicate::text_contains_all_case_insensitive(i))
2921 }
2922
2923 /// Creates a new typed predicate for [`Predicate::TextContainsAny`]
2924 ///
2925 /// ### Examples
2926 ///
2927 /// ```
2928 /// use entity::TypedPredicate as P;
2929 ///
2930 /// let p = P::text_contains_any(vec!["one", "two", "three"]);
2931 ///
2932 /// assert_eq!(p.check(String::from("my one text")), true);
2933 /// assert_eq!(p.check(String::from("my four text")), false);
2934 /// ```
2935 pub fn text_contains_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
2936 Self::new(Predicate::text_contains_any(i))
2937 }
2938
2939 /// Creates a new typed predicate for [`Predicate::TextContainsAnyCaseInsensitive`]
2940 ///
2941 /// ### Examples
2942 ///
2943 /// ```
2944 /// use entity::TypedPredicate as P;
2945 ///
2946 /// let p = P::text_contains_any_case_insensitive(vec!["one", "two", "three"]);
2947 ///
2948 /// assert_eq!(p.check(String::from("MY ONE TEXT")), true);
2949 /// assert_eq!(p.check(String::from("MY FOUR TEXT")), false);
2950 /// ```
2951 pub fn text_contains_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
2952 i: I,
2953 ) -> Self {
2954 Self::new(Predicate::text_contains_any_case_insensitive(i))
2955 }
2956
2957 /// Creates a new typed predicate for [`Predicate::TextEndsWithAny`]
2958 ///
2959 /// ### Examples
2960 ///
2961 /// ```
2962 /// use entity::TypedPredicate as P;
2963 ///
2964 /// let p = P::text_ends_with_any(vec!["one", "two", "three"]);
2965 ///
2966 /// assert_eq!(p.check(String::from("my text one")), true);
2967 /// assert_eq!(p.check(String::from("one my text")), false);
2968 /// ```
2969 pub fn text_ends_with_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
2970 Self::new(Predicate::text_ends_with_any(i))
2971 }
2972
2973 /// Creates a new typed predicate for [`Predicate::TextEndsWithAnyCaseInsensitive`]
2974 ///
2975 /// ### Examples
2976 ///
2977 /// ```
2978 /// use entity::TypedPredicate as P;
2979 ///
2980 /// let p = P::text_ends_with_any_case_insensitive(vec!["one", "two", "three"]);
2981 ///
2982 /// assert_eq!(p.check(String::from("MY TEXT ONE")), true);
2983 /// assert_eq!(p.check(String::from("ONE MY TEXT")), false);
2984 /// ```
2985 pub fn text_ends_with_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
2986 i: I,
2987 ) -> Self {
2988 Self::new(Predicate::text_ends_with_any_case_insensitive(i))
2989 }
2990
2991 /// Creates a new typed predicate for [`Predicate::TextStartsWithAny`]
2992 ///
2993 /// ### Examples
2994 ///
2995 /// ```
2996 /// use entity::TypedPredicate as P;
2997 ///
2998 /// let p = P::text_starts_with_any(vec!["one", "two", "three"]);
2999 ///
3000 /// assert_eq!(p.check(String::from("one my text")), true);
3001 /// assert_eq!(p.check(String::from("my text one")), false);
3002 /// ```
3003 pub fn text_starts_with_any<S: Into<String>, I: IntoIterator<Item = S>>(i: I) -> Self {
3004 Self::new(Predicate::text_starts_with_any(i))
3005 }
3006
3007 /// Creates a new typed predicate for [`Predicate::TextStartsWithAnyCaseInsensitive`]
3008 ///
3009 /// ### Examples
3010 ///
3011 /// ```
3012 /// use entity::TypedPredicate as P;
3013 ///
3014 /// let p = P::text_starts_with_any_case_insensitive(vec!["one", "two", "three"]);
3015 ///
3016 /// assert_eq!(p.check(String::from("ONE MY TEXT")), true);
3017 /// assert_eq!(p.check(String::from("MY TEXT ONE")), false);
3018 /// ```
3019 pub fn text_starts_with_any_case_insensitive<S: Into<String>, I: IntoIterator<Item = S>>(
3020 i: I,
3021 ) -> Self {
3022 Self::new(Predicate::text_starts_with_any_case_insensitive(i))
3023 }
3024}
3025
3026/// Represents a typed [`Predicate`] specifically for maps such as
3027/// [`std::collections::HashMap`], ensuring that only valid conditions are
3028/// used for a given type.
3029///
3030/// This is required due to limitations in Rust's blanket impl functionality,
3031/// which will be resolved once specialization is available.
3032#[derive(Clone, Debug, PartialEq)]
3033pub struct MapTypedPredicate<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike>(
3034 Predicate,
3035 PhantomData<T>,
3036 PhantomData<C>,
3037);
3038
3039impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> PartialEq<Predicate>
3040 for MapTypedPredicate<T, C>
3041{
3042 fn eq(&self, other: &Predicate) -> bool {
3043 self.as_untyped() == other
3044 }
3045}
3046
3047impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> From<Predicate>
3048 for MapTypedPredicate<T, C>
3049{
3050 fn from(predicate: Predicate) -> Self {
3051 Self(predicate, PhantomData, PhantomData)
3052 }
3053}
3054
3055impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> From<MapTypedPredicate<T, C>>
3056 for Predicate
3057{
3058 fn from(map_typed_predicate: MapTypedPredicate<T, C>) -> Self {
3059 map_typed_predicate.0
3060 }
3061}
3062
3063impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> From<TypedPredicate<C>>
3064 for MapTypedPredicate<T, C>
3065{
3066 fn from(typed_predicate: TypedPredicate<C>) -> Self {
3067 Self(typed_predicate.into(), PhantomData, PhantomData)
3068 }
3069}
3070
3071impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> From<MapTypedPredicate<T, C>>
3072 for TypedPredicate<C>
3073{
3074 fn from(map_typed_predicate: MapTypedPredicate<T, C>) -> Self {
3075 Self(map_typed_predicate.into(), PhantomData)
3076 }
3077}
3078
3079impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> std::ops::BitXor
3080 for MapTypedPredicate<T, C>
3081{
3082 type Output = Self;
3083
3084 /// Shorthand to produce [`Predicate::Xor`]
3085 fn bitxor(self, rhs: Self) -> Self {
3086 Self::new(self.0 ^ rhs.0)
3087 }
3088}
3089
3090impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> std::ops::BitAnd
3091 for MapTypedPredicate<T, C>
3092{
3093 type Output = Self;
3094
3095 /// Shorthand to produce [`Predicate::And`]
3096 fn bitand(self, rhs: Self) -> Self {
3097 Self::new(self.0 & rhs.0)
3098 }
3099}
3100
3101impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> std::ops::BitOr
3102 for MapTypedPredicate<T, C>
3103{
3104 type Output = Self;
3105
3106 /// Shorthand to produce [`Predicate::Or`]
3107 fn bitor(self, rhs: Self) -> Self {
3108 Self::new(self.0 | rhs.0)
3109 }
3110}
3111
3112impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> std::ops::Not
3113 for MapTypedPredicate<T, C>
3114{
3115 type Output = Self;
3116
3117 /// Shorthand to produce [`Predicate::Not`]
3118 fn not(self) -> Self::Output {
3119 Self::new(!self.0)
3120 }
3121}
3122
3123impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> MapTypedPredicate<T, C> {
3124 /// Creates a new map typed predicate from an untyped predicate
3125 pub fn new(predicate: Predicate) -> Self {
3126 Self::from(predicate)
3127 }
3128
3129 /// Returns a reference to the untyped [`Predicate`] wrapped by this
3130 /// typed instance
3131 #[inline]
3132 pub fn as_untyped(&self) -> &Predicate {
3133 &self.0
3134 }
3135
3136 /// Checks if the typed predicate is satisfied by the given value
3137 ///
3138 /// NOTE: This consumes the value instead of the untyped version that
3139 /// merely references the value
3140 pub fn check(&self, value: C) -> bool {
3141 self.0.check(&value.into_value())
3142 }
3143}
3144
3145impl<T: ValueLike, C: IntoIterator<Item = (String, T)> + ValueLike> MapTypedPredicate<T, C> {
3146 /// Creates a new typed predicate for [`Predicate::Any`]
3147 ///
3148 /// ### Examples
3149 ///
3150 /// ```
3151 /// use entity::{TypedPredicate as P, MapTypedPredicate as MP};
3152 /// use std::collections::HashMap;
3153 ///
3154 /// let mut map = HashMap::new();
3155 /// map.insert(String::from("a"), 1);
3156 /// map.insert(String::from("b"), 2);
3157 /// map.insert(String::from("c"), 3);
3158 ///
3159 /// let p = MP::any(P::equals(3));
3160 /// assert_eq!(p.check(map.clone()), true);
3161 ///
3162 /// let p = MP::any(P::equals(4));
3163 /// assert_eq!(p.check(map), false);
3164 /// ```
3165 pub fn any<P: Into<TypedPredicate<T>>>(p: P) -> Self {
3166 Self::new(Predicate::any(p.into()))
3167 }
3168
3169 /// Creates a new typed predicate for [`Predicate::Contains`]
3170 ///
3171 /// ### Examples
3172 ///
3173 /// ```
3174 /// use entity::{TypedPredicate as P, MapTypedPredicate as MP};
3175 /// use std::collections::HashMap;
3176 ///
3177 /// let mut map = HashMap::new();
3178 /// map.insert(String::from("a"), 1);
3179 /// map.insert(String::from("b"), 2);
3180 /// map.insert(String::from("c"), 3);
3181 ///
3182 /// let p = MP::contains(3);
3183 /// assert_eq!(p.check(map.clone()), true);
3184 ///
3185 /// let p = MP::contains(4);
3186 /// assert_eq!(p.check(map), false);
3187 /// ```
3188 pub fn contains(value: T) -> Self {
3189 Self::new(Predicate::contains(value))
3190 }
3191
3192 /// Creates a new typed predicate for [`Predicate::ContainsAll`]
3193 ///
3194 /// ### Examples
3195 ///
3196 /// ```
3197 /// use entity::{TypedPredicate as P, MapTypedPredicate as MP};
3198 /// use std::collections::HashMap;
3199 ///
3200 /// let mut map = HashMap::new();
3201 /// map.insert(String::from("a"), 1);
3202 /// map.insert(String::from("b"), 2);
3203 /// map.insert(String::from("c"), 3);
3204 ///
3205 /// let p = MP::contains_all(vec![1, 3]);
3206 /// assert_eq!(p.check(map.clone()), true);
3207 ///
3208 /// let p = MP::contains_all(vec![1, 4]);
3209 /// assert_eq!(p.check(map), false);
3210 /// ```
3211 pub fn contains_all<I: IntoIterator<Item = T>>(i: I) -> Self {
3212 Self::new(Predicate::contains_all(i))
3213 }
3214
3215 /// Creates a new typed predicate for [`Predicate::ContainsAny`]
3216 ///
3217 /// ### Examples
3218 ///
3219 /// ```
3220 /// use entity::{TypedPredicate as P, MapTypedPredicate as MP};
3221 /// use std::collections::HashMap;
3222 ///
3223 /// let mut map = HashMap::new();
3224 /// map.insert(String::from("a"), 1);
3225 /// map.insert(String::from("b"), 2);
3226 /// map.insert(String::from("c"), 3);
3227 ///
3228 /// let p = MP::contains_any(vec![1, 4]);
3229 /// assert_eq!(p.check(map.clone()), true);
3230 ///
3231 /// let p = MP::contains_any(vec![4, 5]);
3232 /// assert_eq!(p.check(map), false);
3233 /// ```
3234 pub fn contains_any<I: IntoIterator<Item = T>>(i: I) -> Self {
3235 Self::new(Predicate::contains_any(i))
3236 }
3237}