gitfetch_rs/config/
manager.rs

1use anyhow::Result;
2use directories::ProjectDirs;
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Debug, Serialize, Deserialize)]
7pub struct Config {
8  pub provider: Option<String>,
9  pub provider_url: Option<String>,
10  pub token: Option<String>,
11  pub default_username: Option<String>,
12  pub cache_expiry_minutes: u32,
13  pub custom_box: Option<String>,
14  #[serde(default = "default_show_date")]
15  pub show_date: bool,
16  pub colors: ColorConfig,
17}
18
19fn default_show_date() -> bool {
20  true
21}
22
23impl Default for Config {
24  fn default() -> Self {
25    Self {
26      provider: None,
27      provider_url: None,
28      token: None,
29      default_username: None,
30      cache_expiry_minutes: 15,
31      custom_box: None,
32      show_date: true,
33      colors: ColorConfig::default(),
34    }
35  }
36}
37
38#[derive(Debug, Serialize, Deserialize)]
39pub struct ColorConfig {
40  pub level_0: String,
41  pub level_1: String,
42  pub level_2: String,
43  pub level_3: String,
44  pub level_4: String,
45}
46
47impl Default for ColorConfig {
48  fn default() -> Self {
49    Self {
50      level_0: "#ebedf0".to_string(), // Light gray like Python
51      level_1: "#9be9a8".to_string(),
52      level_2: "#40c463".to_string(),
53      level_3: "#30a14e".to_string(),
54      level_4: "#216e39".to_string(),
55    }
56  }
57}
58
59pub struct ConfigManager {
60  config_path: PathBuf,
61  pub config: Config,
62}
63
64impl ConfigManager {
65  pub fn new() -> Result<Self> {
66    let project_dirs = ProjectDirs::from("com", "gitfetch", "gitfetch-rs")
67      .ok_or_else(|| anyhow::anyhow!("Could not determine config directory"))?;
68
69    let config_dir = project_dirs.config_dir();
70    std::fs::create_dir_all(config_dir)?;
71
72    let config_path = config_dir.join("config.toml");
73
74    let config = if config_path.exists() {
75      let content = std::fs::read_to_string(&config_path)?;
76      toml::from_str(&content).unwrap_or_else(|_| Config::default())
77    } else {
78      // Use defaults if no config file exists (like Python version)
79      Config::default()
80    };
81
82    Ok(Self {
83      config_path,
84      config,
85    })
86  }
87
88  pub fn is_initialized(&self) -> bool {
89    self.config.provider.is_some()
90  }
91
92  pub fn save(&self) -> Result<()> {
93    let content = toml::to_string_pretty(&self.config)?;
94    std::fs::write(&self.config_path, content)?;
95    Ok(())
96  }
97
98  pub fn get_provider(&self) -> Option<&str> {
99    self.config.provider.as_deref()
100  }
101
102  pub fn set_provider(&mut self, provider: String) {
103    self.config.provider = Some(provider);
104  }
105
106  pub fn get_provider_url(&self) -> Option<&str> {
107    self.config.provider_url.as_deref()
108  }
109
110  pub fn set_provider_url(&mut self, url: String) {
111    self.config.provider_url = Some(url);
112  }
113
114  pub fn get_token(&self) -> Option<&str> {
115    self.config.token.as_deref()
116  }
117
118  pub fn set_token(&mut self, token: String) {
119    self.config.token = Some(token);
120  }
121
122  pub fn get_default_username(&self) -> Option<&str> {
123    self.config.default_username.as_deref()
124  }
125
126  pub fn set_default_username(&mut self, username: String) {
127    self.config.default_username = Some(username);
128  }
129}