use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use crate::error::Result;
fn default_data_branch() -> Option<String> {
Some("data/itack".to_string())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
#[serde(default)]
pub default_assignee: Option<String>,
#[serde(default)]
pub editor: Option<String>,
#[serde(default = "default_data_branch")]
pub data_branch: Option<String>,
}
impl Default for Config {
fn default() -> Self {
Config {
default_assignee: None,
editor: None,
data_branch: default_data_branch(),
}
}
}
impl Config {
pub fn global_dir() -> Option<PathBuf> {
if let Ok(home) = std::env::var("ITACK_HOME") {
return Some(PathBuf::from(home));
}
dirs::home_dir().map(|h| h.join(".itack"))
}
pub fn global_path() -> Option<PathBuf> {
Self::global_dir().map(|d| d.join("config.toml"))
}
pub fn load_global() -> Result<Self> {
let Some(path) = Self::global_path() else {
return Ok(Config::default());
};
if !path.exists() {
return Ok(Config::default());
}
let content = fs::read_to_string(&path)?;
let config: Config = toml::from_str(&content)?;
Ok(config)
}
#[allow(dead_code)]
pub fn save_global(&self) -> Result<()> {
let Some(dir) = Self::global_dir() else {
return Ok(());
};
fs::create_dir_all(&dir)?;
let path = dir.join("config.toml");
let content = toml::to_string_pretty(self)?;
fs::write(path, content)?;
Ok(())
}
pub fn init_global() -> Result<()> {
let Some(dir) = Self::global_dir() else {
return Ok(());
};
if !dir.exists() {
fs::create_dir_all(&dir)?;
}
Ok(())
}
pub fn get_editor(&self) -> String {
self.editor
.clone()
.or_else(|| std::env::var("EDITOR").ok())
.or_else(|| std::env::var("VISUAL").ok())
.unwrap_or_else(|| "vi".to_string())
}
}