lx_cli/
config.rs

1use colored::Color;
2use serde::Deserialize;
3use std::fs;
4use std::path::PathBuf;
5
6#[derive(Debug, Deserialize, Clone)]
7pub struct Config {
8    #[serde(default)]
9    pub colors: ColorConfig,
10    #[serde(default)]
11    pub icons: IconConfig,
12    #[serde(default)]
13    pub display: DisplayConfig,
14}
15
16#[derive(Debug, Deserialize, Clone)]
17pub struct ColorConfig {
18    #[serde(default = "default_directory_color")]
19    pub directory: String,
20    #[serde(default = "default_executable_color")]
21    pub executable: String,
22    #[serde(default = "default_regular_color")]
23    pub regular: String,
24}
25
26#[derive(Debug, Deserialize, Clone)]
27pub struct IconConfig {
28    #[serde(default = "default_directory_icon")]
29    pub directory: String,
30    #[serde(default = "default_executable_icon")]
31    pub executable: String,
32    #[serde(default = "default_regular_icon")]
33    pub regular: String,
34    #[serde(default)]
35    pub colors: IconColorConfig,
36}
37
38#[derive(Debug, Deserialize, Clone)]
39pub struct IconColorConfig {
40    #[serde(default = "default_directory_icon_color")]
41    pub directory: String,
42    #[serde(default = "default_executable_icon_color")]
43    pub executable: String,
44    #[serde(default = "default_regular_icon_color")]
45    pub regular: String,
46}
47
48#[derive(Debug, Deserialize, Clone)]
49pub struct DisplayConfig {
50    #[serde(default = "default_column_spacing")]
51    pub column_spacing: usize,
52    #[serde(default = "default_max_rows")]
53    pub max_rows: usize,
54}
55
56impl Default for Config {
57    fn default() -> Self {
58        Config {
59            colors: ColorConfig::default(),
60            icons: IconConfig::default(),
61            display: DisplayConfig::default(),
62        }
63    }
64}
65
66impl Default for IconConfig {
67    fn default() -> Self {
68        IconConfig {
69            directory: default_directory_icon(),
70            executable: default_executable_icon(),
71            regular: default_regular_icon(),
72            colors: IconColorConfig::default(),
73        }
74    }
75}
76
77impl Default for IconColorConfig {
78    fn default() -> Self {
79        IconColorConfig {
80            directory: default_directory_icon_color(),
81            executable: default_executable_icon_color(),
82            regular: default_regular_icon_color(),
83        }
84    }
85}
86
87impl Default for ColorConfig {
88    fn default() -> Self {
89        ColorConfig {
90            directory: default_directory_color(),
91            executable: default_executable_color(),
92            regular: default_regular_color(),
93        }
94    }
95}
96
97impl Default for DisplayConfig {
98    fn default() -> Self {
99        DisplayConfig {
100            column_spacing: default_column_spacing(),
101            max_rows: default_max_rows(),
102        }
103    }
104}
105
106fn default_directory_color() -> String {
107    "blue".to_string()
108}
109
110fn default_executable_color() -> String {
111    "green".to_string()
112}
113
114fn default_regular_color() -> String {
115    "white".to_string()
116}
117
118fn default_column_spacing() -> usize {
119    2
120}
121
122fn default_max_rows() -> usize {
123    0 // 0 means no limit
124}
125
126fn default_directory_icon() -> String {
127    "".to_string()
128}
129
130fn default_executable_icon() -> String {
131    "".to_string()
132}
133
134fn default_regular_icon() -> String {
135    "".to_string()
136}
137
138fn default_directory_icon_color() -> String {
139    "blue".to_string()
140}
141
142fn default_executable_icon_color() -> String {
143    "green".to_string()
144}
145
146fn default_regular_icon_color() -> String {
147    "white".to_string()
148}
149
150impl ColorConfig {
151    pub fn get_directory_color(&self) -> Color {
152        parse_color(&self.directory)
153    }
154
155    pub fn get_executable_color(&self) -> Color {
156        parse_color(&self.executable)
157    }
158
159    pub fn get_regular_color(&self) -> Color {
160        parse_color(&self.regular)
161    }
162}
163
164impl IconColorConfig {
165    pub fn get_directory_color(&self) -> Color {
166        parse_color(&self.directory)
167    }
168
169    pub fn get_executable_color(&self) -> Color {
170        parse_color(&self.executable)
171    }
172
173    pub fn get_regular_color(&self) -> Color {
174        parse_color(&self.regular)
175    }
176}
177
178impl IconConfig {
179    pub fn get_directory_icon(&self) -> String {
180        self.directory.clone()
181    }
182
183    pub fn get_executable_icon(&self) -> String {
184        self.executable.clone()
185    }
186
187    pub fn get_regular_icon(&self) -> String {
188        self.regular.clone()
189    }
190}
191
192fn parse_color(color_str: &str) -> Color {
193    match color_str.to_lowercase().as_str() {
194        "black" => Color::Black,
195        "red" => Color::Red,
196        "green" => Color::Green,
197        "yellow" => Color::Yellow,
198        "blue" => Color::Blue,
199        "magenta" => Color::Magenta,
200        "cyan" => Color::Cyan,
201        "white" => Color::White,
202        "bright_black" => Color::BrightBlack,
203        "bright_red" => Color::BrightRed,
204        "bright_green" => Color::BrightGreen,
205        "bright_yellow" => Color::BrightYellow,
206        "bright_blue" => Color::BrightBlue,
207        "bright_magenta" => Color::BrightMagenta,
208        "bright_cyan" => Color::BrightCyan,
209        "bright_white" => Color::BrightWhite,
210        _ => Color::White, // Default fallback
211    }
212}
213
214pub fn load_config() -> Config {
215    let config_path = get_config_path();
216
217    if !config_path.exists() {
218        return Config::default();
219    }
220
221    match fs::read_to_string(&config_path) {
222        Ok(contents) => match toml::from_str(&contents) {
223            Ok(config) => config,
224            Err(e) => {
225                eprintln!("Warning: Failed to parse config file: {}", e);
226                Config::default()
227            }
228        },
229        Err(_) => Config::default(),
230    }
231}
232
233fn get_config_path() -> PathBuf {
234    let mut path = dirs::home_dir().unwrap_or_else(|| PathBuf::from("."));
235    path.push(".config");
236    path.push("lx");
237    path.push("config");
238    path
239}