use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Theme {
#[default]
Light,
Dark,
System,
#[serde(rename = "high_contrast_light")]
HighContrastLight,
#[serde(rename = "high_contrast_dark")]
HighContrastDark,
}
impl std::fmt::Display for Theme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Theme::Light => write!(f, "Light"),
Theme::Dark => write!(f, "Dark"),
Theme::System => write!(f, "System"),
Theme::HighContrastLight => write!(f, "High Contrast Light"),
Theme::HighContrastDark => write!(f, "High Contrast Dark"),
}
}
}
impl Theme {
pub fn is_high_contrast(self) -> bool {
matches!(self, Theme::HighContrastLight | Theme::HighContrastDark)
}
pub fn choices() -> &'static [Theme] {
&[Theme::Light, Theme::Dark, Theme::HighContrastLight, Theme::HighContrastDark]
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct UserPrefs {
#[serde(default)]
pub theme: Theme,
#[serde(default)]
pub language: String,
#[serde(default = "default_ignored_dirs")]
pub global_ignored_dirs: Vec<String>,
}
fn default_ignored_dirs() -> Vec<String> {
vec![
".git".into(),
"target".into(),
"node_modules".into(),
".DS_Store".into(),
]
}
impl UserPrefs {
fn path() -> anyhow::Result<PathBuf> {
let base = dirs::config_dir()
.ok_or_else(|| anyhow::anyhow!("Cannot determine OS config directory"))?
.join("aaai");
std::fs::create_dir_all(&base)?;
Ok(base.join("prefs.yaml"))
}
pub fn load() -> Self {
match Self::path().and_then(|p| {
if !p.exists() { return Ok(Self::default()); }
let text = std::fs::read_to_string(&p)?;
serde_yaml::from_str(&text).map_err(|e| anyhow::anyhow!(e))
}) {
Ok(prefs) => prefs,
Err(e) => {
log::warn!("Could not load prefs: {e}");
Self::default()
}
}
}
pub fn save(&self) {
if let Err(e) = Self::path().and_then(|p| {
let yaml = serde_yaml::to_string(self).map_err(|e| anyhow::anyhow!(e))?;
std::fs::write(&p, yaml)?;
Ok(())
}) {
log::warn!("Could not save prefs: {e}");
}
}
}
#[cfg(test)]
mod tests;