summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-04-03 11:15:50 +0200
committerGitHub <noreply@github.com>2018-04-03 11:15:50 +0200
commitb531c50e550d05c95ea02370ba02c0535a4ef5f5 (patch)
treebb805481e321e34f1ebeb8cd3a7fcdd4184c9f0d
parent9cc209fec50c1cdb3ca18761e00c902e8d281b96 (diff)
parentb6470c179c0ed4a594d72914ec4b64828a409c13 (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.rs123
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)]);
+ }
}
+