rrules/lib.rs
1//! # RRules
2//!
3//! A blazing fast and memory efficient library to manage recurrence rules inspired by the standards from [RFC-5547](https://icalendar.org/iCalendar-RFC-5545/3-3-10-recurrence-rule.html).
4//! It provides the ability to define recurrence rules for events, and then iterate over them to get the dates that match the recurrence rules.
5//!
6//! ## How to use it
7//!
8//! The easiest way to use this library is to start by loading a Recurrence instance from a string following the [standards](#standards):
9//!
10//! ### Loading from string
11//!
12//! #### Required attributes:
13//!
14//! - FREQ
15//! - Defines the type of frequency (E.g. DAILY, WEEKLY, MONTHLY, etc)
16//! - INTERVAL
17//! - Defines the interval of the frequency (E.g. every 2 days, every 3 months, etc)
18//! - DTSTART
19//! - Defines the start date of the recurrence
20//!
21//! Examples:
22//!
23//! ```rust
24//! // Daily recurrence example:
25//!
26//! use std::str::FromStr;
27//! use chrono::{DateTime, Utc};
28//! use rrules::Recurrence;
29//!
30//! let recurrence = Recurrence::from_str("FREQ=DAILY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z").unwrap();
31//!
32//! // You can then use the `Recurrence` as an iterator by looping over it or collecting the results into a `Vec`
33//!
34//! for event in recurrence.clone().take(100) { // cloning to avoid moving the iterator
35//! // ...
36//! }
37//! // or
38//! let events: Vec<DateTime<Utc>> = recurrence.take(100).collect();
39//!
40//! ```
41//!
42//! > The `Recurrence` struct is an iterator that will yield all the dates that match the recurrence rules defined.
43//!
44//!
45//! ### How to use it with structs definition
46//!
47//! To define a recurrence rule, start by creating the desired `frequency` rule definition:
48//!
49//! ```rust
50//! use chrono::{Duration, Utc};
51//! use rrules::Frequency;
52//! use rrules::Recurrence;
53//!
54//! let daily = Frequency::Daily {
55//! interval: 1,
56//! by_time: vec![],
57//! };
58//!
59//! // Then, create a `Recurrence` with the frequency defined:
60//!
61//! let recurrence = Recurrence::new(
62//! daily,
63//! Utc::now(), // start date
64//! Some(Utc::now() + Duration::days(1)), // end date
65//! Some(Duration::hours(1)), // duration (optional
66//! );
67//! ```
68//!
69//! The `end` attribute of a `Recurrence` is optional, and if not specified, it will yield events until the `MAX_DATE`.
70//! > The `MAX_DATE` is defined as `9999-12-31T23:59:59Z`
71//!
72//! The `duration` attribute of a `Recurrence` is optional, and if not specified, it will use the default as 0 seconds `Duration::seconds(0)`.
73//!
74//! <span id="standards"></span>
75//! ## Attribute standards
76//!
77//! | Attribute | Description | Example |
78//! |------------|----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|
79//! | FREQ | Defines the type of frequency (E.g. DAILY, WEEKLY, MONTHLY, etc) | FREQ=DAILY |
80//! | INTERVAL | Defines the interval of the frequency (E.g. every 2 days, every 3 months, etc) | INTERVAL=2 |
81//! | DTSTART | Defines the start date of the recurrence | DTSTART=2023-01-01T12:00:00Z |
82//! | DTEND | Defines the end date of the recurrence | DTEND=2023-01-01T12:00:00Z |
83//! | DURATION | Defines the duration of the recurrence | DURATION=PT1H |
84//! | BYDAY | Defines the days of the week that the recurrence will happen | BYDAY=MO,TU -> When FREQ=WEEKLY; BYDAY=1MO,3WE -> When FREQ=MONTHLY |
85//! | BYMONTHDAY | Defines the days of the month that the recurrence will happen | BYMONTHDAY=1,2,3,4, etc |
86//! | BYMONTH | Defines the months of the year that the recurrence will happen | BYMONTH=1,2,3,4,5,6,7,8,9,10,11,12 |
87//!
88//!
89//! ## Supported recurrence rule types + examples
90//! Current supporting recurrence rules:
91//!
92//! - [Secondly](#secondly)
93//! - [minutely](#minutely)
94//! - [hourly](#hourly)
95//! - [Daily](#daily)
96//! - [Weekly](#weekly)
97//! - [Monthly](#monthly)
98//! - [By month day](#monthly-by-month-day)
99//! - [By nth weekday](#monthly-by-day)
100//! - [Yearly](#yearly)
101//! - [By day](#yearly-by-day)
102//! - [By month day](#yearly-by-month-day)
103//!
104//!
105//! <span id="secondly"></span>
106//! ### Secondly Frequencies
107//! Represents the rules for a recurrence that happens every x seconds.
108//!
109//! ```rust
110//! use std::str::FromStr;
111//! use rrules::Recurrence;
112//!
113//! let every_second_recurrence = Recurrence::from_str(
114//! "FREQ=SECONDLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z"
115//! ).unwrap();
116//! ```
117//!
118//! <span id="minutely"></span>
119//! ### Minutely Frequencies
120//! Represents the rules for a recurrence that happens every x minutes.
121//!
122//! ```rust
123//! use std::str::FromStr;
124//! use rrules::Recurrence;
125//!
126//! let every_5_minutes = Recurrence::from_str(
127//! "FREQ=MINUTELY;INTERVAL=5;DTSTART=2023-01-01T12:00:00Z"
128//! ).unwrap();
129//! ```
130//!
131//! <span id="hourly"></span>
132//! ### Hourly Frequencies
133//! Represents the rules for a recurrence that happens every x hours.
134//!
135//! ```rust
136//! use std::str::FromStr;
137//! use rrules::Recurrence;
138//!
139//! let every_6_hours = Recurrence::from_str(
140//! "FREQ=HOURLY;INTERVAL=6;DTSTART=2023-01-01T12:00:00Z"
141//! ).unwrap();
142//! ```
143//!
144//! <span id="daily"></span>
145//! ### Daily Frequencies
146//! Represents the rules for a recurrence that happens x times every x days.
147//!
148//! ```rust
149//! use std::str::FromStr;
150//! use rrules::Recurrence;
151//!
152//! let every_3_days = Recurrence::from_str(
153//! "FREQ=DAILY;INTERVAL=3;DTSTART=2023-01-01T12:00:00Z"
154//! ).unwrap();
155//!
156//! let every_day_at_8am = Recurrence::from_str(
157//! "FREQ=DAILY;INTERVAL=1;DTSTART=2023-01-01T08:00:00Z"
158//! ).unwrap();
159//!
160//! let every_other_day_at_12pm_and_16pm = Recurrence::from_str(
161//! "FREQ=DAILY;INTERVAL=2;DTSTART=2023-01-01T00:00:00Z;BYTIME=12:00,16:00"
162//! ).unwrap();
163//! ```
164//!
165//! <span id="weekly"></span>
166//! ### Weekly Frequencies
167//! Represents the rules for a recurrence that happens x times every x weeks.
168//!
169//! ```rust
170//! use std::str::FromStr;
171//! use rrules::Recurrence;
172//!
173//! let every_week = Recurrence::from_str(
174//! "FREQ=WEEKLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z"
175//! ).unwrap();
176//!
177//! let every_week_mon_and_tue = Recurrence::from_str(
178//! "FREQ=WEEKLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=MO,TU"
179//! ).unwrap();
180//! ```
181//! <span id="monthly"></span>
182//! ### Monthly Frequencies
183//! Represents the rules for a recurrence that happens x times every x months.
184//!
185//! ```rust
186//! use std::str::FromStr;
187//! use rrules::Recurrence;
188//! let monthly = Recurrence::from_str(
189//! "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z"
190//! ).unwrap();
191//! ```
192//!
193//! <span id="monthly-by-month-day"></span>
194//! #### Monthly by month day
195//!
196//! When specifying `BYMONTHDAY`, it will only yield the dates that match the days of the month specified.
197//!
198//! ```
199//! use std::str::FromStr;
200//! use rrules::Recurrence;
201//! let every_15th = Recurrence::from_str(
202//! "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTHDAY=15"
203//! ).unwrap();
204//!
205//! let every_15th_and_25th = Recurrence::from_str(
206//! "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTHDAY=15,25"
207//! ).unwrap();
208//! ```
209//!
210//! <span id="monthly-by-day"></span>
211//! #### Monthly by nth day
212//!
213//! When specifying `BYDAY`, it will only yield the dates that match the nth days of the week specified.
214//! I.g. if you want to have a recurrence every first Monday of the month, you can do:
215//!
216//! ```rust
217//! use std::str::FromStr;
218//! use rrules::Recurrence;
219//! let every_first_monday = Recurrence::from_str(
220//! "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=1MO"
221//! ).unwrap();
222//!
223//! let every_first_monday_and_wednesday = Recurrence::from_str(
224//! "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=1MO,1WE"
225//! ).unwrap();
226//! ```
227//!
228//! <span id="yearly"></span>
229//! ### Yearly Frequencies
230//! Represents the rules for a recurrence that happens x times every x years.
231//!
232//! ```rust
233//! use std::str::FromStr;
234//! use rrules::Recurrence;
235//! let yearly = Recurrence::from_str(
236//! "FREQ=YEARLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z"
237//! ).unwrap();
238//! ```
239//!
240//! <span id="yearly-by-month-day"></span>
241//! #### Yearly by month day
242//!
243//! When specifying `BYMONTH` and `BYMONTHDAY`, it will only yield the dates that match the days of the month specified.
244//! E.g. if you want to have a recurrence every 15th January of the year, you can do:
245//!
246//! ```rust
247//! use std::str::FromStr;
248//! use rrules::Recurrence;
249//! let every_15th_january = Recurrence::from_str(
250//! "FREQ=YEARLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTH=1;BYMONTHDAY=15"
251//! ).unwrap();
252//! ```
253
254extern crate core;
255
256pub mod frequencies;
257pub mod recurrences;
258mod utils;
259pub use frequencies::*;
260pub use recurrences::*;
261pub use frequencies::{Frequency, MonthlyDate, NthWeekday, Time};
262pub use recurrences::{Recurrence, RecurrenceInvalid};