use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::fs;
const CONFIG_DIR: &str = ".cahier";
const CONFIG_FILE: &str = "config.json";
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Config {
#[serde(default = "default_ignored_outputs")]
pub ignored_outputs: Vec<String>,
#[serde(default = "default_theme")]
pub theme: String,
#[serde(default = "default_load_aliases")]
pub load_aliases: bool,
#[serde(default = "default_restore_env")]
pub restore_env: bool,
}
fn default_ignored_outputs() -> Vec<String> {
vec![
"nano".to_string(),
"vim".to_string(),
"vi".to_string(),
"emacs".to_string(),
"hx".to_string(),
"atom".to_string(),
"gedit".to_string(),
"geany".to_string(),
"kate".to_string(),
"kwrite".to_string(),
"nvim".to_string(),
"htop".to_string(),
"top".to_string(),
"atop".to_string(),
"less".to_string(),
"more".to_string(),
"man".to_string(),
"ssh".to_string(),
"tmux".to_string(),
"screen".to_string(),
]
}
fn default_theme() -> String {
"Solarized (dark)".to_string()
}
fn default_load_aliases() -> bool {
true
}
fn default_restore_env() -> bool {
false
}
impl Default for Config {
fn default() -> Self {
Self {
ignored_outputs: default_ignored_outputs(),
theme: default_theme(),
load_aliases: default_load_aliases(),
restore_env: default_restore_env(),
}
}
}
impl Config {
pub fn load() -> Result<Self> {
let home_dir =
dirs::home_dir().ok_or_else(|| anyhow::anyhow!("Could not find home directory"))?;
let config_path = home_dir.join(CONFIG_DIR).join(CONFIG_FILE);
if !config_path.exists() {
let default_config = Config::default();
if let Some(parent) = config_path.parent() {
fs::create_dir_all(parent)?;
}
let json = serde_json::to_string_pretty(&default_config)?;
#[cfg(unix)]
{
use std::os::unix::fs::OpenOptionsExt;
let mut options = fs::OpenOptions::new();
options.write(true).create(true).truncate(true).mode(0o600);
let mut file = options.open(&config_path)?;
use std::io::Write;
file.write_all(json.as_bytes())?;
}
#[cfg(not(unix))]
{
fs::write(&config_path, json)?;
}
return Ok(default_config);
}
let content = fs::read_to_string(&config_path)?;
let config: Config = serde_json::from_str(&content)?;
Ok(config)
}
}