mod env;
mod file;
mod paths;
use std::io;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct ReadOptions<'a> {
pub env_prefix: Option<&'a str>,
}
impl<'a> ReadOptions<'a> {
pub const fn with_env_prefix(env_prefix: &'a str) -> Self {
Self {
env_prefix: Some(env_prefix),
}
}
}
pub fn save<T>(app_name: &str, config: T) -> io::Result<()>
where
T: serde::Serialize,
{
let path = paths::default_config_path(app_name)?;
file::write_config(&path, &config, file::FileType::TOML)
}
pub fn read<T>(app_name: &str, options: Option<ReadOptions<'_>>) -> Result<T, io::Error>
where
T: serde::de::DeserializeOwned + Default + serde::Serialize,
{
let path = paths::default_config_path(app_name)?;
let config = if !path.is_file() {
let default_config = T::default();
file::write_config(&path, &default_config, file::FileType::TOML)?;
default_config
} else {
file::read_config(&path)?
};
match options.and_then(|options| options.env_prefix) {
Some(prefix) => env::apply_env_overrides(config, prefix),
None => Ok(config),
}
}
#[cfg(test)]
mod tests;