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;