use serde::de::DeserializeOwned;
pub fn load_config<T>(basename: &str, env_prefix: &str) -> Result<T, config::ConfigError>
where
T: DeserializeOwned,
{
config::Config::builder()
.add_source(config::File::with_name(basename).required(false))
.add_source(
config::Environment::with_prefix(env_prefix)
.separator("__")
.try_parsing(true),
)
.build()?
.try_deserialize::<T>()
}
#[cfg(test)]
mod tests {
use super::load_config;
use serde::Deserialize;
use std::io::Write;
#[derive(Debug, Deserialize)]
struct App {
server: Server,
}
#[derive(Debug, Deserialize)]
struct Server {
port: u16,
}
#[test]
fn loads_toml_file() {
let dir = tempfile::tempdir().expect("tempdir");
let file_path = dir.path().join("app.toml");
let mut file = std::fs::File::create(&file_path).expect("create config");
writeln!(file, "[server]\nport = 8080").expect("write config");
let basename = file_path.with_extension("");
let app: App =
load_config(basename.to_str().expect("utf8 path"), "RSZERO_TEST").expect("load config");
assert_eq!(app.server.port, 8080);
}
}