use ini::Ini;
use std::path::PathBuf;
pub struct Config {
path: PathBuf,
ini: Ini,
}
fn split_key(key: &str) -> (String, String) {
match key.split_once('_') {
Some((section, option)) => (section.to_lowercase(), option.to_lowercase()),
None => (key.to_lowercase(), key.to_lowercase()),
}
}
impl Config {
pub fn load() -> Self {
let path = Self::config_path();
let ini = Ini::load_from_file(&path).unwrap_or_default();
Config { path, ini }
}
fn config_path() -> PathBuf {
std::env::current_exe()
.ok()
.and_then(|p| p.parent().map(|p| p.to_path_buf()))
.unwrap_or_else(|| PathBuf::from("."))
.join("idm.ini")
}
pub fn get(&self, key: &str) -> Option<String> {
let (section, option) = split_key(key);
self.ini
.section(Some(section.as_str()))
.and_then(|s| s.get(option.as_str()))
.map(|v| v.to_string())
}
pub fn get_bool(&self, key: &str) -> bool {
match self.get(key) {
Some(v) => matches!(v.to_lowercase().as_str(), "1" | "true" | "yes" | "on" | "ok"),
None => false,
}
}
pub fn write_config(&mut self, section: &str, option: &str, value: &str) -> anyhow::Result<()> {
self.ini
.with_section(Some(section.to_lowercase()))
.set(option.to_lowercase(), value);
self.ini.write_to_file(&self.path)?;
Ok(())
}
pub fn print_docs(&self) {
use colored::*;
println!("{}", "uppercase words is VALUE NAME".cyan());
println!();
println!("{}", "download:path:DIR_NAME".bright_yellow());
println!("{}", "download:confirm:1 or 0".bright_green());
println!("{}", "data:user_agent:STRING".bright_green());
println!("{}", "debug:verbose:1 or 0".bright_green());
}
}