Config and CLI
vld-config takes the merged configuration from config-rs or figment (TOML, JSON, YAML, env, defaults), turns it into a serde_json::Value and parses it with your vld schema. You get a typed settings struct or a VldError listing every bad key.
Install
Cargo.toml
[dependencies]
vld = "0.5"
vld-config = "0.5" # config-rs backend
config = "0.15"
figment instead (or as well):
Cargo.toml
[dependencies]
vld-config = { version = "0.5", default-features = false, features = ["figment"] }
figment = { version = "0.10", features = ["toml", "env"] }
Features
| Feature | Default | Description |
|---|---|---|
config-rs | yes | from_config, from_builder for config >=0.14, <0.16 |
figment | no | from_figment for figment 0.10 |
Both can be enabled. The backend crates are not re-exported; add config / figment yourself in a matching version.
MSRV: 1.85 (see MSRV).
Example
use vld_config::prelude::*;
vld::schema! {
#[derive(Debug)]
pub struct AppSettings {
pub host: String => vld::string().min(1),
pub port: i64 => vld::number().int().min(1).max(65535),
pub debug: bool => vld::boolean().with_default(false),
}
}
let config = config::Config::builder()
.add_source(config::File::with_name("config").required(false))
// Env values are strings: `try_parsing(true)` turns APP_PORT=8080 into a number.
.add_source(config::Environment::with_prefix("APP").try_parsing(true))
.build()
.unwrap();
match from_config::<AppSettings>(&config) {
Ok(s) => println!("listening on {}:{}", s.host, s.port),
Err(e) => {
eprintln!("{e}");
std::process::exit(1);
}
}
figment:
let figment = figment::Figment::new()
.merge(figment::providers::Serialized::defaults(
serde_json::json!({"host": "0.0.0.0", "port": 3000}),
))
.merge(figment::providers::Env::prefixed("APP_"));
let settings: AppSettings = vld_config::from_figment(&figment).unwrap();
API
| Item | Description |
|---|---|
from_config::<T>(&config::Config) | Deserialize to JSON, then parse_coerced into T |
from_builder::<T>(ConfigBuilder) | Build the config, then as above |
from_figment::<T>(&figment::Figment) | Extract to JSON, then as above |
from_value::<T>(&Value) | Strict parse of a JSON value (no coercion) |
from_value_coerced::<T>(&Value) | The same coercion the backends use |
VldConfigError | Source(String) (loading failed) or Validation(VldError); implements Error with source() |
prelude | from_* (except from_value_coerced), VldConfigError, vld::prelude::* |
T is any VldParse type: vld::schema!, #[derive(Validate)], or vld-schemars' impl_vld_parse!.
Gotchas
- Coercion:
from_config,from_builderandfrom_figmentusevld::schema::parse_coerced. A number or boolean the backend parsed is turned back into text where the schema wants a string (APP_HOST=12345→"12345"), and a single value is wrapped where the schema wants an array. The text is the backend's parsed value, so a lossy parse ("01234"→1234) gives"1234".from_valuedoes none of this. - config-rs reads env values as strings unless
try_parsing(true)is set; without itvld::number()fields fail on env overrides. - Errors carry the JSON path of the bad key (
database.port); print them with{e}or the formatting helpers.