Expand description
Typed, layered configuration backed by figment.
§Design
The Go Tool Base config system exposes a dynamic Containable
interface with GetString("foo.bar") accessors. We deliberately do
not mimic that. Rust’s strength is in compile-time types, so
Config is a generic container over your serde::Deserialize
struct:
use rtb_config::Config;
use serde::Deserialize;
#[derive(Deserialize, Default)]
struct MyConfig { host: String, port: u16 }
let cfg = Config::<MyConfig>::builder()
.embedded_default(concat!(
"host: localhost\n",
"port: 8080\n",
))
.env_prefixed("MYTOOL_")
.build()
.expect("config layers are consistent");
let current = cfg.get();
assert_eq!(current.host, "localhost");§What ships
- Typed
Config<C>withCdefaulting to()so rtb-app’sArc<Config>field keeps working without a type parameter. ConfigBuilderlayering (embedded default → user file → env).- Explicit
Config::reloadre-reading every source and atomically swapping the stored value viaarc_swap::ArcSwap. Config::subscribereturning atokio::sync::watch::Receiverthat wakes every time a reload succeeds (v0.2).Config::watch_filesbehind thehot-reloadfeature: a debounced background watcher that callsreloadon change and hands back aWatchHandleto stop it (v0.2).
See docs/development/specs/2026-04-22-rtb-config-v0.1.md and
docs/development/specs/2026-04-24-rtb-config-hot-reload.md for
the authoritative contracts.
Re-exports§
pub use config::Config;pub use config::ConfigBuilder;pub use error::ConfigError;