diff options
-rw-r--r-- | .github/ISSUE_TEMPLATE.md | 12 | ||||
-rw-r--r-- | .github/PULL_REQUEST_TEMPLATE.md | 12 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 78 | ||||
-rw-r--r-- | .travis.yml | 36 | ||||
-rw-r--r-- | Cargo.toml | 16 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | examples/main.rs | 34 | ||||
-rw-r--r-- | rustfmt.toml | 3 | ||||
-rw-r--r-- | src/error.rs | 35 | ||||
-rw-r--r-- | src/indicator.rs | 70 | ||||
-rw-r--r-- | src/iter.rs | 256 | ||||
-rw-r--r-- | src/lib.rs | 25 | ||||
-rw-r--r-- | src/matcher.rs | 32 | ||||
-rw-r--r-- | src/parser/iterator.rs | 322 | ||||
-rw-r--r-- | src/parser/mod.rs | 45 | ||||
-rw-r--r-- | src/parser/timetype.rs | 602 | ||||
-rw-r--r-- | src/timetype.rs | 1907 | ||||
-rw-r--r-- | src/util.rs | 140 |
18 files changed, 1825 insertions, 1804 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index ef4b5f0..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,12 +0,0 @@ -<!-- - -IMPORTANT NOTICE - -Github is only used for CI right now, main development continues on the -mailinglist. - -Please send issues and pull requests (either via `git request-pull` or `git -format-patch` + `git send-email`) to -[the imag mailinglist](https://imag-pim.org/mailinglist/). - ---> diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index ef4b5f0..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,12 +0,0 @@ -<!-- - -IMPORTANT NOTICE - -Github is only used for CI right now, main development continues on the -mailinglist. - -Please send issues and pull requests (either via `git request-pull` or `git -format-patch` + `git send-email`) to -[the imag mailinglist](https://imag-pim.org/mailinglist/). - ---> diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b70efcc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +on: [push, pull_request] + +name: MSRV + +jobs: + check: + name: Check + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4.1.1 + + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.75.0 + + - name: Cache + uses: Swatinem/rust-cache@v2 + + - name: Run cargo check + run: cargo check --all-features --examples --tests + + test: + name: Test Suite + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4.1.1 + + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.75.0 + + - name: Cache + uses: Swatinem/rust-cache@v2 + + - name: Run cargo test + run: cargo test --all-features + + fmt: + needs: [check] + name: Rustfmt + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4.1.1 + + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.75.0 + components: rustfmt + + - name: Run cargo fmt + run: cargo fmt --all -- --check + + clippy: + needs: [check] + name: Clippy + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4.1.1 + + - name: Install toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.75.0 + components: clippy + + - name: Cache + uses: Swatinem/rust-cache@v2 + + - name: Run cargo clippy + run: cargo clippy --all-targets --all-features -- -D warnings + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 23d0b5b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -sudo: false -os: - - linux - -dist: - - trusty - -language: rust - -rust: - - 1.32.0 - - 1.33.0 - - stable - - beta - - nightly - -matrix: - allow_failures: - - rust: nightly - -script: - - cargo build --all --all-features --verbose -j 1 - - cargo test --all --all-features --verbose -j 1 - -cache: - cargo: true - -notifications: - email: - on_success: never - irc: - channels: - - chat.freenode.net#imag - template: - - "%{repository_name} (%{branch} @ %{commit} by %{author}): %{result}" - @@ -1,6 +1,7 @@ [package] name = "kairos" -version = "0.3.0" +version = "0.4.0" +edition = "2021" authors = ["Matthias Beyer <mail@beyermatthias.de>"] description = "A library on top of chrono to calculate times and dates ergonomically" @@ -9,19 +10,18 @@ categories = [ "date-and-time" ] keywords = ["time", "calc", "parser"] readme = "README.md" license = "MPL-2.0" - -repository = "https://github.com/matthiasbeyer/kairos" +repository = "https://git.beyermatthi.as/kairos" [dependencies] chrono = "0.4" -nom = "3" -iso8601 = "0.2" -failure = "0.1" +nom = "7" +iso8601 = "0.6" +thiserror = "1" -filters = { version = "0.3", optional = true } +filters = { version = "0.4", optional = true } [dev-dependencies] -env_logger = "0.4" +env_logger = "0.11" log = "0.4" [features] @@ -2,10 +2,6 @@ Calculate times with chrono "plain text like" in Rust. -[![Build Status](https://travis-ci.org/matthiasbeyer/kairos.svg?branch=master)](https://travis-ci.org/matthiasbeyer/kairos) -[![license](https://img.shields.io/github/license/matthiasbeyer/kairos.svg?maxAge=2592000?style=flat-square)]() -[![Tokei](https://tokei.rs/b1/github/matthiasbeyer/kairos)](https://github.com/matthiasbeyer/kairos) - From Wikipedia: > Kairos (καιρός) is an Ancient Greek word meaning the right, critical or diff --git a/examples/main.rs b/examples/main.rs index 75bc9ff..53a328d 100644 --- a/examples/main.rs +++ b/examples/main.rs @@ -4,34 +4,38 @@ use kairos::timetype::TimeType as TT; fn pretty_print(tt: TT) { match tt { - TT::Seconds(e) => println!("{} Seconds", e), - TT::Minutes(e) => println!("{} Minutes", e), - TT::Hours(e) => println!("{} Hours", e), - TT::Days(e) => println!("{} Days", e), - TT::Months(e) => println!("{} Months", e), - TT::Years(e) => println!("{} Years", e), + TT::Seconds(e) => println!("{} Seconds", e), + TT::Minutes(e) => println!("{} Minutes", e), + TT::Hours(e) => println!("{} Hours", e), + TT::Days(e) => println!("{} Days", e), + TT::Months(e) => println!("{} Months", e), + TT::Years(e) => println!("{} Years", e), TT::Moment(ndt) => println!("{} ", ndt), - other => println!("Cannot pretty-print: '{:?}'", other), + other => println!("Cannot pretty-print: '{:?}'", other), } } fn main() { // not sure whether this is actually fast or something, but we don't care here, do we? - let s = ::std::env::args().skip(1).fold(String::new(), |acc, obj| format!("{} {}", acc, obj)); + let s = std::env::args() + .skip(1) + .fold(String::new(), |acc, obj| format!("{} {}", acc, obj)); let s = s.trim(); // because kairos is not yet whitespace tolerant match kairos::parser::parse(s) { Err(e) => println!("Error -> {:?}", e), Ok(kairos::parser::Parsed::TimeType(tt)) => match tt.calculate() { - Ok(r) => pretty_print(r), + Ok(r) => pretty_print(r), Err(e) => println!("Error calculating: {:?}", e), }, - Ok(kairos::parser::Parsed::Iterator(Ok(ui))) => for elem in ui { - match elem { - Ok(r) => pretty_print(r), - Err(e) => { - println!("Error calculating: {:?}", e); - ::std::process::exit(1) + Ok(kairos::parser::Parsed::Iterator(Ok(ui))) => { + for elem in ui { + match elem { + Ok(r) => pretty_print(r), + Err(e) => { + println!("Error calculating: {:?}", e); + std::process::exit(1) + }, } } }, diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..7676086 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +edition = "2021" +match_block_trailing_comma = true +max_width = 120 diff --git a/src/error.rs b/src/error.rs index c095000..979a76b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,42 +1,47 @@ -use timetype::TimeType; +use thiserror::Error; -#[derive(Debug, Clone, Eq, PartialEq, Fail)] -pub enum ErrorKind { +use crate::timetype::TimeType; - #[fail(display = "Unknown Error")] +pub type Result<T, E = Error> = std::result::Result<T, E>; + +#[derive(Debug, Clone, Eq, PartialEq, Error)] +pub enum Error { + #[error("Unknown Error")] UnknownError, - #[fail(display = "Cannot add: {:?} + {:?}", _0, _1)] + #[error("Cannot add: {0:?} + {1:?}")] CannotAdd(TimeType, TimeType), - #[fail(display = "Cannot subtract: {:?} - {:?}", _0, _1)] + #[error("Cannot subtract: {0:?} - {1:?}")] CannotSub(TimeType, TimeType), - #[fail(display = "The passed argument is not an amount: {:?}", _0)] + #[error("The passed argument is not an amount: {0:?}")] ArgumentErrorNotAnAmount(TimeType), - #[fail(display = "The passed argument is not a moment, but a {}", _0)] + #[error("The passed argument is not a moment, but a {0}")] ArgumentErrorNotAMoment(&'static str), - #[fail(display = "Argument Error: Cannot calculate end-of-year on a {:?}", _0)] + #[error("Argument Error: Cannot calculate end-of-year on a {0:?}")] CannotCalculateEndOfYearOn(TimeType), - #[fail(display = "Argument Error: Cannot calculate end-of-month on a {:?}", _0)] + #[error("Argument Error: Cannot calculate end-of-month on a {0:?}")] CannotCalculateEndOfMonthOn(TimeType), - #[fail(display = "Cannot compare Day to non-Moment TimeType: {:?}", _0)] + #[error("Cannot compare Day to non-Moment TimeType: {0:?}")] CannotCompareDayTo(&'static str), - #[fail(display = "Cannot compare Month to non-Moment TimeType: {:?}", _0)] + #[error("Cannot compare Month to non-Moment TimeType: {0:?}")] CannotCompareMonthTo(&'static str), - #[fail(display = "Out of bounds: {}-{}-{}T{}:{}:{}", _0, _1, _2, _3, _4, _5)] + #[error("Out of bounds: {0}-{1}-{2}T{3}:{4}:{5}")] OutOfBounds(i32, u32, u32, u32, u32, u32), - #[fail(display = "Cannot calculate date for iterator")] + #[error("Cannot calculate date for iterator")] NotADateInsideIterator, - #[fail(display = "Unknown parser error")] + #[error("Unknown parser error")] UnknownParserError, + #[error("Tokenizer error")] + NomError(String), } diff --git a/src/indicator.rs b/src/indicator.rs index fa9bf63..a89b0f0 100644 --- a/src/indicator.rs +++ b/src/indicator.rs @@ -1,14 +1,12 @@ #[cfg(feature = "with-filters")] +use chrono::Datelike; +#[cfg(feature = "with-filters")] use filters::filter::Filter; - #[cfg(feature = "with-filters")] use filters::filter::IntoFilter; #[cfg(feature = "with-filters")] -use timetype::TimeType; - -#[cfg(feature = "with-filters")] -use chrono::Datelike; +use crate::timetype::TimeType; #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] pub enum Day { @@ -21,16 +19,16 @@ pub enum Day { Sunday, } -impl Into<::chrono::Weekday> for Day { - fn into(self) -> ::chrono::Weekday { - match self { - Day::Monday => ::chrono::Weekday::Mon, - Day::Tuesday => ::chrono::Weekday::Tue, - Day::Wednesday => ::chrono::Weekday::Wed, - Day::Thursday => ::chrono::Weekday::Thu, - Day::Friday => ::chrono::Weekday::Fri, - Day::Saturday => ::chrono::Weekday::Sat, - Day::Sunday => ::chrono::Weekday::Sun, +impl From<Day> for chrono::Weekday { + fn from(val: Day) -> Self { + match val { + Day::Monday => chrono::Weekday::Mon, + Day::Tuesday => chrono::Weekday::Tue, + Day::Wednesday => chrono::Weekday::Wed, + Day::Thursday => chrono::Weekday::Thu, + Day::Friday => chrono::Weekday::Fri, + Day::Saturday => chrono::Weekday::Sat, + Day::Sunday => chrono::Weekday::Sun, } } } @@ -51,21 +49,21 @@ pub enum Month { December, } -impl Into<u32> for Month { - fn into(self) -> u32 { - match self { - Month::January => 1, - Month::February => 2, - Month::March => 3, - Month::April => 4, - Month::May => 5, - Month::June => 6, - Month::July => 7, - Month::August => 8, - Month::September => 9, - Month::October => 10, - Month::November => 11, - Month::December => 12, +impl From<Month> for u32 { + fn from(val: Month) -> Self { + match val { + Month::January => 1, + Month::February => 2, + Month::March => 3, + Month::April => 4, + Month::May => 5, + Month::June => 6, + Month::July => 7, + Month::August => 8, + Month::September => 9, + Month::October => 10, + Month::November => 11, + Month::December => 12, } } } @@ -76,7 +74,9 @@ pub struct DayFilter(Day); #[cfg(feature = "with-filters")] impl Filter<TimeType> for DayFilter { fn filter(&self, tt: &TimeType) -> bool { - tt.get_moment().map(|mom| mom.weekday() == self.0.clone().into()).unwrap_or(false) + tt.get_moment() + .map(|mom| mom.weekday() == self.0.clone().into()) + .unwrap_or(false) } } @@ -87,17 +87,17 @@ impl IntoFilter<TimeType> for Day { fn into_filter(self) -> Self::IntoFilt { DayFilter(self) } - } - #[cfg(feature = "with-filters")] pub struct MonthFilter(Month); #[cfg(feature = "with-filters")] impl Filter<TimeType> for MonthFilter { fn filter(&self, tt: &TimeType) -> bool { - tt.get_moment().map(|mom| mom.month() == self.0.clone().into()).unwrap_or(false) + tt.get_moment() + .map(|mom| mom.month() == self.0.clone().into()) + .unwrap_or(false) } } @@ -108,6 +108,4 @@ impl IntoFilter<TimeType> for Month { fn into_filter(self) -> Self::IntoFilt { MonthFilter(self) } - } - diff --git a/src/iter.rs b/src/iter.rs index d3d8978..d027083 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -2,12 +2,11 @@ //! use chrono::NaiveDateTime; -use failure::Fallible as Result; -use failure::Error; -use error::ErrorKind as KEK; -use timetype::TimeType; -use matcher::Matcher; +use crate::error::Error; +use crate::error::Result; +use crate::matcher::Matcher; +use crate::timetype::TimeType; #[derive(Debug)] pub struct Iter { @@ -24,13 +23,12 @@ pub struct Iter { // Performing the computation on the yielded `TimeType` instances can be done by transforming this // iterator into a `CalculatingIter`. impl Iter { - pub fn build(base: NaiveDateTime, inc: TimeType) -> Result<Iter> { if !inc.is_a_amount() { - Err(Error::from(KEK::ArgumentErrorNotAnAmount(inc))) + Err(Error::ArgumentErrorNotAnAmount(inc)) } else { Ok(Iter { - base: TimeType::moment(base), + base: TimeType::moment(base), increment: inc, had_first: false, }) @@ -54,14 +52,10 @@ impl Iter { } fn recalculate(&mut self) -> Result<()> { - self.base - .clone() - .calculate() - .map(|res| { - self.base = res; - }) + self.base.clone().calculate().map(|res| { + self.base = res; + }) } - } /// # Warning @@ -85,17 +79,18 @@ impl Iterator for Iter { Some(self.skip().map(|_| self.base.clone())) } } - } #[derive(Debug)] pub struct FilterIter<I, M>(I, M) - where I: Iterator<Item = Result<TimeType>>, - M: Matcher; +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher; impl<I, M> FilterIter<I, M> - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher, { fn new(i: I, m: M) -> FilterIter<I, M> { FilterIter(i, m) @@ -103,33 +98,35 @@ impl<I, M> FilterIter<I, M> } impl<I, M> Iterator for FilterIter<I, M> - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +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, + 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)), - } + 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>; +pub trait EveryFilter<M: Matcher>: Iterator<Item = Result<TimeType>> + Sized { + fn every(self, matcher: M) -> FilterIter<Self, M>; } impl<I, M> EveryFilter<M> for I - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher, { fn every(self, matcher: M) -> FilterIter<Self, M> { FilterIter::new(self, matcher) @@ -138,12 +135,14 @@ impl<I, M> EveryFilter<M> for I #[derive(Debug)] pub struct WithoutIter<I, M>(I, M) - where I: Iterator<Item = Result<TimeType>>, - M: Matcher; +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher; impl<I, M> WithoutIter<I, M> - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher, { fn new(i: I, m: M) -> WithoutIter<I, M> { WithoutIter(i, m) @@ -151,33 +150,35 @@ impl<I, M> WithoutIter<I, M> } impl<I, M> Iterator for WithoutIter<I, M> - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +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, + None => return None, Some(Err(e)) => return Some(Err(e)), Some(Ok(tt)) => match self.1.matches(&tt) { Ok(false) => return Some(Ok(tt)), - Ok(true) => continue, - Err(e) => return Some(Err(e)), - } + Ok(true) => continue, + Err(e) => return Some(Err(e)), + }, } } } } -pub trait WithoutFilter<M: Matcher> : Iterator<Item = Result<TimeType>> + Sized { - fn without(self, M) -> WithoutIter<Self, M>; +pub trait WithoutFilter<M: Matcher>: Iterator<Item = Result<TimeType>> + Sized { + fn without(self, matcher: M) -> WithoutIter<Self, M>; } impl<I, M> WithoutFilter<M> for I - where I: Iterator<Item = Result<TimeType>>, - M: Matcher +where + I: Iterator<Item = Result<TimeType>>, + M: Matcher, { fn without(self, matcher: M) -> WithoutIter<Self, M> { WithoutIter::new(self, matcher) @@ -186,10 +187,12 @@ impl<I, M> WithoutFilter<M> for I #[derive(Debug)] pub struct UntilIter<I>(I, NaiveDateTime) - where I: Iterator<Item = Result<TimeType>>; +where + I: Iterator<Item = Result<TimeType>>; impl<I> UntilIter<I> - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { fn new(i: I, date: NaiveDateTime) -> UntilIter<I> { UntilIter(i, date) @@ -197,36 +200,40 @@ impl<I> UntilIter<I> } impl<I> Iterator for UntilIter<I> - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { type Item = Result<TimeType>; fn next(&mut self) -> Option<Self::Item> { match self.0.next() { - None => None, + None => None, Some(Err(e)) => Some(Err(e)), Some(Ok(tt)) => match tt.calculate() { Err(e) => Some(Err(e)), - Ok(tt) => if tt.is_moment() { - if tt.get_moment().unwrap() < &self.1 { - Some(Ok(tt)) + Ok(tt) => { + if tt.is_moment() { + if tt.get_moment().unwrap() < &self.1 { + Some(Ok(tt)) + } else { + None + } } else { - None + Some(Err(Error::ArgumentErrorNotAMoment(tt.name()))) } - } else { - Some(Err(Error::from(KEK::ArgumentErrorNotAMoment(tt.name())))) - } - } + }, + }, } } } -pub trait Until : Iterator<Item = Result<TimeType>> + Sized { - fn until(self, NaiveDateTime) -> UntilIter<Self>; +pub trait Until: Iterator<Item = Result<TimeType>> + Sized { + fn until(self, ending: NaiveDateTime) -> UntilIter<Self>; } impl<I> Until for I - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { fn until(self, ending: NaiveDateTime) -> UntilIter<Self> { UntilIter::new(self, ending) @@ -235,7 +242,8 @@ impl<I> Until for I #[derive(Debug)] pub struct TimesIter<I> - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { inner: I, times: i64, @@ -243,19 +251,21 @@ pub struct TimesIter<I> } impl<I> TimesIter<I> - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { fn new(i: I, times: i64) -> TimesIter<I> { TimesIter { inner: i, - times: times, + times, count: 0, } } } impl<I> Iterator for TimesIter<I> - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { type Item = Result<TimeType>; @@ -269,12 +279,13 @@ impl<I> Iterator for TimesIter<I> } } -pub trait Times : Iterator<Item = Result<TimeType>> + Sized { - fn times(self, i64) -> TimesIter<Self>; +pub trait Times: Iterator<Item = Result<TimeType>> + Sized { + fn times(self, times: i64) -> TimesIter<Self>; } impl<I> Times for I - where I: Iterator<Item = Result<TimeType>> +where + I: Iterator<Item = Result<TimeType>>, { fn times(self, times: i64) -> TimesIter<Self> { TimesIter::new(self, times) @@ -282,11 +293,11 @@ impl<I> Times for I } pub mod extensions { - use timetype::TimeType as TT; + use crate::error::Error; + use crate::error::Result; + use crate::timetype::TimeType as TT; + use super::Iter; - use failure::Fallible as Result; - use failure::Error; - use error::ErrorKind as KEK; pub trait Minutely { fn minutely(self, i: i64) -> Result<Iter>; @@ -300,7 +311,7 @@ pub mod extensions { fn daily(self, i: i64) -> Result<Iter>; } - pub trait Weekly : Sized { + pub trait Weekly: Sized { fn weekly(self, i: i64) -> Result<Iter>; } @@ -317,7 +328,6 @@ pub mod extensions { } impl Minutely for TT { - fn minutely(self, i: i64) -> Result<Iter> { match self { TT::Moment(mom) => { @@ -325,14 +335,12 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } impl Hourly for TT { - fn hourly(self, i: i64) -> Result<Iter> { match self { TT::Moment(mom) => { @@ -340,14 +348,12 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } impl Daily for TT { - fn daily(self, i: i64) -> Result<Iter> { match self { TT::Moment(mom) => { @@ -355,14 +361,12 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } impl Weekly for TT { - /// Conveniance function over `Daily::daily( n * 7 )` fn weekly(self, i: i64) -> Result<Iter> { match self { @@ -371,14 +375,12 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } impl Monthly for TT { - fn monthly(self, i: i64) -> Result<Iter> { match self { TT::Moment(mom) => { @@ -386,14 +388,12 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } impl Yearly for TT { - fn yearly(self, i: i64) -> Result<Iter> { match self { TT::Moment(mom) => { @@ -401,30 +401,30 @@ pub mod extensions { assert!(increment.is_a_amount(), "This is a Bug, please report this!"); Iter::build(mom, increment) }, - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } - } - impl Every for TT { fn every(self, inc: TT) -> Result<Iter> { match self { TT::Moment(mom) => Iter::build(mom, inc), - _ => Err(Error::from(KEK::ArgumentErrorNotAnAmount(self))), + _ => Err(Error::ArgumentErrorNotAnAmount(self)), } } } #[cfg(test)] mod tests { - use super::*; - use timetype::TimeType as TT; use chrono::NaiveDate as ND; + use crate::timetype::TimeType as TT; + + use super::*; + 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)) + TT::moment(ND::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, mi, s).unwrap()) } #[test] @@ -467,9 +467,9 @@ pub mod extensions { assert_eq!(ymd_hms(2000, 1, 1, 1, 0, 0), *minutes[0].as_ref().unwrap()); assert_eq!(ymd_hms(2000, 1, 8, 1, 0, 0), *minutes[1].as_ref().unwrap()); - assert_eq!(ymd_hms(2000, 1,15, 1, 0, 0), *minutes[2].as_ref().unwrap()); - assert_eq!(ymd_hms(2000, 1,22, 1, 0, 0), *minutes[3].as_ref().unwrap()); - assert_eq!(ymd_hms(2000, 1,29, 1, 0, 0), *minutes[4].as_ref().unwrap()); + assert_eq!(ymd_hms(2000, 1, 15, 1, 0, 0), *minutes[2].as_ref().unwrap()); + assert_eq!(ymd_hms(2000, 1, 22, 1, 0, 0), *minutes[3].as_ref().unwrap()); + assert_eq!(ymd_hms(2000, 1, 29, 1, 0, 0), *minutes[4].as_ref().unwrap()); } #[test] @@ -501,15 +501,13 @@ pub mod extensions { assert_eq!(ymd_hms(2003, 1, 1, 0, 0, 0), *minutes[3].as_ref().unwrap()); assert_eq!(ymd_hms(2004, 1, 1, 0, 0, 0), *minutes[4].as_ref().unwrap()); } - } - } #[cfg(test)] mod type_tests { - use super::*; use super::extensions::*; + use super::*; #[test] fn test_iterator_every_once() { @@ -517,7 +515,7 @@ mod type_tests { let _ = TimeType::today() .yearly(1) .unwrap() - .every(::indicator::Day::Monday); + .every(crate::indicator::Day::Monday); } #[test] @@ -526,25 +524,30 @@ mod type_tests { let _ = TimeType::today() .yearly(1) // collecting makes us stack-overflow because of the heavy filtering! .unwrap() - .every(::indicator::Day::Monday) - .every(::indicator::Month::January); + .every(crate::indicator::Day::Monday) + .every(crate::indicator::Month::January); } } #[cfg(all(feature = "with-filters", test))] mod type_tests_filter_interface { - use super::*; - use super::extensions::*; use filters::filter::Filter; use filters::filter::IntoFilter; + use super::extensions::*; + use super::*; + #[test] fn test_compile() { // This test is solely to check whether this compiles and the API is nice let _ = TimeType::today() .daily(1) .unwrap() - .every(::indicator::Day::Monday.into_filter().or(::indicator::Month::January)) + .every( + crate::indic |