rrules

RRules

A blazing fast and memory efficient library to manage recurrence rules inspired by the standards from RFC-5547. It provides the ability to define recurrence rules for events, and then iterate over them to get the dates that match the recurrence rules.

How to use it

The easiest way to use this library is to start by loading a Recurrence instance from a string following the standards:

Loading from string

Required attributes:

Examples:

```rust // Daily recurrence example:

use std::str::FromStr; use chrono::{DateTime, Utc}; use rrules::Recurrence;

let recurrence = Recurrence::from_str("FREQ=DAILY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z").unwrap();

// You can then use the Recurrence as an iterator by looping over it or collecting the results into a Vec

for event in recurrence.clone().take(100) { // cloning to avoid moving the iterator // ... } // or let events: Vec> = recurrence.take(100).collect();

```

The Recurrence struct is an iterator that will yield all the dates that match the recurrence rules defined.

How to use it with structs definition

To define a recurrence rule, start by creating the desired frequency rule definition:

```rust use chrono::{Duration, Utc}; use rrules::Frequency; use rrules::Recurrence;

let daily = Frequency::Daily { interval: 1, by_time: vec![], };

// Then, create a Recurrence with the frequency defined:

let recurrence = Recurrence::new( daily, Utc::now(), // start date Some(Utc::now() + Duration::days(1)), // end date Some(Duration::hours(1)), // duration (optional ); ```

The end attribute of a Recurrence is optional, and if not specified, it will yield events until the MAX_DATE.

The MAX_DATE is defined as 9999-12-31T23:59:59Z

The duration attribute of a Recurrence is optional, and if not specified, it will use the default as 0 seconds Duration::seconds(0).

Attribute standards

| Attribute | Description | Example | |------------|----------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------| | FREQ | Defines the type of frequency (E.g. DAILY, WEEKLY, MONTHLY, etc) | FREQ=DAILY | | INTERVAL | Defines the interval of the frequency (E.g. every 2 days, every 3 months, etc) | INTERVAL=2 | | DTSTART | Defines the start date of the recurrence | DTSTART=2023-01-01T12:00:00Z | | DTEND | Defines the end date of the recurrence | DTEND=2023-01-01T12:00:00Z | | DURATION | Defines the duration of the recurrence | DURATION=PT1H | | BYDAY | Defines the days of the week that the recurrence will happen | BYDAY=MO,TU -> When FREQ=WEEKLY; BYDAY=1MO,3WE -> When FREQ=MONTHLY | | BYMONTHDAY | Defines the days of the month that the recurrence will happen | BYMONTHDAY=1,2,3,4, etc | | 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 |

Supported recurrence rule types + examples

Current supporting recurrence rules:

Secondly Frequencies

Represents the rules for a recurrence that happens every x seconds.

```rust use std::str::FromStr; use rrules::Recurrence;

let everysecondrecurrence = Recurrence::from_str( "FREQ=SECONDLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z" ).unwrap(); ```

Minutely Frequencies

Represents the rules for a recurrence that happens every x minutes.

```rust use std::str::FromStr; use rrules::Recurrence;

let every5minutes = Recurrence::from_str( "FREQ=MINUTELY;INTERVAL=5;DTSTART=2023-01-01T12:00:00Z" ).unwrap(); ```

Hourly Frequencies

Represents the rules for a recurrence that happens every x hours.

```rust use std::str::FromStr; use rrules::Recurrence;

let every6hours = Recurrence::from_str( "FREQ=HOURLY;INTERVAL=6;DTSTART=2023-01-01T12:00:00Z" ).unwrap(); ```

Daily Frequencies

Represents the rules for a recurrence that happens x times every x days.

```rust use std::str::FromStr; use rrules::Recurrence;

let every3days = Recurrence::from_str( "FREQ=DAILY;INTERVAL=3;DTSTART=2023-01-01T12:00:00Z" ).unwrap();

let everydayat8am = Recurrence::fromstr( "FREQ=DAILY;INTERVAL=1;DTSTART=2023-01-01T08:00:00Z" ).unwrap();

let everyotherdayat12pmand16pm = Recurrence::from_str( "FREQ=DAILY;INTERVAL=2;DTSTART=2023-01-01T00:00:00Z;BYTIME=12:00,16:00" ).unwrap(); ```

Weekly Frequencies

Represents the rules for a recurrence that happens x times every x weeks.

```rust use std::str::FromStr; use rrules::Recurrence;

let everyweek = Recurrence::fromstr( "FREQ=WEEKLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z" ).unwrap();

let everyweekmonandtue = Recurrence::from_str( "FREQ=WEEKLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=MO,TU" ).unwrap(); ```

Monthly Frequencies

Represents the rules for a recurrence that happens x times every x months.

rust use std::str::FromStr; use rrules::Recurrence; let monthly = Recurrence::from_str( "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z" ).unwrap();

Monthly by month day

When specifying BYMONTHDAY, it will only yield the dates that match the days of the month specified.

```rust use std::str::FromStr; use rrules::Recurrence; let every15th = Recurrence::fromstr( "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTHDAY=15" ).unwrap();

let every15thand25th = Recurrence::fromstr( "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTHDAY=15,25" ).unwrap(); ```

Monthly by nth day

When specifying BYDAY, it will only yield the dates that match the nth days of the week specified. I.g. if you want to have a recurrence every first Monday of the month, you can do:

```rust use std::str::FromStr; use rrules::Recurrence; let everyfirstmonday = Recurrence::from_str( "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=1MO" ).unwrap();

let everyfirstmondayandwednesday = Recurrence::from_str( "FREQ=MONTHLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYDAY=1MO,1WE" ).unwrap(); ```

Yearly Frequencies

Represents the rules for a recurrence that happens x times every x years.

rust use std::str::FromStr; use rrules::Recurrence; let yearly = Recurrence::from_str( "FREQ=YEARLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z" ).unwrap();

Yearly by month day

When specifying BYMONTH and BYMONTHDAY, it will only yield the dates that match the days of the month specified. E.g. if you want to have a recurrence every 15th January of the year, you can do:

rust use std::str::FromStr; use rrules::Recurrence; let every_15th_january = Recurrence::from_str( "FREQ=YEARLY;INTERVAL=1;DTSTART=2023-01-01T12:00:00Z;BYMONTH=1;BYMONTHDAY=15" ).unwrap();

License: MIT