From 00ba4141d5bb41f0ffc014c76bfdafcec7c02b6b Mon Sep 17 00:00:00 2001 From: Fredrik Meringdal Date: Tue, 3 Nov 2020 23:22:51 +0100 Subject: using lazy_static instead of once_cell --- Cargo.toml | 2 +- src/iter/masks.rs | 7 ++++--- src/iter/mod.rs | 2 +- src/iter/poslist.rs | 2 +- src/lib.rs | 12 +++++++----- src/options.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/rrule.rs | 1 - src/rrulestr.rs | 26 +++++++++++++------------- src/utils.rs | 9 ++++----- 9 files changed, 69 insertions(+), 30 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e3f2357..5e6ce20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,5 @@ categories = ["date-and-time"] [dependencies] chrono = "0.4.19" chrono-tz = "0.5.3" -once_cell = "1.4.1" +lazy_static = "1.4.0" regex = "1.4.1" diff --git a/src/iter/masks.rs b/src/iter/masks.rs index 8b2f6b0..726d270 100644 --- a/src/iter/masks.rs +++ b/src/iter/masks.rs @@ -1,12 +1,13 @@ -use once_cell::sync::Lazy; - // ============================================================================= // Date masks // ============================================================================= // Every mask is 7 days longer to handle cross-year weekly periods. -pub static MASKS: Lazy = Lazy::new(Masks::default); + +lazy_static! { + pub static ref MASKS: Masks = Masks::default(); +} #[derive(Clone)] pub struct Masks { diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 05b588d..29e86e0 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -313,7 +313,7 @@ pub fn remove_filtered_days( dayset[daycounter] = None; } } - None => continue + None => continue, } } filtered diff --git a/src/iter/poslist.rs b/src/iter/poslist.rs index 8e468aa..ce627a4 100644 --- a/src/iter/poslist.rs +++ b/src/iter/poslist.rs @@ -51,7 +51,7 @@ pub fn build_poslist( timeset[timepos as usize].minute as u32, timeset[timepos as usize].second as u32, ); - + if !poslist.iter().any(|&p| p == res) { poslist.push(res); } diff --git a/src/lib.rs b/src/lib.rs index 035496d..af5fd29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,8 @@ //! - `between`: Generate all recurrences that matches the rules and are between two given dates //! - `before`: Generate the last recurrence that matches the rules and is before a given date //! - `after`: Generate the first recurrence that matches the rules and is after a given date -//! All the generated recurrence will be in the same time zone as the dtstart property. +//! +//! Note: All the generated recurrence will be in the same time zone as the dtstart property. //! //! # Examples //! @@ -29,14 +30,14 @@ //! //! use rrule::RRule; //! -//! // Parse a RRule string, return a RRul to get e type +//! // Parse a RRule string //! let mut rrule: RRule = "DTSTART:20120201T093000Z\nRRULE:FREQ=WEEKLY;INTERVAL=5;UNTIL=20130130T230000Z;BYDAY=MO,FR".parse().unwrap(); //! assert_eq!(rrule.all().len(), 21); //! //! //! use rrule::RRuleSet; //! -//! // Parse a RRuleSet string, return a RRuleSet type +//! // Parse a RRuleSet string //! let mut rrule_set: RRuleSet = "DTSTART:20120201T023000Z\nRRULE:FREQ=MONTHLY;COUNT=5\nRDATE:20120701T023000Z,20120702T023000Z\nEXRULE:FREQ=MONTHLY;COUNT=2\nEXDATE:20120601T023000Z".parse().unwrap(); //! assert_eq!(rrule_set.all().len(), 4); //! ``` @@ -120,7 +121,7 @@ //! rrule_set.exrule(exrule); //! //! let recurrences = rrule_set.all(); -//! +//! //! // Check that all the recurrences are on a Tuesday //! for occurence in &recurrences { //! assert_eq!(occurence.weekday(), Weekday::Tue); @@ -191,8 +192,9 @@ extern crate chrono; extern crate chrono_tz; -extern crate once_cell; extern crate regex; +#[macro_use] +extern crate lazy_static; mod datetime; mod iter; diff --git a/src/options.rs b/src/options.rs index 31f884b..dc2d186 100644 --- a/src/options.rs +++ b/src/options.rs @@ -113,88 +113,126 @@ impl Options { } } + /// The FREQ rule part identifies the type of recurrence rule. pub fn freq(mut self, freq: Frequenzy) -> Self { self.freq = Some(freq); self } + /// The interval between each freq iteration. pub fn interval(mut self, interval: usize) -> Self { self.interval = Some(interval); self } + /// If given, this determines how many occurrences will be generated. pub fn count(mut self, count: u32) -> Self { self.count = Some(count); self } + /// If given, this must be a datetime instance specifying the + /// upper-bound limit of the recurrence. pub fn until(mut self, until: DateTime) -> Self { self.until = Some(until.with_timezone(&UTC)); self } + /// The recurrence start. Recurrences generated by the rrule will + /// be in the same time zone as the start date. pub fn dtstart(mut self, dtstart: DTime) -> Self { self.dtstart = Some(dtstart); self.tzid = Some(dtstart.timezone()); self } + /// The week start day. This will affect recurrences based on weekly periods. The default week start is Weekday::Mon. pub fn wkst(mut self, wkst: Weekday) -> Self { self.wkst = Some(get_weekday_val(&wkst)); self } + /// If given, it must be either an integer, or a sequence of integers, positive or negative. + /// Each given integer will specify an occurrence number, corresponding to the nth occurrence + /// of the rule inside the frequency period. For example, a bysetpos of -1 if combined with + /// a MONTHLY frequency, and a byweekday of (MO, TU, WE, TH, FR), will result in the last + /// work day of every month. pub fn bysetpos(mut self, bysetpos: Vec) -> Self { self.bysetpos = Some(bysetpos); self } + /// If given, it must be either an integer, or a sequence of integers, meaning + /// the months to apply the recurrence to. pub fn bymonth(mut self, bymonth: Vec) -> Self { self.bymonth = Some(bymonth); self } + /// If given, it must be either an integer, or a sequence of integers, meaning + /// the month days to apply the recurrence to. pub fn bymonthday(mut self, bymonthday: Vec) -> Self { self.bymonthday = Some(bymonthday); self } + /// If given, it must be either an integer, or a sequence of integers, meaning + /// the year days to apply the recurrence to. pub fn byyearday(mut self, byyearday: Vec) -> Self { self.byyearday = Some(byyearday); self } + /// If given, it must be either an integer, or a sequence of integers, meaning + /// the week numbers to apply the recurrence to. Week numbers have the meaning + /// described in ISO8601, that is, the first week of the year is that containing + /// at least four days of the new year. pub fn byweekno(mut self, byweekno: Vec) -> Self { self.byweekno = Some(byweekno); self } + /// If given, it must be either an integer (0 == MO), a sequence of integers, one + /// of the weekday constants (MO, TU, etc), or a sequence of these constants. + /// When given, these variables will define the weekdays where the recurrence + /// will be applied. pub fn byweekday(mut self, byweekday: Vec) -> Self { let byweekday = byweekday.iter().map(|w| get_weekday_val(w)).collect(); self.byweekday = Some(byweekday); self } + /// If given, it must be either an integer, or a sequence of integers, + /// meaning the hours to apply the recurrence to. pub fn byhour(mut self, byhour: Vec) -> Self { self.byhour = Some(byhour); self } + /// If given, it must be either an integer, or a sequence of integers, + /// meaning the minutes to apply the recurrence to. pub fn byminute(mut self, byminute: Vec) -> Self { self.byminute = Some(byminute); self } + /// If given, it must be either an integer, or a sequence of integers, + /// meaning the seconds to apply the recurrence to. pub fn bysecond(mut self, bysecond: Vec) -> Self { self.bysecond = Some(bysecond); self } + /// If given, it must be either an integer, or a sequence of integers, positive or negative. + /// Each integer will define an offset from the Easter Sunday. Passing the offset 0 to + /// byeaster will yield the Easter Sunday itself. This is an extension to the RFC specification. pub fn byeaster(mut self, byeaster: isize) -> Self { self.byeaster = Some(byeaster); self } + /// Parses the opptions and build `ParsedOptions` if they are valid. + /// Otherwise an `RRuleParseError` will be returned. pub fn build(self) -> Result { parse_options(&self) } diff --git a/src/rrule.rs b/src/rrule.rs index 4ffcde9..c2a080e 100644 --- a/src/rrule.rs +++ b/src/rrule.rs @@ -11,7 +11,6 @@ pub struct RRule { pub options: ParsedOptions, } - impl RRule { pub fn new(options: ParsedOptions) -> Self { Self { options } diff --git a/src/rrulestr.rs b/src/rrulestr.rs index b798275..eb5a5be 100644 --- a/src/rrulestr.rs +++ b/src/rrulestr.rs @@ -5,22 +5,22 @@ use crate::rrule::RRule; use crate::rruleset::RRuleSet; use chrono::prelude::*; use chrono_tz::{Tz, UTC}; -use once_cell::sync::Lazy; use regex::Regex; use std::str::FromStr; -/// Some regex used for parsing the rrule string. -static DATESTR_RE: Lazy = - Lazy::new(|| Regex::new(r"(?m)^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z?)?$").unwrap()); -static DTSTART_RE: Lazy = - Lazy::new(|| Regex::new(r"(?m)DTSTART(?:;TZID=([^:=]+?))?(?::|=)([^;\s]+)").unwrap()); -static RRULE_RE: Lazy = Lazy::new(|| Regex::new(r"(?m)^(?:RRULE|EXRULE):").unwrap()); -static PARSE_LINE_RE_1: Lazy = Lazy::new(|| Regex::new(r"(?m)^\s+|\s+$").unwrap()); -static PARSE_LINE_RE_2: Lazy = Lazy::new(|| Regex::new(r"(?m)^([A-Z]+?)[:;]").unwrap()); -static RDATE_RE: Lazy = Lazy::new(|| Regex::new(r"(?m)RDATE(?:;TZID=([^:=]+))?").unwrap()); -static EXDATE_RE: Lazy = Lazy::new(|| Regex::new(r"(?m)EXDATE(?:;TZID=([^:=]+))?").unwrap()); -static DATETIME_RE: Lazy = - Lazy::new(|| Regex::new(r"(?m)(VALUE=DATE(-TIME)?)|(TZID=)").unwrap()); +// Some regex used for parsing the rrule string. +lazy_static! { + static ref DATESTR_RE: Regex = + Regex::new(r"(?m)^(\d{4})(\d{2})(\d{2})(T(\d{2})(\d{2})(\d{2})Z?)?$").unwrap(); + static ref DTSTART_RE: Regex = + Regex::new(r"(?m)DTSTART(?:;TZID=([^:=]+?))?(?::|=)([^;\s]+)").unwrap(); + static ref RRULE_RE: Regex = Regex::new(r"(?m)^(?:RRULE|EXRULE):").unwrap(); + static ref PARSE_LINE_RE_1: Regex = Regex::new(r"(?m)^\s+|\s+$").unwrap(); + static ref PARSE_LINE_RE_2: Regex = Regex::new(r"(?m)^([A-Z]+?)[:;]").unwrap(); + static ref RDATE_RE: Regex = Regex::new(r"(?m)RDATE(?:;TZID=([^:=]+))?").unwrap(); + static ref EXDATE_RE: Regex = Regex::new(r"(?m)EXDATE(?:;TZID=([^:=]+))?").unwrap(); + static ref DATETIME_RE: Regex = Regex::new(r"(?m)(VALUE=DATE(-TIME)?)|(TZID=)").unwrap(); +} fn parse_datestring_bit( bits: ®ex::Captures, diff --git a/src/utils.rs b/src/utils.rs index d19ca90..f5451ba 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -25,13 +25,12 @@ pub fn not_empty(v: &Vec) -> bool { !v.is_empty() } - #[cfg(test)] mod test { use super::*; #[test] - fn python_mod(){ + fn python_mod() { assert_eq!(pymod(2, -3), -1); assert_eq!(pymod(-2, 3), 1); assert_eq!(pymod(-2, -3), -2); @@ -47,7 +46,7 @@ mod test { } #[test] - fn includes_works(){ + fn includes_works() { assert!(!includes(&vec![], &0)); assert!(includes(&vec![1], &1)); assert!(includes(&vec![1, 2, 3, 4], &3)); @@ -55,8 +54,8 @@ mod test { } #[test] - fn not_empty_works(){ + fn not_empty_works() { assert!(!not_empty::(&vec![])); assert!(not_empty(&vec![1])); } -} \ No newline at end of file +} -- cgit v1.2.3