Expand description
A performant rust implementation of recurrence rules as defined in the iCalendar RFC.
This crate provides RRuleSet
for working with recurrence rules. It has a collection of DTSTART
, RRULE
s, EXRULE
s, RDATE
s and EXDATE
s. Both the RRULE
and EXRULE
properties are represented by the RRule
type and the DTSTART
, RDATE
and EXDATE
properties are represented by the chrono::DateTime<Tz>
.
Building RRule
and RRuleSet
Both types implements the std::str::FromStr
trait so that they can be parsed and built from a string representation.
RRuleSet
can also be built by composing multiple RRule
s for its rrule
and exrule
properties and chrono::DateTime<Tz>
for its
dt_start
, exdate
and rdate
properties. See the examples below.
Generating occurrences
You can loop over the occurrences of a RRuleSet
by calling any of the following methods:
RRuleSet::all
: Generate all recurrences that match the rules (with a limit to prevent infinite loops).RRuleSet::all_between
: Generate all recurrences that match the rules and are between two given dates.RRuleSet::just_before
: Generate the last recurrence that matches the rules and is before a given date.RRuleSet::just_after
: Generate the first recurrence that matches the rules and is after a given date.- …
If you have some additional filters or want to work with infinite recurrence rules
RRuleSet
implements the Iterator
trait which makes them very flexible.
All the methods above uses the iterator trait in its implementation as shown below.
use chrono::{DateTime, TimeZone};
use chrono_tz::UTC;
use rrule::{RRuleSet};
let rrule: RRuleSet = "DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3".parse().unwrap();
// All dates
assert_eq!(
vec![
DateTime::parse_from_rfc3339("2012-02-01T09:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-02-02T09:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-02-03T09:30:00+00:00").unwrap(),
],
rrule.all(100).unwrap()
);
Find all events that are within a given range.
let rrule: RRuleSet = "DTSTART:20120201T093000Z\nRRULE:FREQ=DAILY;COUNT=3".parse().unwrap();
// Between two dates
let after = UTC.ymd(2012, 2, 1).and_hms(10, 0, 0);
let before = UTC.ymd(2012, 4, 1).and_hms(9, 0, 0);
let inc = true; // Whether dates equal to after or before should be added;
assert_eq!(
vec![
DateTime::parse_from_rfc3339("2012-02-02T09:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-02-03T09:30:00+00:00").unwrap(),
],
rrule.all_between(after, before, inc).unwrap()
);
Note: All the generated recurrence will be in the same time zone as the dt_start
property.
Example
Quick start by parsing strings
use chrono::DateTime;
use rrule::{RRuleSet};
// Parse a RRule string
let rrule: RRuleSet = "DTSTART:20120201T093000Z\n\
RRULE:FREQ=WEEKLY;INTERVAL=5;UNTIL=20130130T230000Z;BYDAY=MO,FR".parse().unwrap();
assert_eq!(rrule.all(100).unwrap().len(), 21);
// Parse a RRuleSet string
let rrule_set: RRuleSet = "DTSTART:20120201T023000Z\n\
RRULE:FREQ=MONTHLY;COUNT=5\n\
RDATE:20120701T023000Z,20120702T023000Z\n\
EXRULE:FREQ=MONTHLY;COUNT=2\n\
EXDATE:20120601T023000Z".parse().unwrap();
let all_dates = rrule_set.all(100).unwrap();
assert_eq!(all_dates.len(), 4);
assert_eq!(
vec![
DateTime::parse_from_rfc3339("2012-04-01T02:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-05-01T02:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-07-01T02:30:00+00:00").unwrap(),
DateTime::parse_from_rfc3339("2012-07-02T02:30:00+00:00").unwrap(),
],
all_dates
);
Structs
Represents a complete RRULE property based on the iCalendar specification
It has two stages, based on the attached type, Validated
or Unvalidated
.
A validated Recurrence Rule that can be used to create an iterator.
Iterator over all the dates in an RRuleSet
.
An empty struct to keep the unvalidated (or not-yet-validated) stage
An empty struct to keep the validated stage
Enums
The frequency of a recurrence.
This indicates the nth occurrence of a specific day within a MONTHLY or YEARLY RRULE.
The error type for the rrule crate.
The day of week.
Traits
A trait for crate::RRuleSetIter
and the private crate::RRuleIter
to handle their errors.