1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
use colored::{ColoredString, Colorize};
use std::fmt::Display;

#[derive(Debug, Clone, Copy, strum_macros::Display, strum_macros::EnumString)]
pub enum Theme {
    None,
    Dark,
}

impl ThemeColors for Theme {
    fn color_numeric_value<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_numeric_value(text),
            Theme::Dark => DarkTheme.color_numeric_value(text),
        }
    }

    fn color_invalid<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_invalid(text),
            Theme::Dark => DarkTheme.color_invalid(text),
        }
    }

    fn color_string_value<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_string_value(text),
            Theme::Dark => DarkTheme.color_string_value(text),
        }
    }

    fn color_type_name<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_type_name(text),
            Theme::Dark => DarkTheme.color_type_name(text),
        }
    }

    fn color_variable_name<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_variable_name(text),
            Theme::Dark => DarkTheme.color_variable_name(text),
        }
    }

    fn color_enum_member<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_enum_member(text),
            Theme::Dark => DarkTheme.color_enum_member(text),
        }
    }

    fn color_url<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_url(text),
            Theme::Dark => DarkTheme.color_url(text),
        }
    }

    fn color_function<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_function(text),
            Theme::Dark => DarkTheme.color_function(text),
        }
    }

    fn color_info<S: Display>(&self, text: S) -> ColoredString {
        match self {
            Theme::None => NoTheme.color_info(text),
            Theme::Dark => DarkTheme.color_info(text),
        }
    }
}

pub struct DarkTheme;

impl ThemeColors for DarkTheme {
    fn color_numeric_value<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0xb5, 0xce, 0xa8)
    }
    fn color_invalid<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0xf4, 0x47, 0x47)
    }
    fn color_string_value<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0xce, 0x91, 0x78)
    }
    fn color_type_name<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0x4e, 0xc9, 0xb0)
    }
    fn color_variable_name<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0x9c, 0xdc, 0xfe)
    }
    fn color_enum_member<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0x9c, 0xdc, 0xfe)
    }
    fn color_url<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().bright_black().underline()
    }
    fn color_function<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().truecolor(0xdc, 0xdc, 0xaa)
    }
    fn color_info<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().bright_black()
    }
}

pub struct NoTheme;

impl ThemeColors for NoTheme {
    fn color_numeric_value<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_invalid<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_string_value<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_type_name<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_variable_name<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_enum_member<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_url<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_function<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }

    fn color_info<S: Display>(&self, text: S) -> ColoredString {
        text.to_string().as_str().into()
    }
}

pub trait ThemeColors {
    fn color_numeric_value<S: Display>(&self, text: S) -> ColoredString;
    fn color_invalid<S: Display>(&self, text: S) -> ColoredString;
    fn color_string_value<S: Display>(&self, text: S) -> ColoredString;
    fn color_type_name<S: Display>(&self, text: S) -> ColoredString;
    fn color_variable_name<S: Display>(&self, text: S) -> ColoredString;
    fn color_enum_member<S: Display>(&self, text: S) -> ColoredString;
    fn color_url<S: Display>(&self, text: S) -> ColoredString;
    fn color_function<S: Display>(&self, text: S) -> ColoredString;
    fn color_info<S: Display>(&self, text: S) -> ColoredString;
}