diff --git a/src/boolean.rs b/src/boolean.rs index 9ad83c7..fd594ae 100644 --- a/src/boolean.rs +++ b/src/boolean.rs @@ -8,40 +8,48 @@ //! Definition of boolean logic combinators over `Predicate`s. +use std::marker::PhantomData; + use Predicate; /// Predicate that combines two `Predicate`s, returning the AND of the results. /// /// This is created by the `Predicate::and` function. #[derive(Debug)] -pub struct AndPredicate +pub struct AndPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { a: M1, b: M2, + _phantom: PhantomData, } -impl AndPredicate +impl AndPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { /// Create a new `AndPredicate` over predicates `a` and `b`. - pub fn new(a: M1, b: M2) -> AndPredicate { - AndPredicate { a: a, b: b } + pub fn new(a: M1, b: M2) -> AndPredicate { + AndPredicate { + a: a, + b: b, + _phantom: PhantomData, + } } } -impl Predicate for AndPredicate +impl Predicate for AndPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { - type Item = M1::Item; - - fn eval(&self, item: &Self::Item) -> bool { + fn eval(&self, item: &Item) -> bool { self.a.eval(item) && self.b.eval(item) } } @@ -50,34 +58,40 @@ where /// /// This is created by the `Predicate::or` function. #[derive(Debug)] -pub struct OrPredicate +pub struct OrPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { a: M1, b: M2, + _phantom: PhantomData, } -impl OrPredicate +impl OrPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { /// Create a new `OrPredicate` over predicates `a` and `b`. - pub fn new(a: M1, b: M2) -> OrPredicate { - OrPredicate { a: a, b: b } + pub fn new(a: M1, b: M2) -> OrPredicate { + OrPredicate { + a: a, + b: b, + _phantom: PhantomData, + } } } -impl Predicate for OrPredicate +impl Predicate for OrPredicate where - M1: Predicate, - M2: Predicate, + M1: Predicate, + M2: Predicate, + Item: ?Sized, { - type Item = M1::Item; - - fn eval(&self, item: &Self::Item) -> bool { + fn eval(&self, item: &Item) -> bool { self.a.eval(item) || self.b.eval(item) } } @@ -86,30 +100,35 @@ where /// /// This is created by the `Predicate::not` function. #[derive(Debug)] -pub struct NotPredicate +pub struct NotPredicate where - M: Predicate, + M: Predicate, + Item: ?Sized, { inner: M, + _phantom: PhantomData, } -impl NotPredicate +impl NotPredicate where - M: Predicate, + M: Predicate, + Item: ?Sized, { /// Create a new `NotPredicate` over predicate `inner`. - pub fn new(inner: M) -> NotPredicate { - NotPredicate { inner: inner } + pub fn new(inner: M) -> NotPredicate { + NotPredicate { + inner: inner, + _phantom: PhantomData, + } } } -impl Predicate for NotPredicate +impl Predicate for NotPredicate where - M: Predicate, + M: Predicate, + Item: ?Sized, { - type Item = M::Item; - - fn eval(&self, item: &Self::Item) -> bool { + fn eval(&self, item: &Item) -> bool { !self.inner.eval(item) } } diff --git a/src/boxed.rs b/src/boxed.rs index 7fce269..a7a1637 100644 --- a/src/boxed.rs +++ b/src/boxed.rs @@ -15,35 +15,45 @@ use Predicate; /// `Predicate` that wraps another `Predicate` as a trait object, allowing /// sized storage of predicate types. -pub struct BoxPredicate(Box + Send + Sync>); +pub struct BoxPredicate(Box + Send + Sync>); -impl fmt::Debug for BoxPredicate { +impl BoxPredicate +where + Item: ?Sized, +{ + /// Creates a new `BoxPredicate`, a wrapper around a dynamically-dispatched + /// `Predicate` type with useful trait impls. + pub fn new>(inner: P) -> BoxPredicate + where + P: Send + Sync + 'static, + { + BoxPredicate(Box::new(inner)) + } +} + +impl fmt::Debug for BoxPredicate +where + Item: ?Sized, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("BoxPredicate").finish() } } -impl fmt::Display for BoxPredicate { +impl fmt::Display for BoxPredicate +where + Item: ?Sized, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "BoxPredicate") } } -impl Predicate for BoxPredicate { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { +impl Predicate for BoxPredicate +where + Item: ?Sized, +{ + fn eval(&self, variable: &Item) -> bool { self.0.eval(variable) } } - -impl BoxPredicate { - /// Creates a new `BoxPredicate`, a wrapper around a dynamically-dispatched - /// `Predicate` type with useful trait impls. - pub fn new>(inner: P) -> BoxPredicate - where - P: Send + Sync + 'static, - { - BoxPredicate(Box::new(inner)) - } -} diff --git a/src/constant.rs b/src/constant.rs index 6099245..d4bc911 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -16,15 +16,13 @@ use Predicate; /// /// This is created by the `predicate::always` and `predicate::never` functions. #[derive(Debug)] -pub struct BooleanPredicate { +pub struct BooleanPredicate { retval: bool, - _phantom: PhantomData, + _phantom: PhantomData, } -impl Predicate for BooleanPredicate { - type Item = T; - - fn eval(&self, _variable: &T) -> bool { +impl Predicate for BooleanPredicate { + fn eval(&self, _variable: &Item) -> bool { self.retval } } @@ -43,7 +41,7 @@ impl Predicate for BooleanPredicate { /// // Won't work - Predicates can only operate on a single type /// // assert_eq!(true, predicate_fn.eval("hello")) /// ``` -pub fn always() -> BooleanPredicate { +pub fn always() -> BooleanPredicate { BooleanPredicate { retval: true, _phantom: PhantomData, @@ -64,7 +62,7 @@ pub fn always() -> BooleanPredicate { /// // Won't work - Predicates can only operate on a single type /// // assert_eq!(false, predicate_fn.eval("hello")) /// ``` -pub fn never() -> BooleanPredicate { +pub fn never() -> BooleanPredicate { BooleanPredicate { retval: false, _phantom: PhantomData, diff --git a/src/core.rs b/src/core.rs index 85152ea..96a6800 100644 --- a/src/core.rs +++ b/src/core.rs @@ -16,13 +16,10 @@ use boxed::BoxPredicate; /// mean that the evaluated item is in some sort of pre-defined set. This is /// different from `Ord` and `Eq` in that an `item` will almost never be the /// same type as the implementing `Predicate` type. -pub trait Predicate { - /// The type that this `Predicate` will accept for evaluating. - type Item: ?Sized; - +pub trait Predicate { /// Execute this `Predicate` against `variable`, returning the resulting /// boolean. - fn eval(&self, variable: &Self::Item) -> bool; + fn eval(&self, variable: &Item) -> bool; /// Compute the logical AND of two `Predicate` results, returning the result. /// @@ -35,9 +32,9 @@ pub trait Predicate { /// let predicate_fn2 = predicate::always().and(predicate::never()); /// assert_eq!(true, predicate_fn1.eval(&4)); /// assert_eq!(false, predicate_fn2.eval(&4)); - fn and(self, other: B) -> AndPredicate + fn and(self, other: B) -> AndPredicate where - B: Predicate, + B: Predicate, Self: Sized, { AndPredicate::new(self, other) @@ -56,9 +53,9 @@ pub trait Predicate { /// assert_eq!(true, predicate_fn1.eval(&4)); /// assert_eq!(true, predicate_fn2.eval(&4)); /// assert_eq!(false, predicate_fn3.eval(&4)); - fn or(self, other: B) -> OrPredicate + fn or(self, other: B) -> OrPredicate where - B: Predicate, + B: Predicate, Self: Sized, { OrPredicate::new(self, other) @@ -75,7 +72,7 @@ pub trait Predicate { /// let predicate_fn2 = predicate::never().not(); /// assert_eq!(false, predicate_fn1.eval(&4)); /// assert_eq!(true, predicate_fn2.eval(&4)); - fn not(self) -> NotPredicate + fn not(self) -> NotPredicate where Self: Sized, { @@ -106,7 +103,7 @@ pub trait Predicate { /// assert_eq!(true, predicates[0].eval(&4)); /// assert_eq!(false, predicates[1].eval(&4)); /// ``` - fn boxed(self) -> BoxPredicate + fn boxed(self) -> BoxPredicate where Self: Sized + Send + Sync + 'static, { diff --git a/src/float/close.rs b/src/float/close.rs index 3b5040f..bfc5e76 100644 --- a/src/float/close.rs +++ b/src/float/close.rs @@ -78,9 +78,7 @@ impl IsClosePredicate { } } -impl Predicate for IsClosePredicate { - type Item = f64; - +impl Predicate for IsClosePredicate { fn eval(&self, variable: &f64) -> bool { variable.approx_eq(&self.target, self.epsilon, self.ulps) } diff --git a/src/function.rs b/src/function.rs index bd21745..ff20a1c 100644 --- a/src/function.rs +++ b/src/function.rs @@ -23,12 +23,10 @@ where _phantom: PhantomData, } -impl Predicate for FnPredicate +impl Predicate for FnPredicate where F: Fn(&T) -> bool, { - type Item = T; - fn eval(&self, variable: &T) -> bool { (self.function)(variable) } diff --git a/src/lib.rs b/src/lib.rs index e8d153f..57381b3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,9 +62,8 @@ //! // returns a `bool`. Implementing a custom `Predicate` still allows all the //! // usual combinators of the `Predicate` trait to work! //! struct IsTheAnswer; -//! impl Predicate for IsTheAnswer { -//! type Item = i32; -//! fn eval(&self, variable: &Self::Item) -> bool { +//! impl Predicate for IsTheAnswer { +//! fn eval(&self, variable: &i32) -> bool { //! *variable == 42 //! } //! } diff --git a/src/ord.rs b/src/ord.rs index 686c5dc..df5b37c 100644 --- a/src/ord.rs +++ b/src/ord.rs @@ -26,13 +26,11 @@ pub struct EqPredicate { op: EqOps, } -impl Predicate for EqPredicate +impl Predicate for EqPredicate where T: PartialEq, { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { + fn eval(&self, variable: &T) -> bool { match self.op { EqOps::Equal => variable.eq(&self.constant), EqOps::NotEqual => variable.ne(&self.constant), @@ -102,13 +100,11 @@ pub struct OrdPredicate { op: OrdOps, } -impl Predicate for OrdPredicate +impl Predicate for OrdPredicate where T: PartialOrd, { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { + fn eval(&self, variable: &T) -> bool { match self.op { OrdOps::LessThan => variable.lt(&self.constant), OrdOps::LessThanOrEqual => variable.le(&self.constant), diff --git a/src/path/existence.rs b/src/path/existence.rs index 7a4bc43..518e01d 100644 --- a/src/path/existence.rs +++ b/src/path/existence.rs @@ -18,9 +18,7 @@ pub struct ExistencePredicate { exists: bool, } -impl Predicate for ExistencePredicate { - type Item = path::Path; - +impl Predicate for ExistencePredicate { fn eval(&self, path: &path::Path) -> bool { path.exists() == self.exists } diff --git a/src/path/ft.rs b/src/path/ft.rs index c101b66..7588df2 100644 --- a/src/path/ft.rs +++ b/src/path/ft.rs @@ -49,9 +49,7 @@ impl FileTypePredicate { } } -impl Predicate for FileTypePredicate { - type Item = path::Path; - +impl Predicate for FileTypePredicate { fn eval(&self, path: &path::Path) -> bool { let metadata = if self.follow { path.metadata() diff --git a/src/set.rs b/src/set.rs index 4e67d46..4d34208 100644 --- a/src/set.rs +++ b/src/set.rs @@ -31,13 +31,11 @@ where inner: Vec, } -impl Predicate for ContainsPredicate +impl Predicate for ContainsPredicate where T: PartialEq, { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { + fn eval(&self, variable: &T) -> bool { self.inner.contains(variable) } } @@ -91,13 +89,11 @@ where inner: Vec, } -impl Predicate for OrdContainsPredicate +impl Predicate for OrdContainsPredicate where T: Ord, { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { + fn eval(&self, variable: &T) -> bool { self.inner.binary_search(variable).is_ok() } } @@ -149,13 +145,11 @@ where inner: HashSet, } -impl Predicate for HashableContainsPredicate +impl Predicate for HashableContainsPredicate where T: Hash + Eq, { - type Item = T; - - fn eval(&self, variable: &Self::Item) -> bool { + fn eval(&self, variable: &T) -> bool { self.inner.contains(variable) } } diff --git a/src/str/difference.rs b/src/str/difference.rs index 48c0950..178ed21 100644 --- a/src/str/difference.rs +++ b/src/str/difference.rs @@ -84,9 +84,7 @@ impl DifferencePredicate { } } -impl Predicate for DifferencePredicate { - type Item = str; - +impl Predicate for DifferencePredicate { fn eval(&self, edit: &str) -> bool { let change = difference::Changeset::new(&self.orig, edit, &self.split); self.op.eval(self.distance, change.distance) diff --git a/src/str/regex.rs b/src/str/regex.rs index 4d84403..978c45d 100644 --- a/src/str/regex.rs +++ b/src/str/regex.rs @@ -21,9 +21,7 @@ pub struct RegexPredicate { re: regex::Regex, } -impl Predicate for RegexPredicate { - type Item = str; - +impl Predicate for RegexPredicate { fn eval(&self, variable: &str) -> bool { self.re.is_match(variable) }