reminder_cli/
cron_parser.rs1use anyhow::{bail, Result};
2use cron::Schedule;
3use std::str::FromStr;
4
5pub fn parse_cron(input: &str) -> Result<String> {
11 let input = input.trim();
12
13 if Schedule::from_str(input).is_ok() {
15 return Ok(input.to_string());
16 }
17
18 match english_to_cron::str_cron_syntax(input) {
20 Ok(cron_expr) => {
21 if Schedule::from_str(&cron_expr).is_ok() {
23 Ok(cron_expr)
24 } else {
25 bail!(
26 "Generated invalid cron expression from '{}': {}",
27 input,
28 cron_expr
29 )
30 }
31 }
32 Err(_) => {
33 bail!(
34 "Invalid cron expression: {}\n\
35 \n\
36 Supported formats:\n\
37 - Standard cron: \"0 0 9 * * *\" (sec min hour day month weekday)\n\
38 - English: \"every day at 9am\", \"every monday at 14:00\", \"every hour\"\n\
39 \n\
40 English examples:\n\
41 - \"every minute\"\n\
42 - \"every hour\"\n\
43 - \"every day at 9am\"\n\
44 - \"every monday at 10:00\"\n\
45 - \"every weekday at 8:30\"\n\
46 - \"every 30 minutes\"",
47 input
48 )
49 }
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_standard_cron() {
59 let result = parse_cron("0 0 9 * * *");
60 assert!(result.is_ok());
61 assert_eq!(result.unwrap(), "0 0 9 * * *");
62 }
63
64 #[test]
65 fn test_english_cron() {
66 let result = parse_cron("every day at 9am");
68 assert!(result.is_ok());
69 }
70}