use anyhow::{Context, Error};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{
fs::{self, File},
io::{Read, Write},
path::Path,
};
pub fn load_config_file<P, T>(path: P) -> Result<T, Error>
where
T: for<'r> Deserialize<'r>,
P: AsRef<Path>,
{
let path = path.as_ref();
let res = do_load(path).with_context(|| format!("loading config from {}", path.display()))?;
Ok(res)
}
pub fn save_config_file<P, T>(value: &T, path: P) -> Result<(), Error>
where
T: Serialize,
P: AsRef<Path>,
{
let path = path.as_ref();
do_save(value, path).with_context(|| format!("saving config to {}", path.display()))?;
Ok(())
}
fn do_load<T: DeserializeOwned>(path: &Path) -> Result<T, Error> {
let mut file = File::open(path)?;
let mut toml = String::new();
file.read_to_string(&mut toml)?;
Ok(toml::de::from_str(&toml)?)
}
fn do_save<T: Serialize>(value: &T, path: &Path) -> Result<(), Error> {
if let Some(dir) = path.parent() {
fs::create_dir_all(dir)?;
}
let mut file = File::create(path)?;
let value_toml = toml::Value::try_from(value)?;
file.write_all(value_toml.to_string().as_bytes())?;
Ok(())
}