diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-04-03 11:15:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-03 11:15:50 +0200 |
commit | b531c50e550d05c95ea02370ba02c0535a4ef5f5 (patch) | |
tree | bb805481e321e34f1ebeb8cd3a7fcdd4184c9f0d | |
parent | 9cc209fec50c1cdb3ca18761e00c902e8d281b96 (diff) | |
parent | b6470c179c0ed4a594d72914ec4b64828a409c13 (diff) |
Merge pull request #27 from matthiasbeyer/filter-result-iter
Add extension to filter Result<T, E> by predicate(&T)
-rw-r--r-- | src/iter.rs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/iter.rs b/src/iter.rs index 79675d1..e5acb6e 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -39,6 +39,88 @@ impl<I, T, F: Filter<T>> FilterWith<T, F> for I } } + +pub struct FilterOksIter<T, E, I, F>(I, F) + where F: Filter<T>, + I: Iterator<Item = Result<T, E>>; + +impl<T, E, I, F> Iterator for FilterOksIter<T, E, I, F> + where F: Filter<T>, + I: Iterator<Item = Result<T, E>> +{ + type Item = Result<T, E>; + + fn next(&mut self) -> Option<Self::Item> { + while let Some(next) = self.0.next() { + match next { + Err(e) => return Some(Err(e)), + Ok(t) => if self.1.filter(&t) { + return Some(Ok(t)); + } + } + } + + None + } +} + +pub trait FilterOks<T, E, I, F> : Iterator<Item = Result<T, E>> + where I: Iterator<Item = Result<T, E>>, + F: Filter<T> +{ + fn filter_oks(self, F) -> FilterOksIter<T, E, I, F>; +} + +impl<T, E, I, F> FilterOks<T, E, I, F> for I + where I: Iterator<Item = Result<T, E>>, + F: Filter<T> +{ + fn filter_oks(self, f: F) -> FilterOksIter<T, E, I, F> { + FilterOksIter(self, f) + } +} + +pub struct FilterErrIter<T, E, I, F>(I, F) + where F: Filter<E>, + I: Iterator<Item = Result<T, E>>; + +impl<T, E, I, F> Iterator for FilterErrIter<T, E, I, F> + where F: Filter<E>, + I: Iterator<Item = Result<T, E>> +{ + type Item = Result<T, E>; + + fn next(&mut self) -> Option<Self::Item> { + while let Some(next) = self.0.next() { + match next { + Ok(t) => return Some(Ok(t)), + Err(e) => if self.1.filter(&e) { + return Some(Err(e)); + } + } + } + + None + } +} + +pub trait FilterErr<T, E, I, F> : Iterator<Item = Result<T, E>> + where I: Iterator<Item = Result<T, E>>, + F: Filter<E> +{ + fn filter_errs(self, F) -> FilterErrIter<T, E, I, F>; +} + +impl<T, E, I, F> FilterErr<T, E, I, F> for I + where I: Iterator<Item = Result<T, E>>, + F: Filter<E> +{ + fn filter_errs(self, f: F) -> FilterErrIter<T, E, I, F> { + FilterErrIter(self, f) + } +} + + #[cfg(test)] mod test { use super::*; @@ -61,4 +143,45 @@ mod test { assert_eq!(v, vec![6, 7, 8, 9]); } + + #[test] + fn test_filter_oks() { + struct Foo; + impl Filter<u64> for Foo { + fn filter(&self, u: &u64) -> bool { + *u > 5 + } + } + + let foo = Foo; + + let v : Vec<Result<u64, u64>> = + vec![Ok(1), Err(2), Ok(3), Err(4), Ok(5), Err(6), Ok(7), Err(8), Ok(9), Err(0)] + .into_iter() + .filter_oks(foo) + .collect(); + + assert_eq!(v, vec![Err(2), Err(4), Err(6), Ok(7), Err(8), Ok(9), Err(0)]); + } + + #[test] + fn test_filter_errs() { + struct Foo; + impl Filter<u64> for Foo { + fn filter(&self, u: &u64) -> bool { + *u > 5 + } + } + + let foo = Foo; + + let v : Vec<Result<u64, u64>> = + vec![Ok(1), Err(2), Ok(3), Err(4), Ok(5), Err(6), Ok(7), Err(8), Ok(9), Err(0)] + .into_iter() + .filter_errs(foo) + .collect(); + + assert_eq!(v, vec![Ok(1), Ok(3), Ok(5), Err(6), Ok(7), Err(8), Ok(9)]); + } } + |