Skip to main content

framework_tool_tui/
config.rs

1use std::fs;
2use std::path::PathBuf;
3
4use serde::{Deserialize, Serialize};
5
6use crate::tui::theme::ThemeVariant;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct Config {
10    pub theme: ThemeVariant,
11    #[serde(default = "default_tick_interval")]
12    pub tick_interval_ms: u64,
13}
14
15fn default_tick_interval() -> u64 {
16    1000
17}
18
19impl Default for Config {
20    fn default() -> Self {
21        Self {
22            theme: ThemeVariant::Default,
23            tick_interval_ms: 1000,
24        }
25    }
26}
27
28impl Config {
29    /// Get the config file path
30    fn config_path() -> color_eyre::Result<PathBuf> {
31        let data_dir = dirs::data_local_dir()
32            .ok_or_else(|| color_eyre::eyre::eyre!("Could not determine local data directory"))?;
33
34        let config_dir = data_dir.join("framework-tool-tui");
35        fs::create_dir_all(&config_dir)?;
36
37        Ok(config_dir.join("config.toml"))
38    }
39
40    /// Load configuration from file, or create default if it doesn't exist
41    pub fn load_or_create() -> color_eyre::Result<Self> {
42        match Self::load() {
43            Ok(config) => Ok(config),
44            Err(_) => {
45                // First startup or invalid config - create default
46                let config = Config::default();
47                config.save()?;
48                Ok(config)
49            }
50        }
51    }
52
53    /// Save configuration to file
54    pub fn save(&self) -> color_eyre::Result<()> {
55        let config_path = Self::config_path()?;
56        let content = toml::to_string_pretty(self)?;
57        fs::write(&config_path, content)?;
58        Ok(())
59    }
60
61    /// Update the theme and save
62    pub fn set_theme(&mut self, theme: ThemeVariant) -> color_eyre::Result<()> {
63        self.theme = theme;
64        self.save()
65    }
66
67    /// Update the tick interval and save
68    pub fn set_tick_interval(&mut self, tick_interval_ms: u64) -> color_eyre::Result<()> {
69        self.tick_interval_ms = tick_interval_ms;
70        self.save()
71    }
72
73    fn load() -> color_eyre::Result<Self> {
74        let config_path = Self::config_path()?;
75        let content = fs::read_to_string(&config_path)?;
76        let config = toml::from_str::<Config>(&content)?;
77
78        Ok(config)
79    }
80}