Expand description
Clap integration for provcfg.
Derive ClapArgs alongside provcfg::Configurable to generate a
<Name>Args struct (a clap::Args) plus a From<&<Name>Args> for <Name>Partial impl. A clap-parsed command line then flows into a provcfg
CLI source without a hand-written per-field conversion.
use clap::Parser;
use provcfg::{Category, Config, Configurable};
use provcfg_clap::ClapArgs;
#[derive(Configurable, ClapArgs, Clone, Default, serde::Deserialize, serde::Serialize)]
#[configurable(clap_prefix = "registry")]
struct Registry {
data_dir: String, // exposed as --registry-data-dir
port: u16, // exposed as --registry-port
}
#[derive(Parser)]
struct Cli {
#[command(flatten)]
registry: RegistryArgs,
}
let cli = Cli::parse_from(["app", "--registry-data-dir", "/var/lib/reg"]);
// The generated `From<&RegistryArgs>` builds the provcfg partial for us.
let partial: RegistryPartial = (&cli.registry).into();
let registry = Config::new().add_cli(partial).build::<RegistryProv>().unwrap();
assert_eq!(registry.data_dir.value(), "/var/lib/reg");
assert_eq!(registry.data_dir.source().category(), Category::Cli);
// `--registry-port` was not passed, so `port` keeps its compiled-in default.
assert_eq!(registry.port.source().category(), Category::Default);The ClapArgs derive:
- generates
<Name>Argswith each leaf wrapped inOption<T>and an#[arg(long = "<prefix>-<field>")]auto-derived from the field name; - forwards any user-written
#[arg(...)]attributes; a user-suppliedlong = "..."overrides the auto-derived one; - for
#[configurable(nested)]fields emits#[command(flatten)]into the nested type’s ownArgsstruct (which must also deriveClapArgs); - omits
#[configurable(skip)]fields from both the Args struct and theFromimpl.
Re-exports§
pub use clap;
Derive Macros§
- Clap
Args - Generates a sibling
<Name>Argsclap-compatible struct plus aFrom<&<Name>Args> for <Name>Partialimpl. Intended to be derived alongsideprovcfg::Configurable.