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}