Parse cron entries directly into a useful structure on configuration load

This commit is contained in:
R Tyler Croy 2020-08-03 18:04:17 -07:00
parent 2f03028f97
commit ed0fcb33c6
3 changed files with 49 additions and 5 deletions

4
Cargo.lock generated
View File

@ -389,8 +389,7 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
name = "cron"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab00a636277f7ea5d8dd92ac7a5099fc9a46e5327bba84d3640b41ae127eada9"
source = "git+https://github.com/zslayton/cron?rev=e52fef0#e52fef0d2c2018eaf0f8c84eada3c82e8e6e3651"
dependencies = [
"chrono",
"error-chain 0.10.0",
@ -1364,6 +1363,7 @@ name = "urci"
version = "0.1.0"
dependencies = [
"async-std",
"chrono",
"cron",
"serde",
"serde_derive",

View File

@ -6,7 +6,9 @@ edition = "2018"
[dependencies]
async-std = { version = "~1.6.0", features = ["attributes"] }
cron = "~0.6.1"
chrono = "~0.4.13"
# This version has Display implemented on cron::Schedule
cron = { git = "https://github.com/zslayton/cron", rev = "e52fef0" }
serde = { version = "~1.0.106", features = ["rc"] }
serde_derive = "~1.0.106"
serde_json = "~1.0.0"

View File

@ -3,6 +3,8 @@
* configuration file
*/
use serde::de::{Deserialize, Deserializer};
use std::str::FromStr;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
@ -21,10 +23,21 @@ pub struct Project {
scm: Scm,
}
#[derive(Debug, Deserialize)]
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Trigger {
cron: Option<String>,
#[serde(deserialize_with = "deserialize_cron_schedule")]
cron: Option<cron::Schedule>,
}
impl std::fmt::Debug for Trigger {
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
write!(formatter, "Trigger: ")?;
if let Some(cron) = &self.cron {
write!(formatter, "cron: {}", cron)?;
}
Ok(())
}
}
#[derive(Debug, Deserialize)]
@ -43,3 +56,32 @@ pub struct Agent {
#[serde(rename_all = "camelCase")]
pub struct Handler {
}
fn deserialize_cron_schedule<'de, D>(deserializer: D) -> Result<Option<cron::Schedule>, D::Error>
where D: Deserializer<'de> {
let buf = String::deserialize(deserializer)?;
if let Ok(schedule) = cron::Schedule::from_str(&buf) {
return Ok(Some(schedule));
}
Err(serde::de::Error::custom("Failed to parse cron, make sure you have at least six fields"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cron_deserialize() {
let trigger_yaml = r#"---
# Fire every second lol
cron: '* * * * * *'
"#;
let trigger: Trigger = serde_yaml::from_str(trigger_yaml)
.expect("Should be able to parse our yaml");
assert!(trigger.cron.is_some());
}
}