use clingwrap::config::*;
use serde::{Deserialize, Serialize};
use tempfile::tempdir;
#[allow(dead_code)]
#[derive(Debug)]
struct Simple {
greeting: String,
whom: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, Eq, PartialEq)]
struct SimpleFile {
greeting: Option<String>,
whom: Option<String>,
}
impl<'a> ConfigFile<'a> for SimpleFile {
type Error = SimpleError;
fn merge(&mut self, config_file: SimpleFile) -> Result<(), Self::Error> {
if let Some(value) = &config_file.greeting {
self.greeting = Some(value.to_string());
}
if let Some(value) = &config_file.whom {
self.whom = Some(value.to_string());
}
Ok(())
}
}
#[derive(Default)]
struct SimpleValidator {}
impl ConfigValidator for SimpleValidator {
type File = SimpleFile;
type Valid = Simple;
type Error = SimpleError;
fn validate(&self, runtime: &Self::File) -> Result<Self::Valid, Self::Error> {
Ok(Simple {
greeting: runtime.greeting.clone().ok_or(SimpleError::Missing)?,
whom: runtime.whom.clone().ok_or(SimpleError::Missing)?,
})
}
}
#[derive(Debug, thiserror::Error)]
enum SimpleError {
#[error("required field has not been set")]
Missing,
}
fn main() {
env_logger::init();
const CONFIG_1: &str = "{}";
const CONFIG_2: &str = r#"greeting: hello
whom: world"#;
let mut loader = ConfigLoader::default();
let tmp = tempdir().unwrap();
let filename = tmp.path().join("config1.json");
std::fs::write(&filename, CONFIG_1.as_bytes()).unwrap();
loader.require_json(&filename);
let filename = tmp.path().join("config2.yaml");
std::fs::write(&filename, CONFIG_2.as_bytes()).unwrap();
loader.require_yaml(&filename);
let validator = SimpleValidator::default();
let valid = loader.load(None, None, &validator).unwrap();
println!("loaded and validated configuration: {valid:#?}");
}