#[derive(Debug,PartialEq,serde::Deserialize)] struct GitlabCi { variables: std::collections::BTreeMap, cache: Cache, // #[serde(flatten)] serde_derive's flatten only supports self-describing formats :( jobs: std::collections::BTreeMap, } #[derive(Debug,PartialEq,serde::Deserialize)] struct Cache { key: String, paths: Vec, } #[derive(Debug,PartialEq,serde::Deserialize)] struct Rule { r#if: Option, when: String, } #[derive(Debug,PartialEq,serde::Deserialize)] struct Job { #[serde(default)] only: Vec, #[serde(default)] except: Vec, #[serde(default)] rules: Vec, stage: String, image: String, #[serde(default)] variables: std::collections::BTreeMap, script: Vec, } fn path_to(f: &str) -> String { format!("{}/examples/gitlab-ci/{}", env!("CARGO_MANIFEST_DIR"), f) } #[test] fn test() { let scfg: GitlabCi = simple_config::from_file(path_to("gitlab-ci.scfg")).unwrap(); let f = buffered_reader::File::open(path_to("gitlab-ci.yml")).unwrap(); let mut yaml: GitlabCi = serde_yaml::from_reader(f).unwrap(); // YAML puts a newline at the end of multi-line strings. Simple Config doesn't. for (_, job) in &mut yaml.jobs { for cmd in &mut job.script { cmd.truncate(cmd.trim_end_matches('\n').len()) } } eprintln!("{:#?}", scfg); eprintln!("{:#?}", yaml); assert_eq!(scfg, yaml); }