From ae868ddf8259599ac733734e7372c3eff4a7c7fd Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 19 Sep 2017 17:42:04 +0200 Subject: Let the TimeType be PartialEq, Eq, PartialOrd, Ord --- src/timetype.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/timetype.rs b/src/timetype.rs index f9e50fa..db0c05e 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), -- cgit v1.2.3 From 6ede3e3c7e57e029026b2efd2aad216b0fa83062 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 19 Sep 2017 17:42:23 +0200 Subject: Add extensions for building iterators conveniently --- src/iter.rs | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/src/iter.rs b/src/iter.rs index 0faceec..94d1458 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -93,3 +93,169 @@ impl> Iterator for CalculatingIter { } +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; + } + + pub trait Hourly { + fn hourly(self, i: i64) -> Result; + } + + pub trait Daily { + fn daily(self, i: i64) -> Result; + } + + pub trait Weekly : Sized { + fn weekly(self, i: i64) -> Result; + } + + pub trait Monthly { + fn monthly(self, i: i64) -> Result; + } + + pub trait Yearly { + fn yearly(self, i: i64) -> Result; + } + + pub trait Every { + fn every(self, inc: TT) -> Result; + } + + impl Minutely for TT { + + fn minutely(self, i: i64) -> Result { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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_simple() { + let minutes = ymd_hms(2000, 1, 1, 0, 0, 0) + .minutely(1) + .unwrap() + .calculate() + .take(5) + .collect::>(); + + 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()); + } + + } + +} -- cgit v1.2.3 From cf623f13e4c9f8cc9d8b6e029bb616293427748c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 25 Sep 2017 16:37:46 +0200 Subject: Fix weird addition bug in iterator The problem was the matching: We matched, in the addition branches, for a pair which we then reversed. This caused a strange bug when adding a moment and a minute. The subtraction matching was wrong as well, as it also reversed the order of the arguments. --- src/timetype.rs | 50 +++++++------------------------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/src/timetype.rs b/src/timetype.rs index db0c05e..cfabe1e 100644 --- a/src/timetype.rs +++ b/src/timetype.rs @@ -598,22 +598,11 @@ fn add(a: Box, b: Box) -> Result { (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 { 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, b: Box) -> Result { 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) -- cgit v1.2.3 From 7bc13877435e1d369cf8e8b361103164422030a5 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 25 Sep 2017 16:47:17 +0200 Subject: Add more tests --- src/iter.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/iter.rs b/src/iter.rs index 94d1458..4bfc2ca 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -239,9 +239,8 @@ pub mod extensions { TT::moment(ND::from_ymd(y, m, d).and_hms(h, mi, s)) } - #[test] - fn test_simple() { + fn test_minutely() { let minutes = ymd_hms(2000, 1, 1, 0, 0, 0) .minutely(1) .unwrap() @@ -256,6 +255,70 @@ pub mod extensions { 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::>(); + + 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::>(); + + 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::>(); + + 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::>(); + + 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()); + } + } } -- cgit v1.2.3