diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2017-09-26 17:18:35 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2017-09-26 17:57:34 +0200 |
commit | 77c3f75343dc84b87e99e333bc15ea5c308fc017 (patch) | |
tree | 60f24189040620496cc91c366f3879588660f103 | |
parent | 694a9a4ecb4f743ab7958a66a042381a812ad156 (diff) |
Add filter iterator
-rw-r--r-- | src/iter.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/iter.rs b/src/iter.rs index 821c9db..7e53da4 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -7,6 +7,7 @@ use error::KairosError as KE; use error::KairosErrorKind as KEK; use error::Result; use timetype::TimeType; +use matcher::Matcher; pub struct Iter { base: TimeType, @@ -105,6 +106,53 @@ impl<I> IntoCalculatingIter for I } } +pub struct FilterIter<I, M>(I, M) + where I: Iterator<Item = Result<TimeType>>, + M: Matcher; + +impl<I, M> FilterIter<I, M> + where I: Iterator<Item = Result<TimeType>>, + M: Matcher +{ + fn new(i: I, m: M) -> FilterIter<I, M> { + FilterIter(i, m) + } +} + +impl<I, M> Iterator for FilterIter<I, M> + where I: Iterator<Item = Result<TimeType>>, + M: Matcher +{ + type Item = Result<TimeType>; + + fn next(&mut self) -> Option<Self::Item> { + loop { + match self.0.next() { + None => return None, + Some(Err(e)) => return Some(Err(e)), + Some(Ok(tt)) => match self.1.matches(&tt) { + Ok(false) => continue, + Ok(true) => return Some(Ok(tt)), + Err(e) => return Some(Err(e)), + } + } + } + } +} + +pub trait EveryFilter<M: Matcher> : Iterator<Item = Result<TimeType>> + Sized { + fn every(self, M) -> FilterIter<Self, M>; +} + +impl<I, M> EveryFilter<M> for I + where I: Iterator<Item = Result<TimeType>>, + M: Matcher +{ + fn every(self, matcher: M) -> FilterIter<Self, M> { + FilterIter::new(self, matcher) + } +} + pub mod extensions { use timetype::TimeType as TT; use super::Iter; @@ -335,3 +383,32 @@ pub mod extensions { } } + +#[cfg(test)] +mod type_tests { + use super::*; + use super::IntoCalculatingIter; + use super::extensions::*; + + #[test] + fn test_iterator_every_once() { + // This test is solely to check whether this compiles and the API is nice + let _ = TimeType::today() + .yearly(1) + .unwrap() + .calculate() + .every(::indicator::Day::Monday); + } + + #[test] + fn test_iterator_every_twice() { + // This test is solely to check whether this compiles and the API is nice + let _ = TimeType::today() + .yearly(1) // collecting makes us stack-overflow because of the heavy filtering! + .unwrap() + .calculate() + .every(::indicator::Day::Monday) + .every(::indicator::Month::January); + } +} + |