summaryrefslogtreecommitdiffstats
path: root/src/iter.rs
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2017-09-26 17:18:35 +0200
committerMatthias Beyer <mail@beyermatthias.de>2017-09-26 17:57:34 +0200
commit77c3f75343dc84b87e99e333bc15ea5c308fc017 (patch)
tree60f24189040620496cc91c366f3879588660f103 /src/iter.rs
parent694a9a4ecb4f743ab7958a66a042381a812ad156 (diff)
Add filter iterator
Diffstat (limited to 'src/iter.rs')
-rw-r--r--src/iter.rs77
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);
+ }
+}
+