diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-04-29 10:42:30 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2018-04-29 10:48:28 +0200 |
commit | 68df53a1467f0dd9c37114cdb7980783fb1fa3a0 (patch) | |
tree | 32213b67883891866a51c38f17e4ff46e26e2d9a | |
parent | b531c50e550d05c95ea02370ba02c0535a4ef5f5 (diff) |
Make error type associated
The problem with the FailingFilter was, that the error type was not an
associated type but a generic type parameter.
This patch fixes this.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/failable/filter.rs | 40 | ||||
-rw-r--r-- | src/failable/ops/and.rs | 10 | ||||
-rw-r--r-- | src/failable/ops/bool.rs | 6 | ||||
-rw-r--r-- | src/failable/ops/map.rs | 26 | ||||
-rw-r--r-- | src/failable/ops/not.rs | 8 | ||||
-rw-r--r-- | src/failable/ops/or.rs | 10 | ||||
-rw-r--r-- | src/failable/ops/xor.rs | 10 | ||||
-rw-r--r-- | src/filter.rs | 4 | ||||
-rw-r--r-- | src/ops/failable.rs | 29 |
10 files changed, 84 insertions, 60 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 21c6414..dff90ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * A macro was added to quickly create `Filter` implementations * An extension for iterators was added to filter the iterator with the filter object. This removes the need to write a closure. +* `FailableFilter` uses an associated type for the error output type now. # 0.2.0 diff --git a/src/failable/filter.rs b/src/failable/filter.rs index 050084c..36440fe 100644 --- a/src/failable/filter.rs +++ b/src/failable/filter.rs @@ -14,14 +14,14 @@ pub use failable::ops::or::FailableOr; pub use failable::ops::map::{FailableMapInput, FailableMapErr}; /// Trait for converting something into a Filter -pub trait IntoFailableFilter<N, E: Sized> { - type IntoFilt: FailableFilter<N, E>; +pub trait IntoFailableFilter<N> { + type IntoFilt: FailableFilter<N>; fn into_failable_filter(self) -> Self::IntoFilt; } /// All Filters can be turned into Filters -impl<N, E: Sized, I: FailableFilter<N, E>> IntoFailableFilter<N, E> for I { +impl<N, I: FailableFilter<N>> IntoFailableFilter<N> for I { type IntoFilt = I; fn into_failable_filter(self) -> Self::IntoFilt { @@ -29,9 +29,11 @@ impl<N, E: Sized, I: FailableFilter<N, E>> IntoFailableFilter<N, E> for I { } } -pub trait FailableFilter<N, E> { +pub trait FailableFilter<N> { + type Error: Sized; + /// The function which is used to filter something - fn filter(&self, &N) -> Result<bool, E>; + fn filter(&self, &N) -> Result<bool, Self::Error>; /// Helper to invert a filter. /// @@ -69,7 +71,7 @@ pub trait FailableFilter<N, E> { /// ``` fn or<F>(self, other: F) -> FailableOr<Self, F::IntoFilt> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized + F: IntoFailableFilter<N> + Sized { FailableOr::new(self, other.into_failable_filter()) } @@ -92,7 +94,7 @@ pub trait FailableFilter<N, E> { /// ``` fn or_not<F>(self, other: F) -> FailableOr<Self, FailableNot<F::IntoFilt>> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized, + F: IntoFailableFilter<N> + Sized, { self.or(FailableNot::new(other.into_failable_filter())) } @@ -117,8 +119,8 @@ pub trait FailableFilter<N, E> { /// ``` fn or3<F, F2>(self, other: F, other2: F2) -> FailableOr<Self, FailableOr<F::IntoFilt, F2::IntoFilt>> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized, - F2: IntoFailableFilter<N, E> + Sized + F: IntoFailableFilter<N> + Sized, + F2: IntoFailableFilter<N> + Sized { FailableOr::new(self, FailableOr::new(other.into_failable_filter(), other2.into_failable_filter())) } @@ -190,7 +192,7 @@ pub trait FailableFilter<N, E> { /// ``` fn and<F>(self, other: F) -> FailableAnd<Self, F::IntoFilt> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized + F: IntoFailableFilter<N> + Sized { FailableAnd::new(self, other.into_failable_filter()) } @@ -218,8 +220,8 @@ pub trait FailableFilter<N, E> { /// ``` fn and3<F, F2>(self, other: F, other2: F2) -> FailableAnd<Self, FailableAnd<F::IntoFilt, F2::IntoFilt>> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized, - F2: IntoFailableFilter<N, E> + Sized + F: IntoFailableFilter<N> + Sized, + F2: IntoFailableFilter<N> + Sized { FailableAnd::new(self, FailableAnd::new(other.into_failable_filter(), other2.into_failable_filter())) } @@ -246,7 +248,7 @@ pub trait FailableFilter<N, E> { /// ``` fn and_not<F>(self, other: F) -> FailableAnd<Self, FailableNot<F::IntoFilt>> where Self: Sized, - F: IntoFailableFilter<N, E> + Sized + F: IntoFailableFilter<N> + Sized { self.and(FailableNot::new(other.into_failable_filter())) } @@ -324,9 +326,9 @@ pub trait FailableFilter<N, E> { /// assert!(c.filter(&6).unwrap()); /// assert!(!c.filter(&9).unwrap()); /// ``` - fn map_err<M, OE>(self, map: M) -> FailableMapErr<Self, M, E, OE> + fn map_err<M, OE>(self, map: M) -> FailableMapErr<Self, M, OE> where Self: Sized, - M: Fn(E) -> OE + M: Fn(Self::Error) -> OE { FailableMapErr::new(self, map) } @@ -334,8 +336,12 @@ pub trait FailableFilter<N, E> { } /// All closures that take a ref to something and return Result<bool, E> are failable filters -impl<I, E, T: Fn(&I) -> Result<bool, E>> FailableFilter<I, E> for T { - fn filter(&self, other: &I) -> Result<bool, E>{ +impl<I, E, T> FailableFilter<I> for T + where T: Fn(&I) -> Result<bool, E> +{ + type Error = E; + + fn filter(&self, other: &I) -> Result<bool, Self::Error> { self(other) } } diff --git a/src/failable/ops/and.rs b/src/failable/ops/and.rs index 1d195a6..4568b71 100644 --- a/src/failable/ops/and.rs +++ b/src/failable/ops/and.rs @@ -24,11 +24,13 @@ impl<T, U> FailableAnd<T, U> { } -impl<N, E, T, U> FailableFilter<N, E> for FailableAnd<T, U> - where T: FailableFilter<N, E>, - U: FailableFilter<N, E> +impl<N, T, U, E> FailableFilter<N> for FailableAnd<T, U> + where T: FailableFilter<N, Error = E>, + U: FailableFilter<N, Error = E> { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = E; + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { Ok(try!(self.0.filter(e)) && try!(self.1.filter(e))) } } diff --git a/src/failable/ops/bool.rs b/src/failable/ops/bool.rs index 82c0ac9..ad68f63 100644 --- a/src/failable/ops/bool.rs +++ b/src/failable/ops/bool.rs @@ -32,8 +32,10 @@ impl From<bool> for FailableBool { } -impl<N, E> FailableFilter<N, E> for FailableBool { - fn filter(&self, _: &N) -> Result<bool, E> { +impl<N> FailableFilter<N> for FailableBool { + type Error = (); + + fn filter(&self, _: &N) -> Result<bool, Self::Error> { Ok(self.0) } } diff --git a/src/failable/ops/map.rs b/src/failable/ops/map.rs index ccec3d3..8dd3cc5 100644 --- a/src/failable/ops/map.rs +++ b/src/failable/ops/map.rs @@ -24,31 +24,35 @@ impl<F, M, FT, B> FailableMapInput<F, M, FT, B> { } } -impl<FT, E, F, T, B, M> FailableFilter<T, E> for FailableMapInput<F, M, FT, B> - where F: FailableFilter<FT, E>, +impl<FT, F, T, B, M> FailableFilter<T> for FailableMapInput<F, M, FT, B> + where F: FailableFilter<FT>, B: Borrow<FT> + Sized, M: Fn(&T) -> B { - fn filter(&self, e: &T) -> Result<bool, E> { + type Error = F::Error; + + fn filter(&self, e: &T) -> Result<bool, Self::Error> { self.0.filter(self.1(e).borrow()) } } #[must_use = "filters are lazy and do nothing unless consumed"] #[derive(Clone)] -pub struct FailableMapErr<F, M, FE, E>(F, M, PhantomData<FE>, PhantomData<E>); +pub struct FailableMapErr<F, M, E>(F, M, PhantomData<E>); -impl<F, M, FE, E> FailableMapErr<F, M, FE, E> { - pub fn new(a: F, m: M) -> FailableMapErr<F, M, FE, E> { - FailableMapErr(a, m, PhantomData, PhantomData) +impl<F, M, E> FailableMapErr<F, M, E> { + pub fn new(a: F, m: M) -> FailableMapErr<F, M, E> { + FailableMapErr(a, m, PhantomData) } } -impl<FE, E, F, T, M> FailableFilter<T, E> for FailableMapErr<F, M, FE, E> - where F: FailableFilter<T, FE>, - M: Fn(FE) -> E +impl<E, F, T, M> FailableFilter<T> for FailableMapErr<F, M, E> + where F: FailableFilter<T>, + M: Fn(F::Error) -> E { - fn filter(&self, e: &T) -> Result<bool, E> { + type Error = E; + + fn filter(&self, e: &T) -> Result<bool, Self::Error> { self.0.filter(e).map_err(&self.1) } } diff --git a/src/failable/ops/not.rs b/src/failable/ops/not.rs index 25c3e3b..bc55230 100644 --- a/src/failable/ops/not.rs +++ b/src/failable/ops/not.rs @@ -24,10 +24,12 @@ impl<T> FailableNot<T> { } -impl<N, E, T> FailableFilter<N, E> for FailableNot<T> - where T: FailableFilter<N, E> +impl<N, T> FailableFilter<N> for FailableNot<T> + where T: FailableFilter<N> { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = T::Error; + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { self.0.filter(e).map(|b| !b) } } diff --git a/src/failable/ops/or.rs b/src/failable/ops/or.rs index 45289c3..b482e63 100644 --- a/src/failable/ops/or.rs +++ b/src/failable/ops/or.rs @@ -24,11 +24,13 @@ impl<T, U> FailableOr<T, U> { } -impl<N, E, T, U> FailableFilter<N, E> for FailableOr<T, U> - where T: FailableFilter<N, E>, - U: FailableFilter<N, E> +impl<N, T, U, E> FailableFilter<N> for FailableOr<T, U> + where T: FailableFilter<N, Error = E>, + U: FailableFilter<N, Error = E> { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = E; + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { Ok(try!(self.0.filter(e)) || try!(self.1.filter(e))) } } diff --git a/src/failable/ops/xor.rs b/src/failable/ops/xor.rs index ecc38ce..9ccfd8e 100644 --- a/src/failable/ops/xor.rs +++ b/src/failable/ops/xor.rs @@ -24,11 +24,13 @@ impl<T, U> FailableXOr<T, U> { } -impl<N, E, T, U> FailableFilter<N, E> for FailableXOr<T, U> - where T: FailableFilter<N, E>, - U: FailableFilter<N, E> +impl<N, T, U, E> FailableFilter<N> for FailableXOr<T, U> + where T: FailableFilter<N, Error = E>, + U: FailableFilter<N, Error = E> { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = E; + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { Ok(try!(self.0.filter(e)) ^ try!(self.1.filter(e))) } } diff --git a/src/filter.rs b/src/filter.rs index 33d1511..5c33160 100644 --- a/src/filter.rs +++ b/src/filter.rs @@ -297,7 +297,7 @@ pub trait Filter<N> { /// assert_eq!(a.filter(&7), Ok(true)); /// assert_eq!(a.filter(&9), Ok(true)); /// ``` - fn into_failable(self) -> IntoFailable<Self, ()> + fn into_failable(self) -> IntoFailable<Self> where Self: Sized { IntoFailable::new(self) @@ -316,7 +316,7 @@ pub trait Filter<N> { /// assert_eq!(b.filter(&3), Ok(false)); /// assert_eq!(a.filter(&7), true); /// assert_eq!(b.filter(&7), Ok(true)); - fn as_failable<'a>(&'a self) -> AsFailable<'a, Self, ()> + fn as_failable<'a>(&'a self) -> AsFailable<'a, Self> where Self: 'a { AsFailable::new(self) diff --git a/src/ops/failable.rs b/src/ops/failable.rs index a3277dc..1b4ca22 100644 --- a/src/ops/failable.rs +++ b/src/ops/failable.rs @@ -9,43 +9,46 @@ //! Will be automatically included when including `filter::Filter`, so importing this module //! shouldn't be necessary. //! -use std::marker::PhantomData; use filter::Filter; use failable::filter::FailableFilter; #[must_use = "filters are lazy and do nothing unless consumed"] #[derive(Clone)] -pub struct IntoFailable<F, E>(F, PhantomData<E>); +pub struct IntoFailable<F>(F); -impl<F, E> IntoFailable<F, E> { - pub fn new(a: F) -> IntoFailable<F, E> { - IntoFailable(a, PhantomData) +impl<F> IntoFailable<F> { + pub fn new(a: F) -> IntoFailable<F> { + IntoFailable(a) } } -impl<F, N, E> FailableFilter<N, E> for IntoFailable<F, E> +impl<F, N> FailableFilter<N> for IntoFailable<F> where F: Filter<N>, { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = (); + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { Ok(self.0.filter(e)) } } #[must_use = "filters are lazy and do nothing unless consumed"] #[derive(Clone)] -pub struct AsFailable<'a, F: 'a + ?Sized, E>(&'a F, PhantomData<E>); +pub struct AsFailable<'a, F: 'a + ?Sized>(&'a F); -impl<'a, F: 'a + ?Sized, E> AsFailable<'a, F, E> { - pub fn new(a: &'a F) -> AsFailable<F, E> { - AsFailable(a, PhantomData) +impl<'a, F: 'a + ?Sized> AsFailable<'a, F> { + pub fn new(a: &'a F) -> AsFailable<F> { + AsFailable(a) } } -impl<'a, F, N, E> FailableFilter<N, E> for AsFailable<'a, F, E> +impl<'a, F, N> FailableFilter<N> for AsFailable<'a, F> where F: Filter<N> + 'a + ?Sized, { - fn filter(&self, e: &N) -> Result<bool, E> { + type Error = (); + + fn filter(&self, e: &N) -> Result<bool, Self::Error> { Ok(self.0.filter(e)) } } |