urci/src/config.rs

115 lines
2.7 KiB
Rust

/**
* This module contains all the defined structures which will process the UrCI
* configuration file
*/
use serde::de::{Deserialize, Deserializer};
use std::collections::HashMap;
use std::str::FromStr;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
pub projects: Vec<Project>,
pub agents: Vec<Agent>,
pub handlers: HashMap<String, Handler>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Project {
name: String,
trigger: Trigger,
handler: String,
scm: Scm,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Trigger {
#[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)]
#[serde(rename_all = "camelCase")]
pub struct Scm {
git: Option<String>,
r#ref: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum AgentType {
Local,
Ssh,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Agent {
name: String,
description: String,
r#type: AgentType,
params: Option<HashMap<String, String>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Handler {
filename: String,
defaults: Option<HashMap<String, String>>,
}
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 std::fs::File;
use std::io::Read;
use super::*;
#[test]
fn test_deserialize_example_config() {
let mut f = File::open("urci.yml").unwrap();
let mut yaml = String::new();
f.read_to_string(&mut yaml)
.expect("Failed to read into string");
let _config: Config = serde_yaml::from_str(&yaml).expect("Failed to parse the yaml");
}
#[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());
}
}