use std::{collections::HashMap, fs, path::PathBuf};
use anyhow::{Result, anyhow};
#[derive(Clone, Debug, PartialEq)]
pub struct Config {
internal: HashMap<String, String>,
pub path: PathBuf,
}
impl Config {
pub fn new<T: AsRef<str>>(name: T) -> Result<Self> {
let mut path = match dirs::config_dir() {
Some(data) => data,
None => return Err(anyhow!("Couldn't get config path")),
};
path.push(format!("{}.yaml", name.as_ref()));
let contents = match fs::read_to_string(&path) {
Ok(data) => data,
Err(_error) => {
let temp: HashMap<String, String> = HashMap::new();
let deserialized = serde_yaml::to_string(&temp)?;
fs::write(&path, deserialized.as_bytes())?;
deserialized
}
};
let internal: HashMap<String, String> = serde_yaml::from_str(contents.as_str())?;
let myself = Self{
internal,
path,
};
Ok(myself)
}
pub fn write_clear_by_name<T: AsRef<str>>(name: T) -> Result<()> {
let mut config = Self::new(name)?;
config.write_clear()
}
pub fn read(&mut self) -> Result<()> {
let contents = fs::read_to_string(&self.path)?;
let internal: HashMap<String, String> = serde_yaml::from_str(contents.as_str())?;
self.internal = internal;
Ok(())
}
pub fn write(&self) -> Result<()> {
let deserialized = serde_yaml::to_string(&self.internal)?;
fs::write(&self.path, deserialized.as_bytes())?;
Ok(())
}
pub fn insert<T: AsRef<str>>(&mut self, key: T, value: T) {
self.internal.insert(key.as_ref().to_string(), value.as_ref().to_string());
}
pub fn get<T: AsRef<str>>(&self, query: T) -> Option<String> {
let res = match self.internal.get(&query.as_ref().to_string()) {
Some(data) => data,
None => return None,
};
Some(res.to_string())
}
pub fn clear(&mut self) {
self.internal.clear();
}
pub fn write_insert<T: AsRef<str>>(&mut self, key: T, value: T) -> Result<()> {
self.insert(key, value);
self.write()
}
pub fn read_get<T: AsRef<str>>(&mut self, query: T) -> Result<Option<String>> {
self.read()?;
Ok(self.get(query))
}
pub fn write_clear(&mut self) -> Result<()> {
self.clear();
self.write()
}
}