use anyhow::Result;
use directories::ProjectDirs;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
pub verbose: bool,
pub log_level: String,
pub data_dir: PathBuf,
}
impl Default for Config {
fn default() -> Self {
Self {
verbose: false,
log_level: "info".to_string(),
data_dir: Self::default_data_dir(),
}
}
}
impl Config {
pub fn load() -> Result<Self> {
let config_path = Self::config_path()?;
if config_path.exists() {
let content = fs::read_to_string(&config_path)?;
Ok(serde_json::from_str(&content)?)
} else {
Ok(Self::default())
}
}
pub fn save(&self) -> Result<()> {
let config_path = Self::config_path()?;
if let Some(parent) = config_path.parent() {
fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(self)?;
fs::write(&config_path, content)?;
Ok(())
}
fn config_path() -> Result<PathBuf> {
let proj_dirs = ProjectDirs::from("com", "thekaiway", "claco")
.ok_or_else(|| anyhow::anyhow!("Unable to find config directory"))?;
Ok(proj_dirs.config_dir().join("config.json"))
}
fn default_data_dir() -> PathBuf {
ProjectDirs::from("com", "thekaiway", "claco")
.map(|dirs| dirs.data_dir().to_path_buf())
.unwrap_or_else(|| PathBuf::from("./data"))
}
}