diff options
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | src/iter/mod.rs | 28 | ||||
-rw-r--r-- | src/lib.rs | 23 | ||||
-rw-r--r-- | src/utils.rs | 25 |
4 files changed, 48 insertions, 38 deletions
@@ -6,6 +6,12 @@ <a href="https://crates.io/crates/rrule"><img src="https://img.shields.io/crates/v/rrule.svg" /></a> </p> +## Warning + +This crate is not production ready yet. Dates and recurrence rules are quite complicated and +takes time to get right. Even though this crate is well tested (high code coverage), there are still +tests missing around edge cases like DST, time zone and rfc_string parsing. Use at your own risk! + ## :zap: Quick start ```rust @@ -34,7 +40,3 @@ This project is licensed under the [MIT license]. - [python-dateutil library](http://labix.org/python-dateutil/) - [rrule.js](https://github.com/jakubroztocil/rrule) - -## Todos - -- cache diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 5e6e4d1..05b588d 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -9,6 +9,7 @@ mod masks; use crate::datetime::{from_ordinal, get_weekday_val, DTime, Time}; use crate::options::*; +use crate::utils::{includes, not_empty}; use chrono::offset::TimeZone; use chrono::prelude::*; use chrono::Duration; @@ -262,17 +263,6 @@ pub fn increment_counter_date( } } -pub fn includes<T>(v: &Vec<T>, el: &T) -> bool -where - T: PartialEq, -{ - v.iter().any(|ve| ve == el) -} - -pub fn not_empty<T>(v: &Vec<T>) -> bool { - !v.is_empty() -} - pub fn is_filtered(ii: &IterInfo, current_day: usize, options: &ParsedOptions) -> bool { return (not_empty(&options.bymonth) && !includes(&options.bymonth, &ii.mmask().unwrap()[current_day])) @@ -316,14 +306,14 @@ pub fn remove_filtered_days( let mut filtered = false; for daycounter in start..end { - let current_day = dayset[daycounter]; - if current_day.is_none() { - continue; - } - - filtered = is_filtered(ii, current_day.unwrap() as usize, options); - if filtered { - dayset[daycounter] = None; + match dayset[daycounter] { + Some(current_day) => { + filtered = is_filtered(ii, current_day as usize, options); + if filtered { + dayset[daycounter] = None; + } + } + None => continue } } filtered @@ -1,13 +1,13 @@ //! A performant rust implementation of recurrence rules as defined in the iCalendar RFC. //! -//! RRule provides two main types for working with recurrence rules: +//! RRule provides two types for working with recurrence rules: //! - `RRule`: For working with a single recurrence rule without any exception dates (exdates / exrules) and no additonal dates (rdate). -//! - `RRuleSet`: For working with a collection of rrule`s, exrule`s, rdate`s and exdate`s. Both the rrule and exrule +//! - `RRuleSet`: For working with a collection of rrules, exrules, rdates and exdates. Both the rrule and exrule //! properties are represented by the `RRule` type and the rdate and exdate properties are represented by the DateTime<Tz> type //! provided by the [chrono](https://crates.io/crates/chrono) and [chrono-tz](https://crates.io/crates/chrono-tz) crates. //! //! # Building RRule and RRuleSet -//! Both types implements the `std::str::FromStr` trait so that they can be parsed and built from a `str`. `RRule` +//! Both types implements the `std::str::FromStr` trait so that they can be parsed and built from a string representation. `RRule` //! can additionally be constructured from the `Option` type which help build the recurrence rule. `RRuleSet` //! can also be built by composing mutliple `RRule`s for its rrule and exrule properties and DateTime<Tz> for its //! exdate and rdate properties. See the examples below. @@ -18,7 +18,7 @@ //! - `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. //! //! # Examples //! @@ -132,8 +132,10 @@ //! //! //! -//! Timezone support -//! +//! Timezone support. +//! The following examples uses `RRuleSet` with one `RRule` that yields recurrences +//! in the Europe/Berlin timezone, and one EXDATE that is specified +//! in UTC and collides with one of those recurrences. //! ``` //! extern crate rrule; //! extern crate chrono; @@ -144,15 +146,6 @@ //! use chrono_tz::Europe::Berlin; //! use rrule::{RRule, RRuleSet, Options, Frequenzy, Weekday}; //! -//! // SOME NOTES: -//! // recurrences produced by an rrule will be in the same timezone -//! // as the start datetime provided (dtstart). The `until` datetime MUST -//! // always be specified with the UTC timezone if it is specified. -//! -//! // Example: -//! // The following examples uses the RRuleSet type with an RRule that yields recurrences -//! // in the Europe/Berlin timezone, and one EXDATE that is specified -//! // in UTC and collides (and therefore filters away) with one of those recurrences. //! //! //! // Build options for rrule that occurs daily at 9 oclock for 4 times diff --git a/src/utils.rs b/src/utils.rs index 161e6c2..d19ca90 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,6 +14,17 @@ pub fn is_some_and_not_empty<T>(v: &Option<Vec<T>>) -> bool { } } +pub fn includes<T>(v: &Vec<T>, el: &T) -> bool +where + T: PartialEq, +{ + v.iter().any(|ve| ve == el) +} + +pub fn not_empty<T>(v: &Vec<T>) -> bool { + !v.is_empty() +} + #[cfg(test)] mod test { @@ -34,4 +45,18 @@ mod test { assert_eq!(pymod(-6, -3), 0); assert_eq!(pymod(6, -3), 0); } + + #[test] + fn includes_works(){ + assert!(!includes(&vec![], &0)); + assert!(includes(&vec![1], &1)); + assert!(includes(&vec![1, 2, 3, 4], &3)); + assert!(!includes(&vec![1, 2, 3, 4], &5)); + } + + #[test] + fn not_empty_works(){ + assert!(!not_empty::<usize>(&vec![])); + assert!(not_empty(&vec![1])); + } }
\ No newline at end of file |