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