simple_config 0.134.0

A config language for humans that is not self-describing.
Documentation
#[derive(Debug,PartialEq,serde::Deserialize)]
struct Workflow {
	name: String,

	on: On,

	jobs: std::collections::BTreeMap<String, Job>,
}

#[serde_with::serde_as]
#[derive(Debug,PartialEq,serde::Deserialize)]
struct On {
	#[serde(default)]
	#[serde_as(deserialize_as="serde_with::DefaultOnNull")]
	pull_request_target: Event,

	#[serde(default)]
	schedule: Vec<Schedule>,
}

#[derive(Debug,Default,PartialEq,serde::Deserialize)]
struct Event {
	#[serde(default)]
	targets: Vec<String>,
}

#[derive(Debug,Default,PartialEq,serde::Deserialize)]
struct Schedule {
	cron: String,
}

#[derive(Debug,PartialEq,serde::Deserialize)]
#[serde(rename_all="kebab-case")]
struct Job {
	r#if: Option<String>,
	runs_on: Vec<String>,
	steps: Vec<Step>,
}

#[derive(Debug,PartialEq,serde::Deserialize)]
struct Step {
	name: Option<String>,
	#[serde(default)]
	env: std::collections::BTreeMap<String, String>,

	run: Option<String>,

	uses: Option<String>,
	#[serde(default)]
	with: std::collections::BTreeMap<String, String>,
}

fn path_to(f: &str, ext: &str) -> String {
	format!("{}/examples/github-workflow/{}.{}", env!("CARGO_MANIFEST_DIR"), f, ext)
}

fn test(path: &str) {
	let scfg: Workflow = simple_config::from_file(path_to(path, "scfg")).expect("parsing scfg");

	let f = std::fs::File::open(path_to(path, "yml")).expect("opening yaml");
	let mut yaml: Workflow = serde_yaml::from_reader(f).expect("parsing yaml");

	// YAML puts a newline at the end of multi-line strings. Simple Config doesn't.
	for (_, job) in &mut yaml.jobs {
		for step in &mut job.steps {
			if let Some(run) = step.run.as_mut() {
				run.truncate(run.trim_end_matches('\n').len())
			}
		}
	}

	eprintln!("{:#?}", scfg);
	eprintln!("{:#?}", yaml);

	assert_eq!(scfg, yaml);
}

#[test]
fn nixos_homepage_cron() {
	test("nixos-homepage/cron")
}

#[test]
fn nixpkgs_pending_set() {
	test("nixpkgs/pending-set")
}