1use crossterm::style::{Color, SetForegroundColor, SetBackgroundColor, ResetColor};
2use std::collections::HashMap;
3use std::io::{stdout, Write};
4use std::sync::OnceLock;
5use crate::output::colors::*;
6
7#[derive(Clone)]
8pub struct Theme {
9 pub name: String,
10 pub fg: Color,
11 pub bg: Color,
12 pub log_styles: HashMap<&'static str, Color>,
13}
14
15impl Theme {
16 pub fn apply(&self) {
17 let _ = write!(stdout(), "{}{}", SetForegroundColor(self.fg), SetBackgroundColor(self.bg));
18 let _ = stdout().flush();
19 }
20
21 pub fn reset() {
22 let _ = write!(stdout(), "{}", ResetColor);
23 let _ = stdout().flush();
24 }
25
26 pub fn get_log_color(&self, key: &str) -> Color {
27 self.log_styles.get(key).copied().unwrap_or(self.fg)
28 }
29}
30
31
32static THEME: OnceLock<Theme> = OnceLock::new();
33
34fn log_defaults(base: Color) -> HashMap<&'static str, Color> {
35 let mut map = HashMap::new();
36 map.insert("error", COLOR_ERROR);
37 map.insert("warn", COLOR_WARNING);
38 map.insert("success", COLOR_SUCCESS);
39 map.insert("debug", COLOR_DEBUG);
40 map.insert("info", COLOR_INFO);
41 map.insert("trace", COLOR_TRACE);
42 map.insert("default", base);
43 map
44}
45
46pub fn apply_theme(name: &str) {
47 let theme = match name.to_lowercase().as_str() {
48 "monochrome" => Theme {
49 name: "monochrome".into(),
50 fg: GREY,
51 bg: BLACK,
52 log_styles: log_defaults(GREY),
53 },
54 "inverted" => Theme {
55 name: "inverted".into(),
56 fg: BLACK,
57 bg: WHITE,
58 log_styles: log_defaults(BLACK),
59 },
60 "blue" => Theme {
61 name: "blue".into(),
62 fg: WHITE,
63 bg: BLUE,
64 log_styles: log_defaults(WHITE),
65 },
66 "green" => Theme {
67 name: "green".into(),
68 fg: BLACK,
69 bg: GREEN,
70 log_styles: log_defaults(BLACK),
71 },
72 _ => Theme {
73 name: "default".into(),
74 fg: WHITE,
75 bg: BLACK,
76 log_styles: log_defaults(WHITE),
77 },
78 };
79
80 let _ = THEME.set(theme.clone()); theme.apply();
82}
83
84pub fn current_theme() -> Theme {
85 THEME
86 .get()
87 .cloned()
88 .unwrap_or_else(|| Theme {
89 name: "default".into(),
90 fg: WHITE,
91 bg: BLACK,
92 log_styles: log_defaults(WHITE),
93 })
94}