From deaa42c636ab2404cc73fb809b90e8c75165e2e5 Mon Sep 17 00:00:00 2001 From: onatm Date: Mon, 9 Aug 2021 22:42:52 +0100 Subject: [PATCH] Enable using day aliases --- Cargo.lock | 9 ++++++++ Cargo.toml | 3 ++- README.md | 2 +- src/lib.rs | 3 +++ src/parser.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f3d9c31..13a8a34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,13 +1,22 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "croon" version = "0.1.0" dependencies = [ + "lazy_static", "linked_hash_set", "nom", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "linked-hash-map" version = "0.5.4" diff --git a/Cargo.toml b/Cargo.toml index 166b279..9703956 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ edition = "2018" [dependencies] nom="^4" -linked_hash_set="^0.1.4" \ No newline at end of file +linked_hash_set="^0.1.4" +lazy_static = "1.4.0" diff --git a/README.md b/README.md index e83638a..2ee25c7 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ croon consists of two main parts: - CLI entry point - Library to parse cron expressions -It has two external dependencies for development convenience: `nom` and `linked_hash_set`. +It has two external dependencies for development convenience: `nom`, `linked_hash_set` and `lazy_static`. ### How it works diff --git a/src/lib.rs b/src/lib.rs index b5d108a..2dc2cc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +#[macro_use] +extern crate lazy_static; + pub mod cron_table; mod error; mod expression; diff --git a/src/parser.rs b/src/parser.rs index d520e4b..f88f0f1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use nom::{types::CompleteStr, *}; use crate::{ @@ -17,6 +19,20 @@ impl Parser { } } +lazy_static! { + static ref ALIAS_MAP: HashMap<&'static str, u32> = { + let mut m = HashMap::new(); + m.insert("MON", 1); + m.insert("TUE", 2); + m.insert("WED", 3); + m.insert("THU", 4); + m.insert("FRI", 5); + m.insert("SAT", 6); + m.insert("SUN", 0); + m + }; +} + named!( number, map_res!(ws!(digit), |x: CompleteStr| x.0.parse()) @@ -24,13 +40,28 @@ named!( named!( exact, - do_parse!(n: number >> (CronBaseExpression::Exact(n))) + do_parse!(n: alt!(number | day) >> (CronBaseExpression::Exact(n))) +); + +fn map_alias_to_number(alias: String) -> Result { + if let Some(value) = ALIAS_MAP.get(&*alias) { + Ok(value.clone()) + } else { + Err(Error) + } +} + +named!( + day, + do_parse!( + day: alt!(tag!("MON") | tag!("TUE") | tag!("WED") | tag!("THU") | tag!("FRI") | tag!("SAT") | tag!("SUN")) >> (map_alias_to_number(day.0.to_string()).unwrap()) + ) ); named!( range, complete!(do_parse!( - start: number >> tag!("-") >> end: number >> (CronBaseExpression::Range(start, end)) + start: alt!(number | day) >> tag!("-") >> end: alt!(number| day) >> (CronBaseExpression::Range(start, end)) )) ); @@ -38,7 +69,7 @@ named!(all, do_parse!(tag!("*") >> (CronBaseExp named!( cron_base_expression, - alt!(all | range | exact) + alt!(all | range | exact ) ); named!( @@ -65,7 +96,7 @@ named!( command, do_parse!( multispace0 >> - command: take_while!(|c: char| c.is_alphanumeric() || c == '/' || c.is_whitespace()) >> (String::from(command.0)) + command: take_while!(|c: char| c.is_alphanumeric() || c == '\'' || c == '/' || c.is_whitespace()) >> (String::from(command.0)) ) ); @@ -101,11 +132,26 @@ mod test { assert!(number(CompleteStr("AAA")).is_err()); } + #[test] + fn test_valid_day() { + day(CompleteStr("MON")).unwrap(); + } + + #[test] + fn test_invalid_alias() { + assert!(day(CompleteStr("MoN")).is_err()); + } + #[test] fn test_valid_range() { range(CompleteStr("2-4")).unwrap(); } + #[test] + fn test_valid_range_of_number_and_day() { + range(CompleteStr("MON-4")).unwrap(); + } + #[test] fn test_invalid_range() { assert!(range(CompleteStr("2-A")).is_err()); @@ -141,6 +187,11 @@ mod test { cron_expression_list(CompleteStr("4,2")).unwrap(); } + #[test] + fn test_valid_alias_list() { + cron_expression_list(CompleteStr("MON,2")).unwrap(); + } + #[test] fn test_invalid_number_list() { assert!(cron_expression_list(CompleteStr("A,4,2")).is_err());