Skip to main content

smith_config/
app.rs

1use anyhow::{Context, Result};
2use once_cell::sync::OnceCell;
3
4use crate::Config;
5
6/// Global, lazily-initialized configuration cache.
7///
8/// Loads configuration once from the environment (including overrides) and
9/// shares the resulting `Config` across all callers. This avoids repeated
10/// env/file parsing throughout the process and centralizes configuration
11/// injection at startup.
12static GLOBAL_CONFIG: OnceCell<Config> = OnceCell::new();
13
14/// Load configuration from the environment and cache it for subsequent calls.
15///
16/// The first caller populates the cache; later callers get the same instance.
17pub fn load_from_env() -> Result<&'static Config> {
18    GLOBAL_CONFIG.get_or_try_init(|| {
19        let mut config = Config::from_env().context("Failed to load configuration")?;
20        if let Err(err) = config.apply_env_overrides() {
21            tracing::warn!(error = %err, "Failed to apply environment overrides; continuing with base config");
22        }
23        Ok(config)
24    })
25}
26
27/// Get the cached configuration, assuming it has been loaded via `load_from_env`.
28/// Panics if called before initialization.
29pub fn get() -> &'static Config {
30    GLOBAL_CONFIG
31        .get()
32        .expect("Config not initialized; call load_from_env first")
33}