cron_lite/lib.rs
1//! Lightweight cron expression parser and time series generator.
2#![deny(unsafe_code, warnings, missing_docs)]
3
4//! This is a tiny crate, intended to:
5//! - parse almost all kinds of popular cron schedule formats;
6//! - generates a series of timestamps according to the schedule.
7//!
8//! It has a single external dependency - [chrono](https://crates.io/crates/chrono) (with default features set).
9//!
10//! _This is not a cron jobs scheduler or runner._ If you need a scheduler/runner,
11//! look for [sacs](https://crates.io/crates/sacs)
12//! of any [other similar crate](https://crates.io/search?q=async%20cron%20scheduler).
13//!
14//! ## Cron schedule format
15//!
16//! Traditionally, cron schedule expression has a 5-field format: minutes, hours, days, months, and days of the week.
17//! This crate uses such a format by default, but two optional fields may be added, seconds and years:
18//! - if _seconds_ is empty, `0` is used by default;
19//! - if _years_ is empty, `*` is used by default;
20//! - if 6-fields schedule is specified, then _seconds_ filed is assumed as first and years as empty (default).
21//!
22//! The table below describes valid values and patterns of each field:
23//!
24//! | Field | Required | Allowed values | Allowed special characters |
25//! |--------------|----------|-----------------|----------------------------|
26//! | Seconds | No | 0-59 | * , - / |
27//! | Minutes | Yes | 0-59 | * , - / |
28//! | Hours | Yes | 0-23 | * , - / |
29//! | Day of Month | Yes | 1-31 | * , - / ? L W |
30//! | Month | Yes | 1-12 or JAN-DEC | * , - / |
31//! | Day of Week | Yes | 0-6 or SUN-SAT | * , - ? L # |
32//! | Year | No | 1970-2099 | * , - / |
33//!
34//! Patterns meanings:
35//! - `*` - each possible value, i.e. `0,1,2,...,59` for minutes;
36//! - `,` - list of values or patterns, i.e. `1,7,12`, `SUN,FRI`;
37//! - `-` - range of values, i.e. `0-15`, `JAN-MAR`;
38//! - `/` - repeating values, i.e. `*/12`, `10/5`, `30-59/2`;
39//! - `L` - last day of the month (for month field), or last particular day of the week (for weekday field), i.e. `L` or `5L`;
40//! - `W` - the weekday (not Sunday or Saturday), nearest to the specified days of month in the same month, i.e. `22W`;
41//! - `#` - specific day of the week, i.e. `fri#1`, `1#4`;
42//! - `?` - for days of month or week means that value doesn't matter: if day of month is specified (not `*`), then day of week should be `?` and vise versa.
43//!
44//! Also, short aliases for well-known schedule expressions are allowed:
45//!
46//! | Alias | Expression |
47//! |----------------------------|---------------|
48//! | `@yearly` (or `@annually`) | 0 0 0 1 1 ? * |
49//! | `@monthly` | 0 0 0 1 * ? * |
50//! | `@weekly` | 0 0 0 ? * 0 * |
51//! | `@daily` (or `@midnight`) | 0 0 0 * * * * |
52//! | `@hourly` | 0 0 * * * * * |
53//!
54//! Some additional information and fields description and relationships may be found [here](https://en.wikipedia.org/wiki/Cron#Cron_expression) (this is not complete or exceptional documentation).
55//!
56//! ### Schedule with timezone
57//! If `tz` feature is enabled, it's possible to prefix cron schedule with timezone, for example:
58//! - `TZ=Europe/Paris @monthly`
59//! - `TZ=EET 0 12 * * *`
60//!
61//! ## How to use
62//!
63//! The single public entity of the crate is a [`Schedule`] structure, which has several basic methods:
64//! - [new()](Schedule::new): constructor to parse and validate provided schedule;
65//! - [upcoming()](Schedule::upcoming): returns time of the next schedule's event, starting from the provided timestamp;
66//! - [iter()](Schedule::iter): returns an `Iterator` which produces a series of timestamps according to the schedule;
67//! - [sleep()](Schedule::sleep): falls asleep until time of the upcoming schedule's event (`async` feature only);
68//! - [stream()](Schedule::stream): construct `Stream` which asynchronously generates events right in scheduled time (`async` feature only).
69//!
70//! ### Example with `upcoming`
71//! ```rust
72//! use chrono::Utc;
73//! use cron_lite::{Result, Schedule};
74//!
75//! fn upcoming() -> Result<()> {
76//! let schedule = Schedule::new("0 0 0 * * *")?;
77//! let now = Utc::now();
78//!
79//! // Get the next event's timestamp starting from now
80//! let next = schedule.upcoming(&now);
81//! assert!(next.is_some());
82//!
83//! println!("next: {:?}", next.unwrap());
84//!
85//!
86//! Ok(())
87//! }
88//! ```
89//!
90//! ### Example with `iter`
91//! ```rust
92//! use chrono::Utc;
93//! use cron_lite::{Result, Schedule};
94//!
95//! fn iterator() -> Result<()> {
96//! let schedule = Schedule::new("0 0 0 * * *")?;
97//! let now = Utc::now();
98//!
99//! // Get the next 10 timestamps starting from now
100//! schedule.iter(&now).take(10).for_each(|t| println!("next: {t}"));
101//!
102//! Ok(())
103//! }
104//! ```
105//!
106//! ### Example with `stream`
107//! ```rust
108//! # #[cfg(feature = "async")]
109//! # mod wrapper {
110//! use chrono::Local;
111//! use cron_lite::{CronEvent, Result, Schedule};
112//! use futures::stream::StreamExt;
113//!
114//! async fn stream() -> Result<()> {
115//! let schedule = Schedule::new("*/15 * * * * *")?;
116//! let now = Local::now();
117//!
118//! // Wake up every 15 seconds 10 times starting from now but skip the first event.
119//! let mut s = schedule.stream(&now).skip(1).take(10);
120//! while let Some(event) = s.next().await {
121//! assert!(matches!(event, CronEvent::Ok(_)));
122//! println!("next: {event:?}");
123//! }
124//!
125//! Ok(())
126//! }
127//! # }
128//! ```
129//!
130//! # Feature flags
131//! * `serde`: adds [`Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) trait implementation for [`Schedule`].
132//! * `tz`: enables support of cron [schedules with timezone](#schedule-with-timezone).
133//! * `async`: adds several methods to use in async environments. See documentation for details.
134
135#[cfg(feature = "async")]
136/// Provides several additional methods to [`Schedule`] to use in asynchronous code with any runtime.
137pub mod asynchronous;
138/// Crate specific Error implementation.
139pub mod error;
140mod pattern;
141/// Cron schedule pattern parser and upcoming events generator.
142pub mod schedule;
143mod series;
144mod utils;
145
146// Re-export of public entities.
147#[cfg(feature = "async")]
148pub use asynchronous::CronEvent;
149#[cfg(feature = "async")]
150pub use asynchronous::CronSleep;
151#[cfg(feature = "async")]
152pub use asynchronous::CronStream;
153
154pub use error::CronError;
155pub use schedule::Schedule;
156
157/// Convenient alias for `Result`.
158pub type Result<T, E = CronError> = std::result::Result<T, E>;