use std::fmt;
use reflection;
use utils;
use Predicate;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum EqOps {
Equal,
NotEqual,
}
impl fmt::Display for EqOps {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let op = match *self {
EqOps::Equal => "==",
EqOps::NotEqual => "!=",
};
write!(f, "{}", op)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
constant: T,
op: EqOps,
}
impl<T> Predicate<T> for EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
fn eval(&self, variable: &T) -> bool {
match self.op {
EqOps::Equal => variable.eq(&self.constant),
EqOps::NotEqual => variable.ne(&self.constant),
}
}
fn find_case<'a>(&'a self, expected: bool, variable: &T) -> Option<reflection::Case<'a>> {
utils::default_find_case(self, expected, variable)
}
}
impl<'a, T> Predicate<T> for EqPredicate<&'a T>
where
T: fmt::Debug + PartialEq + ?Sized,
{
fn eval(&self, variable: &T) -> bool {
match self.op {
EqOps::Equal => variable.eq(self.constant),
EqOps::NotEqual => variable.ne(self.constant),
}
}
fn find_case<'b>(&'b self, expected: bool, variable: &T) -> Option<reflection::Case<'b>> {
utils::default_find_case(self, expected, variable)
}
}
impl<T> reflection::PredicateReflection for EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
}
impl<T> fmt::Display for EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "var {} {:?}", self.op, self.constant)
}
}
pub fn eq<T>(constant: T) -> EqPredicate<T>
where
T: fmt::Debug + PartialEq,
{
EqPredicate {
constant,
op: EqOps::Equal,
}
}
pub fn ne<T>(constant: T) -> EqPredicate<T>
where
T: PartialEq + fmt::Debug,
{
EqPredicate {
constant,
op: EqOps::NotEqual,
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum OrdOps {
LessThan,
LessThanOrEqual,
GreaterThanOrEqual,
GreaterThan,
}
impl fmt::Display for OrdOps {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let op = match *self {
OrdOps::LessThan => "<",
OrdOps::LessThanOrEqual => "<=",
OrdOps::GreaterThanOrEqual => ">=",
OrdOps::GreaterThan => ">",
};
write!(f, "{}", op)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
constant: T,
op: OrdOps,
}
impl<T> Predicate<T> for OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
fn eval(&self, variable: &T) -> bool {
match self.op {
OrdOps::LessThan => variable.lt(&self.constant),
OrdOps::LessThanOrEqual => variable.le(&self.constant),
OrdOps::GreaterThanOrEqual => variable.ge(&self.constant),
OrdOps::GreaterThan => variable.gt(&self.constant),
}
}
fn find_case<'a>(&'a self, expected: bool, variable: &T) -> Option<reflection::Case<'a>> {
utils::default_find_case(self, expected, variable)
}
}
impl<'a, T> Predicate<T> for OrdPredicate<&'a T>
where
T: fmt::Debug + PartialOrd + ?Sized,
{
fn eval(&self, variable: &T) -> bool {
match self.op {
OrdOps::LessThan => variable.lt(self.constant),
OrdOps::LessThanOrEqual => variable.le(self.constant),
OrdOps::GreaterThanOrEqual => variable.ge(self.constant),
OrdOps::GreaterThan => variable.gt(self.constant),
}
}
fn find_case<'b>(&'b self, expected: bool, variable: &T) -> Option<reflection::Case<'b>> {
utils::default_find_case(self, expected, variable)
}
}
impl<T> reflection::PredicateReflection for OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
}
impl<T> fmt::Display for OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "var {} {:?}", self.op, self.constant)
}
}
pub fn lt<T>(constant: T) -> OrdPredicate<T>
where
T: fmt::Debug + PartialOrd,
{
OrdPredicate {
constant,
op: OrdOps::LessThan,
}
}
pub fn le<T>(constant: T) -> OrdPredicate<T>
where
T: PartialOrd + fmt::Debug,
{
OrdPredicate {
constant,
op: OrdOps::LessThanOrEqual,
}
}
pub fn ge<T>(constant: T) -> OrdPredicate<T>
where
T: PartialOrd + fmt::Debug,
{
OrdPredicate {
constant,
op: OrdOps::GreaterThanOrEqual,
}
}
pub fn gt<T>(constant: T) -> OrdPredicate<T>
where
T: PartialOrd + fmt::Debug,
{
OrdPredicate {
constant,
op: OrdOps::GreaterThan,
}
}