config_kit/layer.rs
1//! Configuration sources and the precedence they compose with.
2
3use std::collections::BTreeMap;
4use std::path::Path;
5use std::path::PathBuf;
6
7/// One named source of configuration values.
8///
9/// Layers are applied by [`ConfigBuilder::layer`](crate::ConfigBuilder::layer)
10/// in the order they are added. A later layer's keys replace earlier ones,
11/// while tables merge key-by-key (deep merge), so a late layer can override
12/// a single nested field without clobbering its siblings. Driven in the
13/// documented order this yields precedence **overrides > env > file**.
14#[derive(Debug, Clone)]
15pub enum ConfigLayer {
16 /// A configuration file, parsed at load time by extension: `.json`
17 /// (feature `json`), `.yaml`/`.yml` (feature `yaml`), and anything
18 /// else — including no extension — as TOML.
19 File(PathBuf),
20 /// All environment variables sharing a prefix. The prefix is stripped
21 /// and the remainder lowercased to form the top-level key; values are
22 /// typed by inference (see the crate root for the exact rules).
23 EnvPrefix(String),
24 /// In-process values, typically assembled by a supervisor or test.
25 /// Applied last in the documented order, hence highest precedence.
26 Overrides(BTreeMap<String, toml::Value>),
27}
28
29impl ConfigLayer {
30 /// A file-backed layer parsed by extension (TOML core; JSON and YAML
31 /// behind the matching features).
32 #[must_use]
33 pub fn file(path: impl AsRef<Path>) -> Self {
34 Self::File(path.as_ref().to_path_buf())
35 }
36
37 /// An environment layer matching every variable that starts with
38 /// `prefix` (case-sensitive).
39 #[must_use]
40 pub fn env_prefix(prefix: impl Into<String>) -> Self {
41 Self::EnvPrefix(prefix.into())
42 }
43
44 /// An in-process override layer keyed by top-level field name.
45 #[must_use]
46 pub fn overrides(overrides: BTreeMap<String, toml::Value>) -> Self {
47 Self::Overrides(overrides)
48 }
49}