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