qrush_engine/cron/
cron_parser.rs1use anyhow::{anyhow, Result};
4use chrono::{DateTime, TimeZone, Utc};
5use chrono_tz::Tz;
6use cron::Schedule;
7use std::str::FromStr;
8
9pub struct CronParser;
10
11impl CronParser {
12 pub fn next_execution(cron_expr: &str, from_utc: DateTime<Utc>, timezone: &str) -> Result<DateTime<Utc>> {
20 let schedule = Schedule::from_str(cron_expr)
21 .map_err(|e| anyhow!("invalid cron expression '{}': {:?}", cron_expr, e))?;
22
23 let tz: Tz = timezone
24 .parse()
25 .map_err(|_| anyhow!("invalid timezone '{}'", timezone))?;
26
27 let from_tz = from_utc.with_timezone(&tz);
28
29 let next_tz = schedule
32 .after(&from_tz)
33 .next()
34 .ok_or_else(|| anyhow!("no upcoming cron occurrence for expression '{}'", cron_expr))?;
35
36 Ok(next_tz.with_timezone(&Utc))
37 }
38
39 pub fn validate(cron_expr: &str) -> Result<()> {
41 let _ = Schedule::from_str(cron_expr)
42 .map_err(|e| anyhow!("invalid cron expression '{}': {:?}", cron_expr, e))?;
43 Ok(())
44 }
45
46 pub fn parse_tz(timezone: &str) -> Result<Tz> {
48 timezone
49 .parse::<Tz>()
50 .map_err(|_| anyhow!("invalid timezone '{}'", timezone))
51 }
52
53 pub fn to_tz(ts_utc: DateTime<Utc>, tz: Tz) -> DateTime<Tz> {
55 tz.from_utc_datetime(&ts_utc.naive_utc())
56 }
57}