Skip to main content

retch_cli/
config.rs

1use serde::{Deserialize, Serialize};
2use std::fs;
3use std::path::PathBuf;
4
5/// Configuration for the retch CLI.
6///
7/// This struct represents the options that can be set in the `config.toml` file.
8#[derive(Debug, Serialize, Deserialize, Default, Clone)]
9pub struct Config {
10    /// The name of the theme to use (e.g., "dark", "catppuccin-mocha").
11    pub theme: Option<String>,
12    /// Whether to display the distro logo.
13    pub show_logo: Option<bool>,
14    /// Whether to force ASCII-only logo output.
15    pub ascii_only: Option<bool>,
16    /// List of fields to display, in order.
17    pub fields: Option<Vec<String>>,
18    /// Custom theme color overrides.
19    pub custom_theme: Option<CustomTheme>,
20}
21
22/// Custom color overrides for themes.
23///
24/// Allows users to specify hex codes or color names for specific UI elements.
25#[derive(Debug, Serialize, Deserialize, Default, Clone)]
26pub struct CustomTheme {
27    /// Color for field labels.
28    pub label_color: Option<String>,
29    /// Color for field values.
30    pub value_color: Option<String>,
31    /// Color for accent elements.
32    pub accent_color: Option<String>,
33    /// Color for the title/username line.
34    pub title_color: Option<String>,
35    /// Color for separators.
36    pub separator_color: Option<String>,
37}
38
39impl Config {
40    /// Loads the configuration from the default system path.
41    ///
42    /// Typically looks in `~/.config/retch/config.toml`.
43    pub fn load() -> anyhow::Result<Self> {
44        if let Some(path) = Self::config_path() {
45            if path.exists() {
46                let contents = fs::read_to_string(&path)?;
47                let config: Config = toml::from_str(&contents)?;
48                return Ok(config);
49            }
50        }
51        Ok(Self::default())
52    }
53
54    /// Returns the expected path to the configuration file.
55    pub fn config_path() -> Option<PathBuf> {
56        dirs::config_dir().map(|mut p| {
57            p.push("retch");
58            p.push("config.toml");
59            p
60        })
61    }
62
63    /// Merges CLI options into the configuration.
64    ///
65    /// CLI arguments take precedence over values defined in the config file.
66    pub fn merge_with_cli(&self, cli: &crate::cli::Cli) -> Self {
67        let mut merged = self.clone();
68
69        if let Some(theme) = &cli.theme {
70            merged.theme = Some(theme.clone());
71        }
72        if cli.no_logo {
73            merged.show_logo = Some(false);
74        }
75        if cli.ascii_only {
76            merged.ascii_only = Some(true);
77        }
78        if let Some(fields_str) = &cli.fields {
79            // Split comma-separated string into Vec<String>
80            let fields = fields_str
81                .split(',')
82                .map(|s| s.trim().to_string())
83                .filter(|s| !s.is_empty())
84                .collect::<Vec<String>>();
85            merged.fields = Some(fields);
86        }
87
88        merged
89    }
90}