summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2017-09-25 16:48:14 +0200
committerMatthias Beyer <mail@beyermatthias.de>2017-09-25 16:48:14 +0200
commit79923c0cd6ed917b3b0463a66d0a44df85165e23 (patch)
treef97e19962d2a2fb87dc56533478f5e8e25181d7c
parent7a2a81e06b23d7c5607c3bfda608ab49782f0827 (diff)
parent7bc13877435e1d369cf8e8b361103164422030a5 (diff)
Merge branch 'iter'
-rw-r--r--src/iter.rs229
-rw-r--r--src/timetype.rs52
2 files changed, 237 insertions, 44 deletions
diff --git a/src/iter.rs b/src/iter.rs
index 0faceec..4bfc2ca 100644
--- a/src/iter.rs
+++ b/src/iter.rs
@@ -93,3 +93,232 @@ impl<I: Iterator<Item = TimeType>> Iterator for CalculatingIter<I> {
}
+pub mod extensions {
+ use timetype::TimeType as TT;
+ use super::Iter;
+ use error::Result;
+ use error::KairosError as KE;
+ use error::KairosErrorKind as KEK;
+
+ pub trait Minutely {
+ fn minutely(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Hourly {
+ fn hourly(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Daily {
+ fn daily(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Weekly : Sized {
+ fn weekly(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Monthly {
+ fn monthly(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Yearly {
+ fn yearly(self, i: i64) -> Result<Iter>;
+ }
+
+ pub trait Every {
+ fn every(self, inc: TT) -> Result<Iter>;
+ }
+
+ impl Minutely for TT {
+
+ fn minutely(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::minutes(i);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+ impl Hourly for TT {
+
+ fn hourly(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::hours(i);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+ impl Daily for TT {
+
+ fn daily(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::days(i);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+ impl Weekly for TT {
+
+ /// Conveniance function over `Daily::daily( n * 7 )`
+ fn weekly(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::days(i * 7);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+ impl Monthly for TT {
+
+ fn monthly(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::months(i);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+ impl Yearly for TT {
+
+ fn yearly(self, i: i64) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => {
+ let increment = TT::years(i);
+ assert!(increment.is_a_amount(), "This is a Bug, please report this!");
+ Iter::build(mom, increment)
+ },
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+
+ }
+
+
+ impl Every for TT {
+ fn every(self, inc: TT) -> Result<Iter> {
+ match self {
+ TT::Moment(mom) => Iter::build(mom, inc),
+ _ => Err(KE::from_kind(KEK::ArgumentErrorNotAnAmount(self))),
+ }
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use super::*;
+ use timetype::TimeType as TT;
+ use chrono::NaiveDate as ND;
+
+ fn ymd_hms(y: i32, m: u32, d: u32, h: u32, mi: u32, s: u32) -> TT {
+ TT::moment(ND::from_ymd(y, m, d).and_hms(h, mi, s))
+ }
+
+ #[test]
+ fn test_minutely() {
+ let minutes = ymd_hms(2000, 1, 1, 0, 0, 0)
+ .minutely(1)
+ .unwrap()
+ .calculate()
+ .take(5)
+ .collect::<Vec<_>>();
+
+ assert_eq!(ymd_hms(2000, 1, 1, 0, 1, 0), *minutes[0].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 0, 2, 0), *minutes[1].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 0, 3, 0), *minutes[2].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 0, 4, 0), *minutes[3].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 0, 5, 0), *minutes[4].as_ref().unwrap());
+ }
+
+ #[test]
+ fn test_hourly() {
+ let minutes = ymd_hms(2000, 1, 1, 0, 0, 0)
+ .hourly(1)
+ .unwrap()
+ .calculate()
+ .take(5)
+ .collect::<Vec<_>>();
+
+ assert_eq!(ymd_hms(2000, 1, 1, 1, 0, 0), *minutes[0].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 2, 0, 0), *minutes[1].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 3, 0, 0), *minutes[2].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 4, 0, 0), *minutes[3].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1, 1, 5, 0, 0), *minutes[4].as_ref().unwrap());
+ }
+
+ #[test]
+ fn test_weekly() {
+ let minutes = ymd_hms(2000, 1, 1, 1, 0, 0)
+ .weekly(1)
+ .unwrap()
+ .calculate()
+ .take(5)
+ .collect::<Vec<_>>();
+
+ assert_eq!(ymd_hms(2000, 1, 8, 1, 0, 0), *minutes[0].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1,15, 1, 0, 0), *minutes[1].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1,22, 1, 0, 0), *minutes[2].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 1,29, 1, 0, 0), *minutes[3].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 2, 5, 1, 0, 0), *minutes[4].as_ref().unwrap());
+ }
+
+ #[test]
+ fn test_monthly() {
+ let minutes = ymd_hms(2000, 1, 1, 0, 0, 0)
+ .monthly(1)
+ .unwrap()
+ .calculate()
+ .take(5)
+ .collect::<Vec<_>>();
+
+ assert_eq!(ymd_hms(2000, 2, 1, 0, 0, 0), *minutes[0].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 3, 1, 0, 0, 0), *minutes[1].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 4, 1, 0, 0, 0), *minutes[2].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 5, 1, 0, 0, 0), *minutes[3].as_ref().unwrap());
+ assert_eq!(ymd_hms(2000, 6, 1, 0, 0, 0), *minutes[4].as_ref().unwrap());
+ }
+
+ #[test]
+ fn test_yearly() {
+ let minutes = ymd_hms(2000, 1, 1, 0, 0, 0)
+ .yearly(1)
+ .unwrap()
+ .calculate()
+ .take(5)
+ .collect::<Vec<_>>();
+
+ assert_eq!(ymd_hms(2001, 1, 1, 0, 0, 0), *minutes[0].as_ref().unwrap());
+ assert_eq!(ymd_hms(2002, 1, 1, 0, 0, 0), *minutes[1].as_ref().unwrap());
+ assert_eq!(ymd_hms(2003, 1, 1, 0, 0, 0), *minutes[2].as_ref().unwrap());
+ assert_eq!(ymd_hms(2004, 1, 1, 0, 0, 0), *minutes[3].as_ref().unwrap());
+ assert_eq!(ymd_hms(2005, 1, 1, 0, 0, 0), *minutes[4].as_ref().unwrap());
+ }
+
+ }
+
+}
diff --git a/src/timetype.rs b/src/timetype.rs
index f9e50fa..cfabe1e 100644
--- a/src/timetype.rs
+++ b/src/timetype.rs
@@ -19,7 +19,7 @@ use indicator::{Day, Month};
use util::*;
/// A Type of Time, currently based on chrono::NaiveDateTime
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum TimeType {
Seconds(i64),
Minutes(i64),
@@ -598,22 +598,11 @@ fn add(a: Box<TimeType>, b: Box<TimeType>) -> Result<TimeType> {
(thing, TT::Moment(mom)) => Err(KE::from_kind(KEK::CannotAdd(thing, TT::Moment(mom)))),
(TT::Seconds(a), other) => add_to_seconds(a, other),
- (other, TT::Seconds(a)) => add_to_seconds(a, other),
-
(TT::Minutes(a), other) => add_to_minutes(a, other),
- (other, TT::Minutes(a)) => add_to_minutes(a, other),
-
(TT::Hours(a), other) => add_to_hours(a, other),
- (other, TT::Hours(a)) => add_to_hours(a, other),
-
(TT::Days(a), other) => add_to_days(a, other),
- (other, TT::Days(a)) => add_to_days(a, other),
-
(TT::Months(a), other) => add_to_months(a, other),
- (other, TT::Months(a)) => add_to_months(a, other),
-
(TT::Years(a), other) => add_to_years(a, other),
- (other, TT::Years(a)) => add_to_years(a, other),
(TT::Addition(a, b), other) => add(a, b)
.map(Box::new)
@@ -683,7 +672,7 @@ fn add_to_minutes(amount: i64, tt: TimeType) -> Result<TimeType> {
TT::EndOfHour(e) => Err(KE::from_kind(KEK::CannotAdd(TT::Minutes(amount), TT::EndOfHour(e)))),
TT::EndOfMinute(e) => Err(KE::from_kind(KEK::CannotAdd(TT::Minutes(amount), TT::EndOfMinute(e)))),
TT::Addition(b, c) => add_to_minutes(amount, try!(add(b, c))),
- TT::Subtraction(b, c) => add_to_minutes(amount, try!(sub(b, c))),
+ TT::Subtraction(b, c) => sub_from_minutes(amount, try!(sub(b, c))),
}
}
@@ -875,37 +864,12 @@ fn sub(a: Box<TimeType>, b: Box<TimeType>) -> Result<TimeType> {
match (*a, *b) {
(TT::Moment(mom), thing) => sub_from_moment(mom, thing),
- (thing, TT::Moment(mom)) => Err(KE::from_kind(KEK::CannotSub(thing, TT::Moment(mom)))),
-
- (TT::Seconds(a), other) => sub_from_seconds(a, other),
- (other, TT::Seconds(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Seconds(a)))), // recurses into match branch above
-
- (TT::Minutes(a), other) => sub_from_minutes(a, other),
- (other, TT::Minutes(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Minutes(a)))), // recurses into match branch above
-
- (TT::Hours(a), other) => sub_from_hours(a, other),
- (other, TT::Hours(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Hours(a)))), // recurses into match branch above
-
- (TT::Days(a), other) => sub_from_days(a, other),
- (other, TT::Days(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Days(a)))), // recurses into match branch above
-
- (TT::Months(a), other) => sub_from_months(a, other),
- (other, TT::Months(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Months(a)))), // recurses into match branch above
-
- (TT::Years(a), other) => sub_from_years(a, other),
- (other, TT::Years(a)) => do_calculate(other)
- .map(Box::new)
- .and_then(|br| sub(br, Box::new(TT::Years(a)))), // recurses into match branch above
+ (TT::Seconds(a), other) => sub_from_seconds(a, other),
+ (TT::Minutes(a), other) => sub_from_minutes(a, other),
+ (TT::Hours(a), other) => sub_from_hours(a, other),
+ (TT::Days(a), other) => sub_from_days(a, other),
+ (TT::Months(a), other) => sub_from_months(a, other),
+ (TT::Years(a), other) => sub_from_years(a, other),
(TT::Subtraction(a, b), other) => sub(a, b)
.map(Box::new)