diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2017-11-11 11:19:42 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2017-11-19 14:00:24 +0100 |
commit | c1a9ab6a43d14b007f9787d9eb48752b13ac7dc4 (patch) | |
tree | bb48d5ecbba45f70e9aad2c16dafac85d776070f /src | |
parent | 3a4f59eafe6e8a4e00d0a3aa0fe1853a3351adaa (diff) |
Add parser iterator type -> API iterator type mapping
Diffstat (limited to 'src')
-rw-r--r-- | src/iter.rs | 5 | ||||
-rw-r--r-- | src/parser.rs | 88 |
2 files changed, 87 insertions, 6 deletions
diff --git a/src/iter.rs b/src/iter.rs index 7399de5..05669c2 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -9,6 +9,7 @@ use error::Result; use timetype::TimeType; use matcher::Matcher; +#[derive(Debug)] pub struct Iter { base: TimeType, increment: TimeType, @@ -80,6 +81,7 @@ impl Iterator for Iter { } +#[derive(Debug)] pub struct FilterIter<I, M>(I, M) where I: Iterator<Item = Result<TimeType>>, M: Matcher; @@ -127,6 +129,7 @@ impl<I, M> EveryFilter<M> for I } } +#[derive(Debug)] pub struct WithoutIter<I, M>(I, M) where I: Iterator<Item = Result<TimeType>>, M: Matcher; @@ -174,6 +177,7 @@ impl<I, M> WithoutFilter<M> for I } } +#[derive(Debug)] pub struct UntilIter<I>(I, NaiveDateTime) where I: Iterator<Item = Result<TimeType>>; @@ -222,6 +226,7 @@ impl<I> Until for I } } +#[derive(Debug)] pub struct TimesIter<I> where I: Iterator<Item = Result<TimeType>> { diff --git a/src/parser.rs b/src/parser.rs index 7a2e7a1..80ff151 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -50,6 +50,8 @@ use std::str::FromStr; use chrono::NaiveDate; use timetype; +use iter; +use error; named!(integer<i64>, alt!( map_res!( @@ -345,18 +347,92 @@ pub enum UntilSpec { } named!(iterator<Iterator>, do_parse!( - d: date >> - spec: iter_spec >> - until: opt!(until_spec) >> + opt!(sp) >> d: date >> + opt!(sp) >> spec: iter_spec >> + opt!(sp) >> until: opt!(complete!(until_spec)) >> (Iterator(d, spec, until)) )); #[derive(Debug, PartialEq, Eq)] pub struct Iterator(Date, Iterspec, Option<UntilSpec>); -impl Into<timetype::TimeType> for Iterator { - fn into(self) -> timetype::TimeType { - unimplemented!() +impl Iterator { + pub fn into_user_iterator(self) -> error::Result<UserIterator<iter::Iter>> { + use iter::Times; + use iter::Until; + + let unit_to_amount = |i, unit| match unit { + Unit::Second => timetype::TimeType::seconds(i), + Unit::Minute => timetype::TimeType::minutes(i), + Unit::Hour => timetype::TimeType::hours(i), + Unit::Day => timetype::TimeType::days(i), + Unit::Week => timetype::TimeType::weeks(i), + Unit::Month => timetype::TimeType::months(i), + Unit::Year => timetype::TimeType::years(i), + }; + + let recur = match self.1 { + Iterspec::Every(i, unit) => unit_to_amount(i, unit), + Iterspec::Secondly => unit_to_amount(1, Unit::Second), + Iterspec::Minutely => unit_to_amount(1, Unit::Minute), + Iterspec::Hourly => unit_to_amount(1, Unit::Hour), + Iterspec::Daily => unit_to_amount(1, Unit::Day), + Iterspec::Weekly => unit_to_amount(1, Unit::Week), + Iterspec::Monthly => unit_to_amount(1, Unit::Month), + Iterspec::Yearly => unit_to_amount(1, Unit::Year), + }; + + let into_ndt = |e: timetype::TimeType| try!(e.calculate()) + .get_moment() + .ok_or(error::KairosErrorKind::NotADateInsideIterator) + .map(Clone::clone); + + match self.2 { + Some(UntilSpec::Exact(e)) => { + let base = try!(into_ndt(self.0.into())); + let e = try!(into_ndt(e.into())); + + iter::Iter::build(base, recur) + .map(|it| UserIterator::UntilIterator(it.until(e))) + }, + + Some(UntilSpec::Times(i)) => { + let base = try!(into_ndt(self.0.into())); + iter::Iter::build(base, recur) + .map(|it| it.times(i)) + .map(UserIterator::TimesIter) + }, + + None => { + let base = try!(into_ndt(self.0.into())); + iter::Iter::build(base, recur) + .map(UserIterator::Iterator) + }, + } + } +} + +// names are hard +#[derive(Debug)] +pub enum UserIterator<I> + where I: ::std::iter::Iterator<Item = error::Result<timetype::TimeType>> +{ + Iterator(iter::Iter), + TimesIter(iter::TimesIter<I>), + UntilIterator(iter::UntilIter<I>) +} + +impl<I> ::std::iter::Iterator for UserIterator<I> + where I: ::std::iter::Iterator<Item = error::Result<timetype::TimeType>> +{ + type Item = error::Result<timetype::TimeType>; + + fn next(&mut self) -> Option<Self::Item> { + match *self { + UserIterator::Iterator(ref mut i) => i.next(), + UserIterator::TimesIter(ref mut i) => i.next(), + UserIterator::UntilIterator(ref mut i) => i.next(), + } } } |