use std::path::{Path, PathBuf};
use figment::{
providers::{Env, Format as _, Toml},
Figment,
};
use serde::Deserialize;
use snafu::ResultExt as _;
use crate::{ConfigFileWriteSnafu, Error};
pub fn create_config_file<C>(config_path: impl Into<PathBuf>) -> Result<(), Error>
where
C: doku::Document,
{
let path = config_path.into();
let config_contents = doku::to_toml::<C>();
std::fs::write(&path, config_contents).with_context(|_| ConfigFileWriteSnafu { path })?;
Ok(())
}
pub struct Config<C> {
pub config: C,
}
impl<'a, C> Config<C>
where
C: Deserialize<'a> + doku::Document,
{
pub fn new<P, E>(config_path: Option<P>, env_prefix: Option<E>) -> Result<Self, Error>
where
P: AsRef<Path>,
E: AsRef<str>,
{
let f = Figment::new();
let f = match config_path {
Some(config_file) => f.merge(Toml::file(config_file)),
None => f,
};
let f = match env_prefix {
Some(env_prefix) => {
let env_prefix = env_prefix.as_ref();
f.merge(Env::prefixed(env_prefix).split("__"))
}
None => f,
};
let config = f.extract().with_context(|_| super::ConfigLoadSnafu {})?;
Ok(Self { config })
}
}