use crate::map::ErasedTy;
#[cfg(feature = "sync")]
pub type ValidatorHandler<T> = Box<dyn Fn(&T) -> bool + Send + Sync>;
#[cfg(not(feature = "sync"))]
pub type ValidatorHandler<T> = Box<dyn Fn(&T) -> bool>;
pub struct ValValidator<T>(ValidatorHandler<T>);
impl<T> std::fmt::Debug for ValValidator<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ValValidator").field(&"{...}").finish()
}
}
impl<T: ErasedTy> ValValidator<T> {
pub fn new(handler: ValidatorHandler<T>) -> Self {
Self(handler)
}
pub fn invoke(&self, val: &T) -> bool {
(self.0)(val)
}
#[cfg(feature = "sync")]
pub fn from_fn(func: impl Fn(&T) -> bool + Send + Sync + 'static) -> Self {
Self(Box::new(move |val| func(val)))
}
#[cfg(not(feature = "sync"))]
pub fn from_fn(func: impl Fn(&T) -> bool + 'static) -> Self {
Self(Box::new(move |val| func(val)))
}
}
impl<T: ErasedTy + PartialEq> ValValidator<T> {
pub fn equal(val: T) -> Self {
Self(Box::new(move |inner_val| inner_val == &val))
}
pub fn contains(vals: Vec<T>) -> Self {
Self(Box::new(move |inner_val| vals.contains(inner_val)))
}
}
impl<T: ErasedTy> ValValidator<T> {
pub fn equal2<K>(val: K) -> Self
where
K: ErasedTy + PartialEq<T>,
{
Self(Box::new(move |inner_val| &val == inner_val))
}
pub fn contains2<K>(vals: Vec<K>) -> Self
where
K: ErasedTy + PartialEq<T>,
{
Self(Box::new(move |inner_val| {
vals.iter().any(|v| PartialEq::eq(v, inner_val))
}))
}
}
impl<T: ErasedTy + PartialOrd> ValValidator<T> {
pub fn range_full(start: T, end: T) -> Self {
Self(Box::new(move |inner_val| {
inner_val >= &start && inner_val <= &end
}))
}
pub fn range_from(start: T) -> Self {
Self(Box::new(move |inner_val| inner_val >= &start))
}
pub fn range_to(end: T) -> Self {
Self(Box::new(move |inner_val| inner_val <= &end))
}
}