Skip to main content

leenfetch_core/config/
settings.rs

1use serde::{Deserialize, Serialize};
2
3/// Describes a single entry in the `modules` array.
4#[derive(Debug, Deserialize, Serialize, Clone)]
5#[serde(untagged)]
6pub enum LayoutItem {
7    Break(String),
8    Module(ModuleEntry),
9}
10
11/// Configuration flags corresponding to display and formatting options.
12#[derive(Debug, Deserialize, Serialize, Clone)]
13pub struct Flags {
14    #[serde(default)]
15    pub ascii_distro: String,
16    #[serde(default)]
17    pub ascii_colors: String,
18    #[serde(default)]
19    pub battery_display: String,
20    #[serde(default)]
21    pub color_blocks: String,
22    #[serde(default)]
23    pub cpu_brand: bool,
24    #[serde(default)]
25    pub cpu_cores: bool,
26    #[serde(default)]
27    pub cpu_frequency: bool,
28    #[serde(default)]
29    pub cpu_speed: bool,
30    #[serde(
31        default,
32        alias = "cpu_show_temp",
33        deserialize_with = "deserialize_cpu_temp"
34    )]
35    pub cpu_temp: String,
36    #[serde(default)]
37    pub custom_logo_path: String,
38    #[serde(default)]
39    pub de_version: bool,
40    #[serde(default)]
41    pub disk_display: String,
42    #[serde(default)]
43    pub disk_percent: bool,
44    #[serde(default)]
45    pub disk_show: String,
46    #[serde(default)]
47    pub disk_subtitle: String,
48    #[serde(default, alias = "distro_display")]
49    pub distro_shorthand: String,
50    #[serde(default)]
51    pub gpu_brand: bool,
52    #[serde(default)]
53    pub gpu_type: String,
54    #[serde(default)]
55    pub kernel_shorthand: bool,
56    #[serde(default)]
57    pub memory_percent: bool,
58    #[serde(default)]
59    pub memory_unit: String,
60    #[serde(default)]
61    pub os_age_shorthand: String,
62    #[serde(default)]
63    pub package_managers: String,
64    #[serde(default)]
65    pub shell_path: bool,
66    #[serde(default)]
67    pub shell_version: bool,
68    #[serde(default)]
69    pub speed_shorthand: bool,
70    #[serde(default)]
71    pub uptime_shorthand: String,
72}
73
74/// Root configuration structure.
75#[derive(Debug, Deserialize, Serialize, Clone)]
76pub struct Config {
77    #[serde(default, rename = "$schema")]
78    #[allow(dead_code)]
79    pub schema: Option<String>,
80    #[serde(default)]
81    #[allow(dead_code)]
82    pub logo: Option<Logo>,
83    #[serde(default)]
84    pub flags: Flags,
85    #[serde(default, alias = "layout", alias = "modules")]
86    pub layout: Vec<LayoutItem>,
87}
88
89/// Minimal representation of the logo block.
90#[derive(Debug, Deserialize, Serialize, Clone, Default)]
91pub struct Logo {
92    #[serde(rename = "type", default)]
93    #[allow(dead_code)]
94    pub logo_type: Option<String>,
95    #[serde(default)]
96    #[allow(dead_code)]
97    pub source: Option<String>,
98}
99
100/// Configuration for an individual info module.
101#[derive(Debug, Deserialize, Serialize, Clone, Default)]
102pub struct ModuleEntry {
103    #[serde(rename = "type", default)]
104    pub module_type: Option<String>,
105    #[serde(default)]
106    pub key: Option<String>,
107    #[serde(default)]
108    pub label: Option<String>,
109    #[serde(default)]
110    pub field: Option<String>,
111    #[serde(default)]
112    pub format: Option<String>,
113    #[serde(default)]
114    pub text: Option<String>,
115}
116
117impl ModuleEntry {
118    pub fn field_name(&self) -> Option<&str> {
119        self.module_type
120            .as_deref()
121            .or(self.field.as_deref())
122            .map(str::trim)
123            .filter(|value| !value.is_empty())
124    }
125
126    pub fn label(&self) -> Option<&str> {
127        self.key.as_deref().or(self.label.as_deref())
128    }
129
130    pub fn is_custom(&self) -> bool {
131        self.field_name()
132            .map(|field| field.eq_ignore_ascii_case("custom"))
133            .unwrap_or(false)
134    }
135}
136
137fn deserialize_cpu_temp<'de, D>(deserializer: D) -> Result<String, D::Error>
138where
139    D: serde::Deserializer<'de>,
140{
141    struct CpuTempVisitor;
142
143    impl<'de> serde::de::Visitor<'de> for CpuTempVisitor {
144        type Value = String;
145
146        fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
147            f.write_str("\"C\", \"F\", \"off\", true, or false")
148        }
149
150        fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<String, E> {
151            match v.to_lowercase().as_str() {
152                "c" | "f" => Ok(v.to_uppercase()),
153                "off" => Ok("off".to_string()),
154                _ => Err(serde::de::Error::custom(format!("invalid cpu_temp: {v}"))),
155            }
156        }
157
158        fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<String, E> {
159            Ok(if v {
160                "C".to_string()
161            } else {
162                "off".to_string()
163            })
164        }
165    }
166
167    deserializer.deserialize_any(CpuTempVisitor)
168}
169
170impl Default for Flags {
171    fn default() -> Self {
172        Self {
173            ascii_distro: "auto".into(),
174            ascii_colors: "distro".into(),
175            custom_logo_path: String::new(),
176            battery_display: "barinfo".into(),
177            color_blocks: "███".into(),
178            cpu_brand: true,
179            cpu_cores: true,
180            cpu_frequency: true,
181            cpu_speed: true,
182            cpu_temp: "C".into(),
183            de_version: true,
184            disk_display: "barinfo".into(),
185            disk_percent: true,
186            disk_show: "/".into(),
187            disk_subtitle: "dir".into(),
188            distro_shorthand: "name".into(),
189            gpu_brand: true,
190            gpu_type: "all".into(),
191            kernel_shorthand: true,
192            memory_percent: true,
193            memory_unit: "mib".into(),
194            os_age_shorthand: "full".into(),
195            package_managers: "tiny".into(),
196            shell_path: true,
197            shell_version: true,
198            speed_shorthand: false,
199            uptime_shorthand: "full".into(),
200        }
201    }
202}