nu_data/
primitive.rs

1use crate::config::NuConfig;
2use nu_ansi_term::{Color, Style};
3use nu_protocol::{hir::Number, Primitive, Value};
4use nu_table::{Alignment, TextStyle};
5use std::collections::HashMap;
6
7pub fn number(number: impl Into<Number>) -> Primitive {
8    let number = number.into();
9
10    match number {
11        Number::BigInt(int) => Primitive::BigInt(int),
12        Number::Int(int) => Primitive::Int(int),
13        Number::Decimal(decimal) => Primitive::Decimal(decimal),
14    }
15}
16
17pub fn lookup_ansi_color_style(s: String) -> Style {
18    match s.as_str() {
19        "g" | "green" => Color::Green.normal(),
20        "gb" | "green_bold" => Color::Green.bold(),
21        "gu" | "green_underline" => Color::Green.underline(),
22        "gi" | "green_italic" => Color::Green.italic(),
23        "gd" | "green_dimmed" => Color::Green.dimmed(),
24        "gr" | "green_reverse" => Color::Green.reverse(),
25        "gbl" | "green_blink" => Color::Green.blink(),
26        "gst" | "green_strike" => Color::Green.strikethrough(),
27        "r" | "red" => Color::Red.normal(),
28        "rb" | "red_bold" => Color::Red.bold(),
29        "ru" | "red_underline" => Color::Red.underline(),
30        "ri" | "red_italic" => Color::Red.italic(),
31        "rd" | "red_dimmed" => Color::Red.dimmed(),
32        "rr" | "red_reverse" => Color::Red.reverse(),
33        "rbl" | "red_blink" => Color::Red.blink(),
34        "rst" | "red_strike" => Color::Red.strikethrough(),
35        "u" | "blue" => Color::Blue.normal(),
36        "ub" | "blue_bold" => Color::Blue.bold(),
37        "uu" | "blue_underline" => Color::Blue.underline(),
38        "ui" | "blue_italic" => Color::Blue.italic(),
39        "ud" | "blue_dimmed" => Color::Blue.dimmed(),
40        "ur" | "blue_reverse" => Color::Blue.reverse(),
41        "ubl" | "blue_blink" => Color::Blue.blink(),
42        "ust" | "blue_strike" => Color::Blue.strikethrough(),
43        "b" | "black" => Color::Black.normal(),
44        "bb" | "black_bold" => Color::Black.bold(),
45        "bu" | "black_underline" => Color::Black.underline(),
46        "bi" | "black_italic" => Color::Black.italic(),
47        "bd" | "black_dimmed" => Color::Black.dimmed(),
48        "br" | "black_reverse" => Color::Black.reverse(),
49        "bbl" | "black_blink" => Color::Black.blink(),
50        "bst" | "black_strike" => Color::Black.strikethrough(),
51        "y" | "yellow" => Color::Yellow.normal(),
52        "yb" | "yellow_bold" => Color::Yellow.bold(),
53        "yu" | "yellow_underline" => Color::Yellow.underline(),
54        "yi" | "yellow_italic" => Color::Yellow.italic(),
55        "yd" | "yellow_dimmed" => Color::Yellow.dimmed(),
56        "yr" | "yellow_reverse" => Color::Yellow.reverse(),
57        "ybl" | "yellow_blink" => Color::Yellow.blink(),
58        "yst" | "yellow_strike" => Color::Yellow.strikethrough(),
59        "p" | "purple" => Color::Purple.normal(),
60        "pb" | "purple_bold" => Color::Purple.bold(),
61        "pu" | "purple_underline" => Color::Purple.underline(),
62        "pi" | "purple_italic" => Color::Purple.italic(),
63        "pd" | "purple_dimmed" => Color::Purple.dimmed(),
64        "pr" | "purple_reverse" => Color::Purple.reverse(),
65        "pbl" | "purple_blink" => Color::Purple.blink(),
66        "pst" | "purple_strike" => Color::Purple.strikethrough(),
67        "c" | "cyan" => Color::Cyan.normal(),
68        "cb" | "cyan_bold" => Color::Cyan.bold(),
69        "cu" | "cyan_underline" => Color::Cyan.underline(),
70        "ci" | "cyan_italic" => Color::Cyan.italic(),
71        "cd" | "cyan_dimmed" => Color::Cyan.dimmed(),
72        "cr" | "cyan_reverse" => Color::Cyan.reverse(),
73        "cbl" | "cyan_blink" => Color::Cyan.blink(),
74        "cst" | "cyan_strike" => Color::Cyan.strikethrough(),
75        "w" | "white" => Color::White.normal(),
76        "wb" | "white_bold" => Color::White.bold(),
77        "wu" | "white_underline" => Color::White.underline(),
78        "wi" | "white_italic" => Color::White.italic(),
79        "wd" | "white_dimmed" => Color::White.dimmed(),
80        "wr" | "white_reverse" => Color::White.reverse(),
81        "wbl" | "white_blink" => Color::White.blink(),
82        "wst" | "white_strike" => Color::White.strikethrough(),
83        _ => Color::White.normal(),
84    }
85}
86
87pub fn string_to_lookup_value(str_prim: &str) -> String {
88    match str_prim {
89        "primitive_int" => "Primitive::Int".to_string(),
90        "primitive_decimal" => "Primitive::Decimal".to_string(),
91        "primitive_filesize" => "Primitive::Filesize".to_string(),
92        "primitive_string" => "Primitive::String".to_string(),
93        "primitive_line" => "Primitive::Line".to_string(),
94        "primitive_columnpath" => "Primitive::ColumnPath".to_string(),
95        "primitive_pattern" => "Primitive::GlobPattern".to_string(),
96        "primitive_boolean" => "Primitive::Boolean".to_string(),
97        "primitive_date" => "Primitive::Date".to_string(),
98        "primitive_duration" => "Primitive::Duration".to_string(),
99        "primitive_range" => "Primitive::Range".to_string(),
100        "primitive_path" => "Primitive::FilePath".to_string(),
101        "primitive_binary" => "Primitive::Binary".to_string(),
102        "separator_color" => "separator_color".to_string(),
103        "header_align" => "header_align".to_string(),
104        "header_color" => "header_color".to_string(),
105        "header_style" => "header_style".to_string(),
106        "index_color" => "index_color".to_string(),
107        "leading_trailing_space_bg" => "leading_trailing_space_bg".to_string(),
108        _ => "Primitive::Nothing".to_string(),
109    }
110}
111
112fn update_hashmap(key: &str, val: &Value, hm: &mut HashMap<String, Style>) {
113    if let Ok(var) = val.as_string() {
114        let color = lookup_ansi_color_style(var);
115        let prim = string_to_lookup_value(key);
116        if let Some(v) = hm.get_mut(&prim) {
117            *v = color;
118        } else {
119            hm.insert(prim, color);
120        }
121    }
122}
123
124pub fn get_color_config(config: &NuConfig) -> HashMap<String, Style> {
125    let config = &config.vars;
126
127    // create the hashmap
128    let mut hm: HashMap<String, Style> = HashMap::new();
129    // set some defaults
130    hm.insert("primitive_int".to_string(), Color::White.normal());
131    hm.insert("primitive_decimal".to_string(), Color::White.normal());
132    hm.insert("primitive_filesize".to_string(), Color::White.normal());
133    hm.insert("primitive_string".to_string(), Color::White.normal());
134    hm.insert("primitive_line".to_string(), Color::White.normal());
135    hm.insert("primitive_columnpath".to_string(), Color::White.normal());
136    hm.insert("primitive_pattern".to_string(), Color::White.normal());
137    hm.insert("primitive_boolean".to_string(), Color::White.normal());
138    hm.insert("primitive_date".to_string(), Color::White.normal());
139    hm.insert("primitive_duration".to_string(), Color::White.normal());
140    hm.insert("primitive_range".to_string(), Color::White.normal());
141    hm.insert("primitive_path".to_string(), Color::White.normal());
142    hm.insert("primitive_binary".to_string(), Color::White.normal());
143    hm.insert("separator_color".to_string(), Color::White.normal());
144    hm.insert("header_align".to_string(), Color::Green.bold());
145    hm.insert("header_color".to_string(), Color::Green.bold());
146    hm.insert("header_style".to_string(), Style::default());
147    hm.insert("index_color".to_string(), Color::Green.bold());
148    hm.insert(
149        "leading_trailing_space_bg".to_string(),
150        Style::default().on(Color::Rgb(128, 128, 128)),
151    );
152
153    // populate hashmap from config values
154    if let Some(primitive_color_vars) = config.get("color_config") {
155        for (key, value) in primitive_color_vars.row_entries() {
156            match key.as_ref() {
157                "primitive_int" => {
158                    update_hashmap(key, value, &mut hm);
159                }
160                "primitive_decimal" => {
161                    update_hashmap(key, value, &mut hm);
162                }
163                "primitive_filesize" => {
164                    update_hashmap(key, value, &mut hm);
165                }
166                "primitive_string" => {
167                    update_hashmap(key, value, &mut hm);
168                }
169                "primitive_line" => {
170                    update_hashmap(key, value, &mut hm);
171                }
172                "primitive_columnpath" => {
173                    update_hashmap(key, value, &mut hm);
174                }
175                "primitive_pattern" => {
176                    update_hashmap(key, value, &mut hm);
177                }
178                "primitive_boolean" => {
179                    update_hashmap(key, value, &mut hm);
180                }
181                "primitive_date" => {
182                    update_hashmap(key, value, &mut hm);
183                }
184                "primitive_duration" => {
185                    update_hashmap(key, value, &mut hm);
186                }
187                "primitive_range" => {
188                    update_hashmap(key, value, &mut hm);
189                }
190                "primitive_path" => {
191                    update_hashmap(key, value, &mut hm);
192                }
193                "primitive_binary" => {
194                    update_hashmap(key, value, &mut hm);
195                }
196                "separator_color" => {
197                    update_hashmap(key, value, &mut hm);
198                }
199                "header_align" => {
200                    update_hashmap(key, value, &mut hm);
201                }
202                "header_color" => {
203                    update_hashmap(key, value, &mut hm);
204                }
205                "header_style" => {
206                    update_hashmap(key, value, &mut hm);
207                }
208                "index_color" => {
209                    update_hashmap(key, value, &mut hm);
210                }
211                "leading_trailing_space_bg" => {
212                    update_hashmap(key, value, &mut hm);
213                }
214                _ => (),
215            }
216        }
217    }
218
219    hm
220}
221
222// This function will assign a text style to a primitive, or really any string that's
223// in the hashmap. The hashmap actually contains the style to be applied.
224pub fn style_primitive(primitive: &str, color_hm: &HashMap<String, Style>) -> TextStyle {
225    match primitive {
226        "Int" => {
227            let style = color_hm.get("Primitive::Int");
228            match style {
229                Some(s) => TextStyle::with_style(Alignment::Right, *s),
230                None => TextStyle::basic_right(),
231            }
232        }
233        "Decimal" => {
234            let style = color_hm.get("Primitive::Decimal");
235            match style {
236                Some(s) => TextStyle::with_style(Alignment::Right, *s),
237                None => TextStyle::basic_right(),
238            }
239        }
240        "Filesize" => {
241            let style = color_hm.get("Primitive::Filesize");
242            match style {
243                Some(s) => TextStyle::with_style(Alignment::Right, *s),
244                None => TextStyle::basic_right(),
245            }
246        }
247        "String" => {
248            let style = color_hm.get("Primitive::String");
249            match style {
250                Some(s) => TextStyle::with_style(Alignment::Left, *s),
251                None => TextStyle::basic_left(),
252            }
253        }
254        "Line" => {
255            let style = color_hm.get("Primitive::Line");
256            match style {
257                Some(s) => TextStyle::with_style(Alignment::Left, *s),
258                None => TextStyle::basic_left(),
259            }
260        }
261        "ColumnPath" => {
262            let style = color_hm.get("Primitive::ColumnPath");
263            match style {
264                Some(s) => TextStyle::with_style(Alignment::Left, *s),
265                None => TextStyle::basic_left(),
266            }
267        }
268        "GlobPattern" => {
269            let style = color_hm.get("Primitive::GlobPattern");
270            match style {
271                Some(s) => TextStyle::with_style(Alignment::Left, *s),
272                None => TextStyle::basic_left(),
273            }
274        }
275        "Boolean" => {
276            let style = color_hm.get("Primitive::Boolean");
277            match style {
278                Some(s) => TextStyle::with_style(Alignment::Left, *s),
279                None => TextStyle::basic_left(),
280            }
281        }
282        "Date" => {
283            let style = color_hm.get("Primitive::Date");
284            match style {
285                Some(s) => TextStyle::with_style(Alignment::Left, *s),
286                None => TextStyle::basic_left(),
287            }
288        }
289        "Duration" => {
290            let style = color_hm.get("Primitive::Duration");
291            match style {
292                Some(s) => TextStyle::with_style(Alignment::Left, *s),
293                None => TextStyle::basic_left(),
294            }
295        }
296        "Range" => {
297            let style = color_hm.get("Primitive::Range");
298            match style {
299                Some(s) => TextStyle::with_style(Alignment::Left, *s),
300                None => TextStyle::basic_left(),
301            }
302        }
303        "FilePath" => {
304            let style = color_hm.get("Primitive::FilePath");
305            match style {
306                Some(s) => TextStyle::with_style(Alignment::Left, *s),
307                None => TextStyle::basic_left(),
308            }
309        }
310        "Binary" => {
311            let style = color_hm.get("Primitive::Binary");
312            match style {
313                Some(s) => TextStyle::with_style(Alignment::Left, *s),
314                None => TextStyle::basic_left(),
315            }
316        }
317        "BeginningOfStream" => {
318            let style = color_hm.get("Primitive::BeginningOfStream");
319            match style {
320                Some(s) => TextStyle::with_style(Alignment::Left, *s),
321                None => TextStyle::basic_left(),
322            }
323        }
324        "EndOfStream" => {
325            let style = color_hm.get("Primitive::EndOfStream");
326            match style {
327                Some(s) => TextStyle::with_style(Alignment::Left, *s),
328                None => TextStyle::basic_left(),
329            }
330        }
331        "Nothing" => {
332            let style = color_hm.get("Primitive::Nothing");
333            match style {
334                Some(s) => TextStyle::with_style(Alignment::Left, *s),
335                None => TextStyle::basic_left(),
336            }
337        }
338        "separator_color" => {
339            let style = color_hm.get("separator");
340            match style {
341                Some(s) => TextStyle::with_style(Alignment::Left, *s),
342                None => TextStyle::basic_left(),
343            }
344        }
345        "header_align" => {
346            let style = color_hm.get("header_align");
347            match style {
348                Some(s) => TextStyle::with_style(Alignment::Center, *s),
349                None => TextStyle::default_header(),
350            }
351        }
352        "header_color" => {
353            let style = color_hm.get("header_color");
354            match style {
355                Some(s) => TextStyle::with_style(Alignment::Center, *s),
356                None => TextStyle::default_header().bold(Some(true)),
357            }
358        }
359        "header_style" => {
360            let style = color_hm.get("header_style");
361            match style {
362                Some(s) => TextStyle::with_style(Alignment::Center, *s),
363                None => TextStyle::default_header(),
364            }
365        }
366        "index_color" => {
367            let style = color_hm.get("index_color");
368            match style {
369                Some(s) => TextStyle::with_style(Alignment::Right, *s),
370                None => TextStyle::new()
371                    .alignment(Alignment::Right)
372                    .fg(Color::Green)
373                    .bold(Some(true)),
374            }
375        }
376        _ => TextStyle::basic_center(),
377    }
378}