use std::fmt;
use std::marker::PhantomData;
use crate::reflection;
use crate::utils;
use crate::Predicate;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
function: F,
name: &'static str,
_phantom: PhantomData<T>,
}
impl<F, T> FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
pub fn fn_name(mut self, name: &'static str) -> Self {
self.name = name;
self
}
}
impl<F, T> Predicate<T> for FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
fn eval(&self, variable: &T) -> bool {
(self.function)(variable)
}
fn find_case<'a>(&'a self, expected: bool, variable: &T) -> Option<reflection::Case<'a>> {
utils::default_find_case(self, expected, variable)
}
}
impl<F, T> reflection::PredicateReflection for FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
}
impl<F, T> fmt::Display for FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}(var)", self.name)
}
}
pub fn function<F, T>(function: F) -> FnPredicate<F, T>
where
F: Fn(&T) -> bool,
T: ?Sized,
{
FnPredicate {
function,
name: "fn",
_phantom: PhantomData,
}
}
#[test]
fn str_function() {
let f = function(|x: &str| x == "hello");
assert!(f.eval(&"hello"));
assert!(!f.eval(&"goodbye"));
}