use crate::{Scalar, consideration::*};
pub trait Condition<M = ()>: Send + Sync {
fn validate(&self, memory: &M) -> bool;
}
impl<M> Condition<M> for bool {
fn validate(&self, _: &M) -> bool {
*self
}
}
pub struct ClosureCondition<M = ()>(pub Box<dyn Fn(&M) -> bool + Send + Sync>);
impl<M> ClosureCondition<M> {
pub fn new<F>(f: F) -> Self
where
F: Fn(&M) -> bool + 'static + Send + Sync,
{
Self(Box::new(f))
}
}
impl<M> Condition<M> for ClosureCondition<M> {
fn validate(&self, memory: &M) -> bool {
(self.0)(memory)
}
}
impl<M> std::fmt::Debug for ClosureCondition<M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ClosureCondition").finish()
}
}
pub struct ConditionInvert<M = ()>(pub Box<dyn Condition<M>>);
impl<M> ConditionInvert<M> {
pub fn new<C>(condition: C) -> Self
where
C: Condition<M> + 'static,
{
Self(Box::new(condition))
}
}
impl<M> Condition<M> for ConditionInvert<M> {
fn validate(&self, memory: &M) -> bool {
!self.0.validate(memory)
}
}
impl<M> std::fmt::Debug for ConditionInvert<M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConditionInvert").finish()
}
}
pub struct ConsiderationCondition<M = ()> {
pub consideration: Box<dyn Consideration<M>>,
pub threshold: Scalar,
}
impl<M> ConsiderationCondition<M> {
pub fn new<C>(consideration: C, threshold: Scalar) -> Self
where
C: Consideration<M> + 'static,
{
Self {
consideration: Box::new(consideration),
threshold,
}
}
}
impl<M> Condition<M> for ConsiderationCondition<M> {
fn validate(&self, memory: &M) -> bool {
self.consideration.score(memory) > self.threshold
}
}
impl<M> std::fmt::Debug for ConsiderationCondition<M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConsiderationCondition")
.field("threshold", &self.threshold)
.finish()
}
}