use std::fs;
use std::path::PathBuf;
use anyhow::Result;
use directories::ProjectDirs;
use serde::{Deserialize, Serialize};
use crate::tui::style::Theme;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct Config {
#[serde(default = "default_holidays_locale")]
pub holidays_locale: String,
pub theme: Theme,
}
impl Config {
pub fn load() -> Result<Self> {
let path = config_path()?;
if !path.exists() {
let cfg = Config::default();
cfg.save()?;
return Ok(cfg);
}
let contents = fs::read_to_string(&path)?;
let cfg: Config = toml::from_str(&contents)?;
Ok(cfg)
}
pub fn save(&self) -> Result<()> {
let path = config_path()?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let contents = toml::to_string_pretty(self)?;
fs::write(&path, contents)?;
Ok(())
}
pub fn path() -> Result<PathBuf> {
config_path()
}
}
fn default_holidays_locale() -> String {
"none".to_string()
}
fn config_path() -> Result<PathBuf> {
let config_dir = if let Ok(dir) = std::env::var("RUSTODO_CONFIG_DIR") {
PathBuf::from(dir)
} else {
let dirs = ProjectDirs::from("", "", "rustodo")
.ok_or_else(|| anyhow::anyhow!("Could not determine config directory"))?;
dirs.config_dir().to_path_buf()
};
fs::create_dir_all(&config_dir)?;
Ok(config_dir.join("config.toml"))
}