aopt_core/value/
validator.rs

1use crate::map::ErasedTy;
2
3#[cfg(feature = "sync")]
4pub type ValidatorHandler<T> = Box<dyn Fn(&T) -> bool + Send + Sync>;
5
6#[cfg(not(feature = "sync"))]
7pub type ValidatorHandler<T> = Box<dyn Fn(&T) -> bool>;
8
9pub struct ValValidator<T>(ValidatorHandler<T>);
10
11impl<T> std::fmt::Debug for ValValidator<T> {
12    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13        f.debug_tuple("ValValidator").field(&"{...}").finish()
14    }
15}
16
17impl<T: ErasedTy> ValValidator<T> {
18    pub fn new(handler: ValidatorHandler<T>) -> Self {
19        Self(handler)
20    }
21
22    pub fn invoke(&self, val: &T) -> bool {
23        (self.0)(val)
24    }
25
26    #[cfg(feature = "sync")]
27    pub fn from_fn(func: impl Fn(&T) -> bool + Send + Sync + 'static) -> Self {
28        Self(Box::new(move |val| func(val)))
29    }
30
31    #[cfg(not(feature = "sync"))]
32    pub fn from_fn(func: impl Fn(&T) -> bool + 'static) -> Self {
33        Self(Box::new(move |val| func(val)))
34    }
35}
36
37impl<T: ErasedTy + PartialEq> ValValidator<T> {
38    pub fn equal(val: T) -> Self {
39        Self(Box::new(move |inner_val| inner_val == &val))
40    }
41
42    pub fn contains(vals: Vec<T>) -> Self {
43        Self(Box::new(move |inner_val| vals.contains(inner_val)))
44    }
45}
46
47impl<T: ErasedTy> ValValidator<T> {
48    pub fn equal2<K>(val: K) -> Self
49    where
50        K: ErasedTy + PartialEq<T>,
51    {
52        Self(Box::new(move |inner_val| &val == inner_val))
53    }
54
55    pub fn contains2<K>(vals: Vec<K>) -> Self
56    where
57        K: ErasedTy + PartialEq<T>,
58    {
59        Self(Box::new(move |inner_val| {
60            vals.iter().any(|v| PartialEq::eq(v, inner_val))
61        }))
62    }
63}
64
65impl<T: ErasedTy + PartialOrd> ValValidator<T> {
66    pub fn range_full(start: T, end: T) -> Self {
67        Self(Box::new(move |inner_val| {
68            inner_val >= &start && inner_val <= &end
69        }))
70    }
71
72    pub fn range_from(start: T) -> Self {
73        Self(Box::new(move |inner_val| inner_val >= &start))
74    }
75
76    pub fn range_to(end: T) -> Self {
77        Self(Box::new(move |inner_val| inner_val <= &end))
78    }
79}