1use anyhow::Result;
4use core::fmt;
5use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
6use std::fs;
7use std::path::PathBuf;
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Default, Debug, Serialize, Deserialize)]
13pub struct TcaSection {
14 pub default_theme: Option<String>,
17 pub default_dark_theme: Option<String>,
19 pub default_light_theme: Option<String>,
21}
22
23#[derive(Default, Debug, Serialize, Deserialize)]
28pub struct TcaConfig {
29 #[serde(default)]
30 pub tca: TcaSection,
32}
33
34impl TcaConfig {
35 pub fn path() -> Result<PathBuf> {
37 let strategy = choose_app_strategy(AppStrategyArgs {
38 top_level_domain: "org".into(),
39 author: "TCA".into(),
40 app_name: "tca".into(),
41 })?;
42 Ok(strategy.config_dir().join("tca.toml"))
43 }
44
45 pub fn load() -> Self {
49 let Ok(path) = TcaConfig::path() else {
50 return Self::default();
51 };
52 let Ok(content) = fs::read_to_string(path) else {
53 return Self::default();
54 };
55 toml::from_str::<TcaConfig>(&content).unwrap_or_default()
56 }
57
58 pub fn store(&self) -> Result<()> {
60 let path = TcaConfig::path()?;
61 if let Some(parent) = path.parent() {
62 fs::create_dir_all(parent)?;
63 }
64 let content = toml::to_string(self)?;
65 fs::write(&path, content)?;
66 Ok(())
67 }
68}
69
70impl fmt::Display for TcaConfig {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 write!(
73 f,
74 "default: {:?}\ndefault_dark: {:?}\ndefault_light: {:?}",
75 self.tca.default_theme.as_deref().unwrap_or("None"),
76 self.tca.default_dark_theme.as_deref().unwrap_or("None"),
77 self.tca.default_light_theme.as_deref().unwrap_or("None"),
78 )
79 }
80}