diff --git a/.cocorc b/.cocorc index 55e71d4..9a68399 100644 --- a/.cocorc +++ b/.cocorc @@ -7,3 +7,4 @@ scopes: - "cli" - "logger" - "macros" + - "sched" diff --git a/lib/sched/rules.rs b/lib/sched/rules.rs index ef4fa9f..3e5537e 100644 --- a/lib/sched/rules.rs +++ b/lib/sched/rules.rs @@ -3,7 +3,7 @@ mod cron; #[cfg(feature = "sched-rule-recurrent")] mod recurrent; #[cfg(feature = "sched-rule-recurrent")] -pub use self::recurrent::{many, val, range, ranges, ruleset, RecurrenceRuleSet, Rule}; +pub use self::recurrent::{many, range, ranges, ruleset, val, RecurrenceRuleSet, Rule}; use chrono::{DateTime, Local}; diff --git a/lib/sched/rules/cron.rs b/lib/sched/rules/cron.rs index c641e17..100dcbb 100644 --- a/lib/sched/rules/cron.rs +++ b/lib/sched/rules/cron.rs @@ -1,2 +1 @@ - -// TODO: cron based scheduling \ No newline at end of file +// TODO: cron based scheduling diff --git a/lib/sched/rules/recurrent/mod.rs b/lib/sched/rules/recurrent/mod.rs index 8b45ed9..e60ac0e 100644 --- a/lib/sched/rules/recurrent/mod.rs +++ b/lib/sched/rules/recurrent/mod.rs @@ -1,8 +1,10 @@ #[cfg(test)] mod tests; -mod ruleset; mod rule_unit; +mod ruleset; -pub use ruleset::{RecurrenceRuleSet, builder::ruleset}; -pub use rule_unit::{Rule, val, range, many, ranges}; \ No newline at end of file +pub use { + rule_unit::{many, range, ranges, val, Rule}, + ruleset::{builder::ruleset, RecurrenceRuleSet}, +}; diff --git a/lib/sched/rules/recurrent/ruleset.rs b/lib/sched/rules/recurrent/ruleset.rs index b5cd730..6d79ab9 100644 --- a/lib/sched/rules/recurrent/ruleset.rs +++ b/lib/sched/rules/recurrent/ruleset.rs @@ -1,5 +1,5 @@ pub mod builder; - + use { super::Rule, crate::sched::utils::cron_date::LoolDate, @@ -9,7 +9,7 @@ use { /// 🧉 » a recurrence rule-set /// /// sets rules that define a certain recurrence behavior -/// +/// /// use the builder pattern to create a new `RecurrenceRuleSet` pub struct RecurrenceRuleSet { /// second of the minute (0..59) @@ -37,10 +37,7 @@ impl RecurrenceRuleSet { /// 🧉 » returns the next match of the rule set from a given `DateTime` pub fn next_match_from(&self, from: DateTime) -> Option> { let next = self._next_match(from); - match next { - Some(date) => Some(date.date()), - None => None, - } + next.map(|date| date.date()) } /// 🚧 internal @@ -51,12 +48,12 @@ impl RecurrenceRuleSet { // check year if let Some(Rule::Val(year)) = self.year { - if year < from.year().into() { + if year < from.year() { return None; } } - let mut next = LoolDate::new(from.clone()); + let mut next = LoolDate::new(from); next.add_second(); loop { @@ -125,4 +122,3 @@ impl RecurrenceRuleSet { Some(next) } } - diff --git a/lib/sched/rules/recurrent/ruleset/builder.rs b/lib/sched/rules/recurrent/ruleset/builder.rs index a2670b1..cc2c6c9 100644 --- a/lib/sched/rules/recurrent/ruleset/builder.rs +++ b/lib/sched/rules/recurrent/ruleset/builder.rs @@ -1,11 +1,10 @@ use chrono::Weekday; -use super::RecurrenceRuleSet; -use crate::sched::rules::Rule; +use {super::RecurrenceRuleSet, crate::sched::rules::Rule}; pub fn ruleset() -> RecurrenceRuleSet { - let ruleset = RecurrenceRuleSet::recurring(); - ruleset + + RecurrenceRuleSet::recurring() } impl RecurrenceRuleSet { diff --git a/lib/sched/rules/recurrent/tests/mod.rs b/lib/sched/rules/recurrent/tests/mod.rs index be927a1..446e9d1 100644 --- a/lib/sched/rules/recurrent/tests/mod.rs +++ b/lib/sched/rules/recurrent/tests/mod.rs @@ -1,3 +1,3 @@ -mod recurrence_rules_by_val; +mod recurrence_rules_by_many; mod recurrence_rules_by_range; -mod recurrence_rules_by_many; \ No newline at end of file +mod recurrence_rules_by_val; diff --git a/lib/sched/rules/recurrent/tests/recurrence_rules_by_many.rs b/lib/sched/rules/recurrent/tests/recurrence_rules_by_many.rs index 957aa19..239a706 100644 --- a/lib/sched/rules/recurrent/tests/recurrence_rules_by_many.rs +++ b/lib/sched/rules/recurrent/tests/recurrence_rules_by_many.rs @@ -1,10 +1,10 @@ -use chrono::{Datelike, Local, TimeZone, Utc}; +use chrono::{Datelike, Local, TimeZone}; use crate::sched::rules::{many, range, ruleset}; #[test] fn every_day_at_12_and_15() { - let date = Local.with_ymd_and_hms(2024, 4, 7, 13, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 7, 13, 15, 5).unwrap(); let mut rules = ruleset(); rules.hours_rule(many(vec![12, 15])).at_minute(0).at_second(0); @@ -28,12 +28,12 @@ fn every_day_at_12_and_15() { #[test] fn each_day_between_9_and_17_at_hour_start() { // will start next day because it's already > 17:00:00 - let date = Local.with_ymd_and_hms(2024, 4, 25, 19, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 25, 19, 15, 5).unwrap(); let mut rules = ruleset(); rules.hours_rule(range(9, 17, 1)).at_minute(0).at_second(0); - let mut next = date.clone(); + let mut next = date; let initial_day = date.day() + 1; for i in 0..18 { diff --git a/lib/sched/rules/recurrent/tests/recurrence_rules_by_range.rs b/lib/sched/rules/recurrent/tests/recurrence_rules_by_range.rs index 014c67e..2a618a9 100644 --- a/lib/sched/rules/recurrent/tests/recurrence_rules_by_range.rs +++ b/lib/sched/rules/recurrent/tests/recurrence_rules_by_range.rs @@ -4,12 +4,12 @@ use crate::sched::rules::{range, ruleset}; #[test] fn between_10_and_20_seconds() { - let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 5).unwrap(); let mut rules = ruleset(); rules.seconds_rule(range(10, 20, 1)); - let mut next = date.clone(); + let mut next = date; let initial_minute = date.minute(); for i in 0..20 { @@ -33,12 +33,12 @@ fn between_10_and_20_seconds() { #[test] fn each_day_between_9_and_17_at_hour_start() { // will start next day because it's already > 17:00:00 - let date = Local.with_ymd_and_hms(2024, 4, 25, 19, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 25, 19, 15, 5).unwrap(); let mut rules = ruleset(); rules.hours_rule(range(9, 17, 1)).at_minute(0).at_second(0); - let mut next = date.clone(); + let mut next = date; let initial_day = date.day() + 1; for i in 0..18 { diff --git a/lib/sched/rules/recurrent/tests/recurrence_rules_by_val.rs b/lib/sched/rules/recurrent/tests/recurrence_rules_by_val.rs index 58ee585..44a6c6c 100644 --- a/lib/sched/rules/recurrent/tests/recurrence_rules_by_val.rs +++ b/lib/sched/rules/recurrent/tests/recurrence_rules_by_val.rs @@ -6,12 +6,12 @@ use crate::sched::rules::ruleset; fn at_second_1_of_each_minute() { // we have passed the second 1 of the minute // so it should go to the next minute - let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 5).unwrap(); let mut rules = ruleset(); rules.at_second(1); - let mut next = date.clone(); + let mut next = date; let initial_minute = date.minute(); for i in 0..10 { @@ -20,7 +20,7 @@ fn at_second_1_of_each_minute() { // should match 16:16:01, 16:17:01, 16:18:01, ... assert_eq!( next, - Local.with_ymd_and_hms(2024, 4, 7, 16, initial_minute + i + 1, 01).unwrap() + Local.with_ymd_and_hms(2024, 4, 7, 16, initial_minute + i + 1, 1).unwrap() ); } } @@ -29,12 +29,12 @@ fn at_second_1_of_each_minute() { fn at_hour_1_of_each_day() { // we have passed the hour 1 of the day // so it should go to the next day - let date = Local.with_ymd_and_hms(2024, 4, 25, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 25, 16, 15, 5).unwrap(); let mut rules = ruleset(); rules.at_time(1, 0, 0); - let mut next = date.clone(); + let mut next = date; let mut initial_day = date.day() as i32; let mut initial_month = date.month(); @@ -55,9 +55,9 @@ fn at_hour_1_of_each_day() { 2024, initial_month, (initial_day + i + 1) as u32, - 01, - 00, - 00 + 1, + 0, + 0 ) .unwrap() ); @@ -68,12 +68,12 @@ fn at_hour_1_of_each_day() { fn each_1st_of_month() { // we have passed the 1st of the month // so it should go to the next month - let date = Local.with_ymd_and_hms(2024, 5, 7, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 5, 7, 16, 15, 5).unwrap(); let mut rules = ruleset(); rules.on_day(1).at_time(0, 0, 0); - let mut next = date.clone(); + let mut next = date; let mut initial_month = date.month() as i32; let mut initial_year = date.year(); @@ -90,7 +90,7 @@ fn each_1st_of_month() { assert_eq!( next, Local - .with_ymd_and_hms(initial_year, (initial_month + i + 1) as u32, 01, 00, 00, 00) + .with_ymd_and_hms(initial_year, (initial_month + i + 1) as u32, 1, 0, 0, 0) .unwrap() ); } @@ -100,20 +100,20 @@ fn each_1st_of_month() { fn each_wednesday() { // we have passed the Wednesday // so it should go to the next Wednesday - let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 4, 7, 16, 15, 5).unwrap(); let mut next_wednesday = Local.with_ymd_and_hms(2024, 4, 10, 0, 0, 0).unwrap(); let mut rules = ruleset(); rules.on_dow(Weekday::Wed).at_time(0, 0, 0); - let mut next = date.clone(); + let mut next = date; for _ in 0..10 { next = rules.next_match_from(next).unwrap(); println!("next: {:?}", next); assert_eq!(next, next_wednesday); - next_wednesday = next_wednesday + chrono::Duration::days(7); + next_wednesday += chrono::Duration::days(7); } } @@ -121,12 +121,12 @@ fn each_wednesday() { fn from_31th_may_schedule_first_of_each_june() { // we have passed the 31th of May // so it should go to the 1st of June - let date = Local.with_ymd_and_hms(2024, 5, 31, 16, 15, 05).unwrap(); + let date = Local.with_ymd_and_hms(2024, 5, 31, 16, 15, 5).unwrap(); let mut rules = ruleset(); rules.in_month(6).on_day(1).at_time(0, 0, 0); - let mut next = date.clone(); + let mut next = date; let initial_year = date.year(); let initial_month = date.month(); @@ -138,7 +138,7 @@ fn from_31th_may_schedule_first_of_each_june() { // should match 2024-06-01 00:00:00, 2024-07-01 00:00:00, 2024-08-01 00:00:00, ... assert_eq!( next, - Local.with_ymd_and_hms(initial_year + i, initial_month + 1, 01, 00, 00, 00).unwrap() + Local.with_ymd_and_hms(initial_year + i, initial_month + 1, 1, 0, 0, 0).unwrap() ); } } @@ -150,7 +150,7 @@ fn from_1st_may_schedule_first_of_each_june() { let mut rules = ruleset(); rules.in_month(6).on_day(1).at_time(0, 0, 0); - let mut next = date.clone(); + let mut next = date; let initial_year = date.year(); for i in 0..10 { @@ -159,7 +159,7 @@ fn from_1st_may_schedule_first_of_each_june() { assert_eq!( next, - Local.with_ymd_and_hms(initial_year + i + 1, 06, 01, 00, 00, 00).unwrap() + Local.with_ymd_and_hms(initial_year + i + 1, 6, 1, 0, 0, 0).unwrap() ); } } diff --git a/lib/sched/utils/cron_date.rs b/lib/sched/utils/cron_date.rs index b5fcd5c..b30a598 100644 --- a/lib/sched/utils/cron_date.rs +++ b/lib/sched/utils/cron_date.rs @@ -54,25 +54,25 @@ impl LoolDate { /// adds `1` day to the current date pub fn add_day(&mut self) { - self.date = self.date.clone() + Duration::days(1); + self.date += Duration::days(1); self.set_start_of(TimeUnit::Day); } /// adds `1` hour to the current date pub fn add_hour(&mut self) { - self.date = self.date.clone() + Duration::hours(1); + self.date += Duration::hours(1); self.set_start_of(TimeUnit::Hour); } /// adds `1` minute to the current date pub fn add_minute(&mut self) { - self.date = self.date.clone() + Duration::minutes(1); + self.date += Duration::minutes(1); self.set_start_of(TimeUnit::Minute); } /// adds `1` second to the current date pub fn add_second(&mut self) { - self.date = self.date.clone() + Duration::seconds(1); + self.date += Duration::seconds(1); self.set_start_of(TimeUnit::Second); } @@ -88,22 +88,22 @@ impl LoolDate { /// subtracts `1` day from the current date pub fn subs_day(&mut self) { - self.date = self.date.clone() - Duration::days(1); + self.date -= Duration::days(1); } /// subtracts `1` hour from the current date pub fn subs_hour(&mut self) { - self.date = self.date.clone() - Duration::hours(1); + self.date -= Duration::hours(1); } /// subtracts `1` minute from the current date pub fn subs_minute(&mut self) { - self.date = self.date.clone() - Duration::minutes(1); + self.date -= Duration::minutes(1); } /// subtracts `1` second from the current date pub fn subs_second(&mut self) { - self.date = self.date.clone() - Duration::seconds(1); + self.date -= Duration::seconds(1); } /// returns the day of the month starting from `1` @@ -152,7 +152,7 @@ impl LoolDate { } /// returns the number of milliseconds since the last second boundary - /// + /// /// In event of a [leap second](https://en.wikipedia.org/wiki/Leap_second) this may exceed /// `999`. pub fn millis(&self) -> u64 { @@ -160,7 +160,7 @@ impl LoolDate { } /// Returns the number of microseconds since the last second boundary. - /// + /// /// In event of a [leap second](https://en.wikipedia.org/wiki/Leap_second) this may exceed /// `999999`. pub fn micros(&self) -> u32 { @@ -168,7 +168,7 @@ impl LoolDate { } /// Returns the number of nanoseconds since the last second boundary. - /// + /// /// In event of a [leap second](https://en.wikipedia.org/wiki/Leap_second) this may exceed /// `999999999`. pub fn nanos(&self) -> u32 { @@ -176,25 +176,33 @@ impl LoolDate { } /// sets the nanoseconds since the last second change - /// + /// /// values greater than `2000,000,000` will be clamped to `1999,999,999` pub fn set_nanos(&mut self, nanos: u32) { // avoid `whith_nanosecond` returning None for > 2_000_000_000 values // so we can safely unwrap the result - let nanos = if nanos > 2_000_000_000 { 1_999_999_999 } else { nanos }; + let nanos = if nanos > 2_000_000_000 { + 1_999_999_999 + } else { + nanos + }; self.date = self.date.with_nanosecond(nanos).unwrap(); } /// sets the microseconds since the last second change - /// + /// /// values greater than `2,000,000` will be clamped to `1,999,999` pub fn set_micros(&mut self, micros: u32) { - let micros = if micros > 2_000_000 { 1_999_999 } else { micros }; - self.date = self.date.with_nanosecond(micros as u32 * 1_000).unwrap(); + let micros = if micros > 2_000_000 { + 1_999_999 + } else { + micros + }; + self.date = self.date.with_nanosecond(micros * 1_000).unwrap(); } /// sets the milliseconds since the last second change - /// + /// /// values greater than `2,000` will be clamped to `1,999` pub fn set_millis(&mut self, millis: u64) { let millis = if millis > 2_000 { 1_999 } else { millis }; @@ -202,7 +210,7 @@ impl LoolDate { } /// sets the second number of the date - /// + /// /// values >= `60` will be clamped to `0` pub fn set_second(&mut self, second: u32) { let second = if second >= 60 { 0 } else { second }; @@ -210,7 +218,7 @@ impl LoolDate { } /// sets the minute number of the date - /// + /// /// values >= `60` will be clamped to `0` pub fn set_minute(&mut self, minute: u32) { let minute = if minute >= 60 { 0 } else { minute }; @@ -218,7 +226,7 @@ impl LoolDate { } /// sets the hour number of the date `(0..23)` - /// + /// /// values >= `24` will be clamped to `0` pub fn set_hour(&mut self, hour: u32) { let hour = if hour >= 24 { 0 } else { hour }; @@ -226,11 +234,11 @@ impl LoolDate { } /// sets the hour, minute and second of the date at once - /// + /// /// - `hour` must be in the range `(0..23)` /// - `minute` must be in the range `(0..59)` /// - `second` must be in the range `(0..59)` - /// + /// /// values greater than the maximum will be clamped (see `set_hour`, `set_minute`, `set_second`) /// documentation for more information pub fn set_hms(&mut self, hour: u32, minute: u32, second: u32) { @@ -240,7 +248,7 @@ impl LoolDate { } /// sets the day of the month `(1..31)` - /// + /// /// values greater than the maximum day of the month will be clamped to the last day of the /// month, depending on the current year and month and taking leap years into account. pub fn set_day(&mut self, day: u32) { @@ -255,10 +263,10 @@ impl LoolDate { } /// sets the month of the year `(1..12)` - /// + /// /// - values greater than the maximum month will be clamped to `12` /// - values less than `1` will be clamped to `1` - /// + /// /// if the current day is greater than the last day of the new month, the day will be clamped /// to the last day of the month, depending on the current year and month and taking leap years /// into account. So, be aware that changing the month may imply a change in the day. @@ -285,7 +293,7 @@ impl LoolDate { } /// sets the month and day of the date at once - /// + /// /// check the `set_month` and `set_day` documentation for more information about the clamping /// behavior. pub fn set_md(&mut self, month: u32, day: u32) { @@ -294,12 +302,12 @@ impl LoolDate { } /// sets the year of the date - /// - /// **warning**: changing the year may imply a change in the day. + /// + /// **warning**: changing the year may imply a change in the day. /// For example, if the current date is `2024-02-29` and you set the year to `2023`, the date /// date `2023-02-29` will be invalid, because `2023` is not a leap year. In this case, the day /// will be clamped to `2023-02-28`. - /// + /// /// check the `set_day` documentation for more information about the clamping behavior. pub fn set_year(&mut self, year: i32) { let month = self.date.month(); @@ -315,7 +323,7 @@ impl LoolDate { } /// sets the year, month and day of the date at once - /// + /// /// check the `set_year`, `set_month` and `set_day` documentation for more information about the /// clamping behavior. pub fn set_ymd(&mut self, year: i32, month: u32, day: u32) { @@ -347,32 +355,32 @@ impl LoolDate { self.set_minute(0); self.set_second(0); self.set_nanos(0); - }, + } TimeUnit::Month => { self.set_day(1); self.set_hour(0); self.set_minute(0); self.set_second(0); self.set_nanos(0); - }, + } TimeUnit::Day => { self.set_hour(0); self.set_minute(0); self.set_second(0); self.set_nanos(0); - }, + } TimeUnit::Hour => { self.set_minute(0); self.set_second(0); self.set_nanos(0); - }, + } TimeUnit::Minute => { self.set_second(0); self.set_nanos(0); - }, + } TimeUnit::Second => { self.set_nanos(0); - }, + } }; } } diff --git a/lib/sched/utils/mod.rs b/lib/sched/utils/mod.rs index 6c6a7c4..726e694 100644 --- a/lib/sched/utils/mod.rs +++ b/lib/sched/utils/mod.rs @@ -10,7 +10,7 @@ const INVALID_OFFSET_MIN_ERR: &str = "invalid timezone offset (minute should be /// 🧉 » converts `hours` and `minutes` durations to total seconds /// /// e.g. `h=1, m=30` should return `5400` -/// +/// /// meaning `1 hour and 30 minutes` is `5400` seconds pub fn hm_to_s(h: i32, m: i32) -> i32 { h * 3600 + m * 60 @@ -48,7 +48,7 @@ pub fn tz_to_s(offset: &str) -> Result { 0 }; - // offset hours cannot be greater than 14, minutes cannot be greater than 59 and + // offset hours cannot be greater than 14, minutes cannot be greater than 59 and // seconds cannot be greater than 59 ensure!(hours <= 14, INVALID_OFFSET_HS_ERR); ensure!(minutes <= 59, INVALID_OFFSET_MIN_ERR); @@ -58,8 +58,10 @@ pub fn tz_to_s(offset: &str) -> Result { #[cfg(test)] mod tests { - use eyre::{set_hook, DefaultHandler}; - use super::*; + use { + super::*, + eyre::{set_hook, DefaultHandler}, + }; fn setup_eyre() { let _ = set_hook(Box::new(DefaultHandler::default_with));