cron_lingo/
lib.rs

1//! This crate allows to parse a cron-like, human-readable expression.
2//! The resulting object can be turned into an iterator to compute the next date
3//! (as a `time::OffsetDateTime`) one at a time. By default dates are computed
4//! in the current local offset, but the iterator can be configured to use other
5//! offsets.
6//!
7//! # Example
8//! ```rust
9//! use cron_lingo::Schedule;
10//! use std::str::FromStr;
11//! use time::macros::offset;
12//!
13//! fn main() -> Result<(), cron_lingo::error::Error> {
14//!     // Create a schedule from an expression and iterate.
15//!     let expr = "at 6:30 AM on Mondays and Thursdays";
16//!     let schedule1 = Schedule::from_str(expr)?;
17//!     assert!(schedule1.iter()?.next().is_some());
18//!
19//!     // Create another schedule, add it to the first, and then iterate.
20//!     let schedule2 = Schedule::from_str("at 8 PM on the first Sunday")?;
21//!     let mut combination = schedule1 + schedule2;
22//!     assert!(combination.iter()?.next().is_some());
23//!
24//!     // Finally add another to the existing collection of schedules.
25//!     let schedule3 = Schedule::from_str("at 12:00 PM on the last Friday")?;
26//!     combination += schedule3;
27//!     assert!(combination.iter()?.next().is_some());
28//!
29//!     // The examples above assume that the current local offset is to
30//!     // be used to determine the dates, but dates can also be computed
31//!     // in different offsets.
32//!     let expr = "at 6:30 AM on Mondays and Thursdays";
33//!     let schedule = Schedule::from_str(expr)?;
34//!     assert!(schedule.iter()?.assume_offset(offset!(+3)).next().is_some());
35//!     Ok(())
36//! }
37//! ```
38//!
39//! # Expression syntax
40//!
41//! A single expression consists of three parts:
42//! a time specification, and optionally a weekday and week specification.
43//!
44//! > \<time spec\> [\<weekday spec\>] [\<week spec\>]
45//!
46//! Here are a few random examples of complete expressions:
47//!
48//! * at 1 AM
49//! * 6 PM on Saturdays and Sundays
50//! * at 2 PM (Mondays, Thursdays) in even weeks
51//! * at 6:45 PM on Wednesdays in odd weeks
52//! * at 6:30 AM on Mondays
53//! * at 6 AM, 6 PM (Mondays)
54//! * at 8 AM on the first Sunday
55//!
56//! This table gives some more examples for each type of specification in a block:
57//!
58//! | Times                  | Weekday (optional)           | Week (optional)  |
59//! | ---------------------- | ---------------------------- | ---------------- |
60//! | at every full hour     | on Mondays and Tuesdays      | in odd weeks     |
61//! | at 7:30 AM and 7:30 PM | on Tuesdays, Saturdays       | in even weeks    |
62//! | at 6 AM, 6 PM and 8 PM | on Fridays                   |                  |
63//! | at 6 AM, 12 AM, 6 PM   |                              |                  |
64//! | at 8:30 AM             |                              | in odd weeks     |
65//! | at 8 AM                | on Wednesdays                |                  |
66//! | at 08 AM               | on the first Monday          |                  |
67//! | at 08 PM               | on the 4th Friday            | in even weeks    |
68//! | at 08 PM               | on Wednesdays and Sundays    |                  |
69//! | at 5:45 AM             | (Mondays and Thursdays)      |                  |
70//! | at 6 AM and 6 PM       | (first Sunday)               |                  |
71//! | at 1:15 PM             | (1st Monday and 2nd Friday)  |                  |
72//! | at 1 PM                | on the third Monday          |                  |
73//! | at 1:50 PM             | on the 3rd Monday            |                  |
74//! | at 1 PM                | on the 4th Saturday          |                  |
75//! | at 6 PM                | on the last Monday           |                  |
76//!
77//! ## Ruleset
78//!
79//! The examples above cover the basic rules of the expression syntax to a certain (and for most use cases
80//! probably sufficient) extent.
81//! Nevertheless, here is a list of "rules" that an expression must comply with and that you might find useful to avoid mistakes:
82//!
83//! ### Times specification
84//!
85//! * must start with _at_
86//! * then follows either _every full hour_ OR a list of distinct _times_
87//! * a _time_ adheres to the 12-hour-clock, so a number from 1 to 12 followed by _AM_ or _PM_ (uppercase!), e.g. 1 AM or 1 PM
88//! * a time may also contain _minutes_ from 00 to 59 (separated from the hour by a _colon_). Omitting the minutes means
89//! _on the hour_, e.g. 8 PM == 8:00 PM
90//! * distinct times are concatenated by _commata_ or _and_
91//!
92//! ### Weekday specification
93//!
94//! * is _optional_
95//! * succeeds the _time spec_
96//! * consists of a list of _weekdays_ with optional _modifiers_ to select only specific weekdays in a month.
97//! * the list either starts with _on_ OR is enclosed by simple braces _()_ for compactness
98//! * a weekday must be one of [ Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday ] appended with an ***s*** if e.g. _every_ Monday is to be included OR a weekday preceded by a modifier [ first | 1st | second | 2nd | third | 3rd | fourth | 4th | last ] in order to include only specific weekdays in a month.
99//!
100//! ### Week specification
101//!
102//! * is _optional_
103//! * must be one of _in even weeks_ / _in odd weeks_
104pub mod error;
105mod parse;
106pub mod schedule;
107mod types;
108
109pub use self::schedule::Schedule;