confcade 0.0.1

Minimalistic cascading configuration
Documentation
use std::fs::File;

use clap::Parser;
use serde::Deserialize;

#[derive(Debug, confcade::Confcade, Parser, Deserialize)]
#[confcade(concrete_derive(Debug))]
pub struct Settings {
    #[arg(long)]
    pub field1: Option<String>,
    #[arg(long)]
    pub field2: Option<String>,
    #[arg(long)]
    pub field3: Option<String>,

    #[serde(default)]
    #[command(flatten)]
    pub sub: SubFields,
}

#[derive(Debug, confcade::Confcade, clap::Args, Deserialize, Default)]
#[confcade(concrete_derive(Debug))]
pub struct SubFields {
    #[arg(long)]
    pub field4: Option<String>,
    #[arg(long)]
    pub field5: Option<String>,
}

fn main() {
    use confcade::Confcade;

    let from_cli = Settings::parse();
    println!("CLI: {from_cli:?}");

    let from_config: Settings = serde_json::from_reader(File::open("examples/example-settings.json").unwrap()).unwrap();
    println!("Config: {from_config:?}");

    let mut settings = Settings::INITIAL;
    settings.fallback(from_cli);
    settings.fallback(from_config);
    settings.field3.fallback(Some("default-3".to_owned()));

    println!("Combined: {settings:?}");

    let finalized = settings.finalize();
    println!("finalized: {finalized:?}");
}