Crates.io | clap-adapters |
lib.rs | clap-adapters |
version | 0.2.2 |
source | src |
created_at | 2024-01-19 05:01:08.900426 |
updated_at | 2024-09-06 20:24:58.088242 |
description | Neat adapters for parsing config files with clap |
homepage | |
repository | https://github.com/nicholastmosher/clap-adapters |
max_upload_size | |
id | 1104996 |
size | 66,458 |
clap-adapters
Adapter types for declaratively loading configurations with clap
Did you know that any type that implements [FromStr
] can
be used in a clap
derive struct? That means that any
logic you can fit into a fn(&str) -> Result<T, Error>
can
be run at parsing-time. This can be expecially useful for
declaratively selecting config files or doing other cool
stuff. Check this out:
use clap::Parser;
use clap_adapters::prelude::*;
#[derive(Debug, Parser)]
struct Cli {
/// Path to a config file of arbitrary Json
#[clap(long)]
config: PathTo<JsonOf<serde_json::Value>>,
}
fn main() {
// Create a config file in a temporary directory
let config_dir = tempfile::tempdir()?;
let config_path = config_dir.path().join("config.json");
let config_path_string = config_path.display().to_string();
// Write a test config of {"hello":"world"} to the config file
let config = serde_json::json!({"hello": "world"});
let config_string = serde_json::to_string(&config)?;
std::fs::write(&config_path, &config_string)?;
// Parse our CLI, passing our config file path to --config
let cli = Cli::parse_from(["app", "--config", &config_path_string]);
let data = cli.config.data();
// We should expect the value we get to match what we wrote to the config
assert_eq!(data, &serde_json::json!({"hello":"world"}));
}
clap-adapters
You can implement additional composable adapters by defining new types that
implement traits in this crate. For example, by implementing FromReader
,
you could define an adapter that can construct itself from a file path, nesting
your adapter into PathTo<T>
, like PathTo<YourAdapter>
.