use ini::{Ini, Properties};
use std::{path::PathBuf, str::FromStr};
#[derive(Debug, Clone, Default)]
pub struct Preferences {
path: PathBuf,
content: Ini,
}
impl Preferences {
#[inline]
pub fn new(path: PathBuf) -> Self {
let content = Ini::load_from_file(&path).unwrap_or_default();
Self { path, content }
}
#[inline]
pub fn section(&self, section: &str) -> Option<&Properties> {
self.content.section(Some(section))
}
#[inline]
pub fn contains(&self, section: &str, key: &str) -> bool {
self.content
.get_from(Some(section), key)
.is_some_and(|s| !s.is_empty())
}
#[inline]
pub fn get(&self, section: &str, key: &str) -> Option<&str> {
self.content.get_from(Some(section), key)
}
#[inline]
pub fn parse<T: FromStr>(
&self,
section: &str,
key: &str,
) -> Option<Result<T, <T as FromStr>::Err>> {
self.get(section, key).map(|s| s.parse())
}
pub fn update(&mut self, section: &str, key: &str, value: String) {
let path = self.path.as_path();
self.content.with_section(Some(section)).set(key, value);
if let Err(err) = self.content.write_to_file(path) {
tracing::error!("fail to write `{}`: {}", path.display(), err);
}
}
}