cron_tab/
lib.rs

1//! # CronTab - A Modern Rust Cron Job Scheduler
2//!
3//! CronTab is a feature-rich cron job scheduling library for Rust applications that provides
4//! both synchronous and asynchronous job execution with timezone support and high performance.
5//!
6//! ## Features
7//!
8//! - **Dual Execution Modes**: Support for both synchronous and asynchronous job execution
9//! - **Timezone Support**: Full timezone handling with chrono integration
10//! - **High Performance**: Efficient job scheduling with minimal overhead
11//! - **Thread Safety**: Built with Rust's safety guarantees in mind
12//! - **Flexible Scheduling**: Standard cron expressions with second precision
13//! - **Runtime Control**: Add, remove, start, and stop jobs at runtime
14//!
15//! ## Installation
16//!
17//! Add CronTab to your `Cargo.toml`:
18//!
19//! ```toml
20//! [dependencies]
21//! # For both sync and async support
22//! cron_tab = { version = "0.2", features = ["sync", "async"] }
23//!
24//! # For sync only
25//! cron_tab = { version = "0.2", features = ["sync"] }
26//!
27//! # For async only
28//! cron_tab = { version = "0.2", features = ["async"] }
29//! ```
30//!
31//! ## Cron Expression Format
32//!
33//! CronTab supports 7-field cron expressions with second precision:
34//!
35//! ```text
36//! ┌───────────── second (0 - 59)
37//! │ ┌─────────── minute (0 - 59)
38//! │ │ ┌───────── hour (0 - 23)
39//! │ │ │ ┌─────── day of month (1 - 31)
40//! │ │ │ │ ┌───── month (1 - 12)
41//! │ │ │ │ │ ┌─── day of week (0 - 6) (Sunday to Saturday)
42//! │ │ │ │ │ │ ┌─ year (1970 - 3000)
43//! │ │ │ │ │ │ │
44//! * * * * * * *
45//! ```
46//!
47//! ## Synchronous Usage Example
48//!
49//! ```rust
50//! use chrono::{FixedOffset, Local, TimeZone, Utc};
51//! use cron_tab::Cron;
52//!
53//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
54//! // Create a new cron scheduler with UTC timezone
55//! let mut cron = Cron::new(Utc);
56//!
57//! // Add a job that runs every 10 seconds
58//! let job_id = cron.add_fn("*/10 * * * * * *", || {
59//!     println!("Job executed at: {}", Local::now());
60//! })?;
61//!
62//! // Start the scheduler in background
63//! cron.start();
64//!
65//! // Add another job that runs every minute
66//! cron.add_fn("0 * * * * * *", || {
67//!     println!("Every minute job executed!");
68//! })?;
69//!
70//! // Remove the first job after some time
71//! std::thread::sleep(std::time::Duration::from_secs(1));
72//! cron.remove(job_id);
73//!
74//! // Stop the scheduler
75//! cron.stop();
76//! # Ok(())
77//! # }
78//! ```
79//!
80//! ## Asynchronous Usage Example
81//!
82//! ```rust
83//! # #[cfg(feature = "async")]
84//! # {
85//! use std::sync::Arc;
86//! use chrono::{FixedOffset, Local, TimeZone, Utc};
87//! use cron_tab::AsyncCron;
88//! use tokio::sync::Mutex;
89//!
90//! # #[tokio::main]
91//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
92//! // Create a new async cron scheduler
93//! let mut cron = AsyncCron::new(Utc);
94//!
95//! // Shared state between jobs
96//! let counter = Arc::new(Mutex::new(0));
97//!
98//! // Add an async job that increments counter
99//! let counter_clone = counter.clone();
100//! cron.add_fn("* * * * * * *", move || {
101//!     let counter = counter_clone.clone();
102//!     async move {
103//!         let mut count = counter.lock().await;
104//!         *count += 1;
105//!         println!("Counter: {}", *count);
106//!         // Simulate async work
107//!         tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
108//!     }
109//! }).await?;
110//!
111//! // Start the scheduler
112//! cron.start().await;
113//!
114//! // Let it run for a few seconds
115//! tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
116//!
117//! // Stop the scheduler
118//! cron.stop().await;
119//!
120//! let final_count = *counter.lock().await;
121//! println!("Final count: {}", final_count);
122//! # Ok(())
123//! # }
124//! # }
125//! ```
126//!
127//! ## Timezone Support Example
128//!
129//! ```rust
130//! use chrono::{FixedOffset, TimeZone, Utc};
131//! use cron_tab::Cron;
132//!
133//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
134//! // Tokyo timezone (UTC+9)
135//! let tokyo_tz = FixedOffset::east_opt(9 * 3600).unwrap();
136//! let mut cron_tokyo = Cron::new(tokyo_tz);
137//!
138//! // New York timezone (UTC-5)
139//! let ny_tz = FixedOffset::west_opt(5 * 3600).unwrap();
140//! let mut cron_ny = Cron::new(ny_tz);
141//!
142//! // Jobs will run according to their respective timezones
143//! cron_tokyo.add_fn("0 0 9 * * * *", || {
144//!     println!("Good morning from Tokyo!");
145//! })?;
146//!
147//! cron_ny.add_fn("0 0 9 * * * *", || {
148//!     println!("Good morning from New York!");
149//! })?;
150//!
151//! cron_tokyo.start();
152//! cron_ny.start();
153//! # Ok(())
154//! # }
155//! ```
156
157mod error;
158
159#[cfg(feature = "async")]
160mod async_cron;
161#[cfg(feature = "async")]
162mod async_entry;
163
164#[cfg(feature = "sync")]
165mod cron;
166#[cfg(feature = "sync")]
167mod entry;
168
169/// Re-export of the asynchronous cron scheduler.
170///
171/// This is only available when the "async" feature is enabled.
172/// Use [`AsyncCron`] for asynchronous job scheduling with tokio runtime.
173#[cfg(feature = "async")]
174pub use crate::async_cron::AsyncCron;
175
176/// Re-export of the synchronous cron scheduler.
177///
178/// This is only available when the "sync" feature is enabled.
179/// Use [`Cron`] for synchronous job scheduling with threads.
180#[cfg(feature = "sync")]
181pub use crate::cron::Cron;
182
183/// Re-export of the cron error type.
184///
185/// All fallible operations in this crate return a `Result<T, CronError>`.
186pub use crate::error::CronError;
187
188/// Convenience type alias for Results returned by this crate.
189///
190/// This is equivalent to `std::result::Result<T, CronError>`.
191pub type Result<T> = std::result::Result<T, CronError>;
192
193/// Maximum wait time in seconds for the scheduler loop.
194///
195/// This constant is used as a fallback when no jobs are scheduled,
196/// preventing infinite blocking while still being responsive to
197/// new job additions or stop signals.
198const MAX_WAIT_SECONDS: u64 = 100000000;