pub struct ConfigBuilder<S> { /* private fields */ }Expand description
Builder for layered, typed configuration.
The state parameter makes loading impossible until a layer exists:
ConfigBuilder::new returns ConfigBuilder<Empty>,
every layer call returns
ConfigBuilder<Ready>, and only the ready state
exposes load / load_strict.
§Precedence
Layers apply in the order added; later layers win on colliding keys, with tables merging key-by-key (deep merge). Driven in the documented order this gives overrides > env > file:
ConfigBuilder::new()
.layer(ConfigLayer::file("app.toml")) // base
.layer(ConfigLayer::env_prefix("APP_")) // deployment env wins over file
.layer(ConfigLayer::overrides(over)) // in-process wins over both
.load::<AppSettings>()?;§Example
use config_kit::{ConfigBuilder, ConfigLayer};
use serde::Deserialize;
use std::collections::BTreeMap;
#[derive(Deserialize)]
struct Settings {
port: u16,
debug: bool,
}
std::env::set_var("CKIT_DOC_PORT", "8080");
std::env::set_var("CKIT_DOC_DEBUG", "true");
let mut over: BTreeMap<String, toml::Value> = BTreeMap::new();
over.insert("port".into(), toml::Value::Integer(9090));
let settings: Settings = ConfigBuilder::new()
.layer(ConfigLayer::env_prefix("CKIT_DOC_"))
.layer(ConfigLayer::overrides(over))
.load()?;
assert_eq!(settings.port, 9090); // overrides beat env
assert!(settings.debug); // env value inferred as boolImplementations§
Source§impl ConfigBuilder<Empty>
impl ConfigBuilder<Empty>
Sourcepub fn new() -> Self
pub fn new() -> Self
A builder with no layers. Add at least one
ConfigLayer to unlock loading.
Source§impl<S> ConfigBuilder<S>
impl<S> ConfigBuilder<S>
Sourcepub fn layer(self, layer: ConfigLayer) -> ConfigBuilder<Ready>
pub fn layer(self, layer: ConfigLayer) -> ConfigBuilder<Ready>
Adds a layer and transitions the builder to the Ready state.
Layers take effect in the order added; see the type-level documentation for precedence and merge semantics.
Source§impl ConfigBuilder<Ready>
impl ConfigBuilder<Ready>
Sourcepub fn load<T: DeserializeOwned>(self) -> Result<T, ConfigError>
pub fn load<T: DeserializeOwned>(self) -> Result<T, ConfigError>
Deserializes the merged configuration into T.
Unknown keys are ignored (use load_strict to
deny them); types must line up with T’s fields.
§Errors
ConfigError::Iowhen a file layer cannot be read,ConfigError::Parsewhen a file layer fails to parse, names a format whose feature is disabled, or when the merged values do not fitT,ConfigError::EnvVarwhen a matching environment variable has a non-Unicode value.
Sourcepub fn load_strict<T: DeserializeOwned>(self) -> Result<T, ConfigError>
pub fn load_strict<T: DeserializeOwned>(self) -> Result<T, ConfigError>
Strict load: fails with ConfigError::UnknownFields when any
top-level key of the merged configuration is not consumed by a
field of T.
The precise, honest contract:
- Detection is container-agnostic — it works for any
T: DeserializeOwnedby instrumenting deserialization withserde_ignoredand reporting which top-level map keys no field visited. It is not#[serde(deny_unknown_fields)]semantics (that derive is per-struct; config-kit never sees your schema declaration sites). - Top level only. Unknown keys nested inside tables (
[db]→rogue = 1) are passed through to serde’s normal handling and are not reported. Keys introduced by env or override layers are checked identically to file keys. - Types using
#[serde(flatten)]collect unknown keys into the flattened field before instrumentation can see them, so flattened content is exempt from this check. - If
Titself derivesdeny_unknown_fields, its own error wins and surfaces asConfigError::Parse.
On success the deserialized value is returned directly — there is no second parse pass.
§Errors
Everything load reports, plus
ConfigError::UnknownFields when unconsumed top-level keys exist.
Trait Implementations§
Source§impl<S: Clone> Clone for ConfigBuilder<S>
impl<S: Clone> Clone for ConfigBuilder<S>
Source§fn clone(&self) -> ConfigBuilder<S>
fn clone(&self) -> ConfigBuilder<S>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more