ansi2/
theme.rs

1#[cfg_attr(feature = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
2#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
3// https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
4#[derive(Debug, Clone, Copy)]
5pub enum Theme {
6    Vscode,
7    Ubuntu,
8    Vga,
9    Xterm,
10}
11
12impl<'a> From<&'a str> for Theme {
13    fn from(value: &'a str) -> Self {
14        match value {
15            "vscode" => Theme::Vscode,
16            "ubuntu" => Theme::Ubuntu,
17            "vga" => Theme::Vga,
18            "xterm" => Theme::Xterm,
19            _ => Theme::Vscode,
20        }
21    }
22}
23
24// https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
25pub const COLOR256: [(u8, u8, u8); 256] = [
26    (0, 0, 0),
27    (128, 0, 0),
28    (0, 128, 0),
29    (128, 128, 0),
30    (0, 0, 128),
31    (128, 0, 128),
32    (0, 128, 128),
33    (192, 192, 192),
34    (128, 128, 128),
35    (255, 0, 0),
36    (0, 255, 0),
37    (255, 255, 0),
38    (0, 0, 255),
39    (255, 0, 255),
40    (0, 255, 255),
41    (255, 255, 255),
42    (0, 0, 0),
43    (0, 0, 95),
44    (0, 0, 135),
45    (0, 0, 175),
46    (0, 0, 215),
47    (0, 0, 255),
48    (0, 95, 0),
49    (0, 95, 95),
50    (0, 95, 135),
51    (0, 95, 175),
52    (0, 95, 215),
53    (0, 95, 255),
54    (0, 135, 0),
55    (0, 135, 95),
56    (0, 135, 135),
57    (0, 135, 175),
58    (0, 135, 215),
59    (0, 135, 255),
60    (0, 175, 0),
61    (0, 175, 95),
62    (0, 175, 135),
63    (0, 175, 175),
64    (0, 175, 215),
65    (0, 175, 255),
66    (0, 215, 0),
67    (0, 215, 95),
68    (0, 215, 135),
69    (0, 215, 175),
70    (0, 215, 215),
71    (0, 215, 255),
72    (0, 255, 0),
73    (0, 255, 95),
74    (0, 255, 135),
75    (0, 255, 175),
76    (0, 255, 215),
77    (0, 255, 255),
78    (95, 0, 0),
79    (95, 0, 95),
80    (95, 0, 135),
81    (95, 0, 175),
82    (95, 0, 215),
83    (95, 0, 255),
84    (95, 95, 0),
85    (95, 95, 95),
86    (95, 95, 135),
87    (95, 95, 175),
88    (95, 95, 215),
89    (95, 95, 255),
90    (95, 135, 0),
91    (95, 135, 95),
92    (95, 135, 135),
93    (95, 135, 175),
94    (95, 135, 215),
95    (95, 135, 255),
96    (95, 175, 0),
97    (95, 175, 95),
98    (95, 175, 135),
99    (95, 175, 175),
100    (95, 175, 215),
101    (95, 175, 255),
102    (95, 215, 0),
103    (95, 215, 95),
104    (95, 215, 135),
105    (95, 215, 175),
106    (95, 215, 215),
107    (95, 215, 255),
108    (95, 255, 0),
109    (95, 255, 95),
110    (95, 255, 135),
111    (95, 255, 175),
112    (95, 255, 215),
113    (95, 255, 255),
114    (135, 0, 0),
115    (135, 0, 95),
116    (135, 0, 135),
117    (135, 0, 175),
118    (135, 0, 215),
119    (135, 0, 255),
120    (135, 95, 0),
121    (135, 95, 95),
122    (135, 95, 135),
123    (135, 95, 175),
124    (135, 95, 215),
125    (135, 95, 255),
126    (135, 135, 0),
127    (135, 135, 95),
128    (135, 135, 135),
129    (135, 135, 175),
130    (135, 135, 215),
131    (135, 135, 255),
132    (135, 175, 0),
133    (135, 175, 95),
134    (135, 175, 135),
135    (135, 175, 175),
136    (135, 175, 215),
137    (135, 175, 255),
138    (135, 215, 0),
139    (135, 215, 95),
140    (135, 215, 135),
141    (135, 215, 175),
142    (135, 215, 215),
143    (135, 215, 255),
144    (135, 255, 0),
145    (135, 255, 95),
146    (135, 255, 135),
147    (135, 255, 175),
148    (135, 255, 215),
149    (135, 255, 255),
150    (175, 0, 0),
151    (175, 0, 95),
152    (175, 0, 135),
153    (175, 0, 175),
154    (175, 0, 215),
155    (175, 0, 255),
156    (175, 95, 0),
157    (175, 95, 95),
158    (175, 95, 135),
159    (175, 95, 175),
160    (175, 95, 215),
161    (175, 95, 255),
162    (175, 135, 0),
163    (175, 135, 95),
164    (175, 135, 135),
165    (175, 135, 175),
166    (175, 135, 215),
167    (175, 135, 255),
168    (175, 175, 0),
169    (175, 175, 95),
170    (175, 175, 135),
171    (175, 175, 175),
172    (175, 175, 215),
173    (175, 175, 255),
174    (175, 215, 0),
175    (175, 215, 95),
176    (175, 215, 135),
177    (175, 215, 175),
178    (175, 215, 215),
179    (175, 215, 255),
180    (175, 255, 0),
181    (175, 255, 95),
182    (175, 255, 135),
183    (175, 255, 175),
184    (175, 255, 215),
185    (175, 255, 255),
186    (215, 0, 0),
187    (215, 0, 95),
188    (215, 0, 135),
189    (215, 0, 175),
190    (215, 0, 215),
191    (215, 0, 255),
192    (215, 95, 0),
193    (215, 95, 95),
194    (215, 95, 135),
195    (215, 95, 175),
196    (215, 95, 215),
197    (215, 95, 255),
198    (215, 135, 0),
199    (215, 135, 95),
200    (215, 135, 135),
201    (215, 135, 175),
202    (215, 135, 215),
203    (215, 135, 255),
204    (215, 175, 0),
205    (215, 175, 95),
206    (215, 175, 135),
207    (215, 175, 175),
208    (215, 175, 215),
209    (215, 175, 255),
210    (215, 215, 0),
211    (215, 215, 95),
212    (215, 215, 135),
213    (215, 215, 175),
214    (215, 215, 215),
215    (215, 215, 255),
216    (215, 255, 0),
217    (215, 255, 95),
218    (215, 255, 135),
219    (215, 255, 175),
220    (215, 255, 215),
221    (215, 255, 255),
222    (255, 0, 0),
223    (255, 0, 95),
224    (255, 0, 135),
225    (255, 0, 175),
226    (255, 0, 215),
227    (255, 0, 255),
228    (255, 95, 0),
229    (255, 95, 95),
230    (255, 95, 135),
231    (255, 95, 175),
232    (255, 95, 215),
233    (255, 95, 255),
234    (255, 135, 0),
235    (255, 135, 95),
236    (255, 135, 135),
237    (255, 135, 175),
238    (255, 135, 215),
239    (255, 135, 255),
240    (255, 175, 0),
241    (255, 175, 95),
242    (255, 175, 135),
243    (255, 175, 175),
244    (255, 175, 215),
245    (255, 175, 255),
246    (255, 215, 0),
247    (255, 215, 95),
248    (255, 215, 135),
249    (255, 215, 175),
250    (255, 215, 215),
251    (255, 215, 255),
252    (255, 255, 0),
253    (255, 255, 95),
254    (255, 255, 135),
255    (255, 255, 175),
256    (255, 255, 215),
257    (255, 255, 255),
258    (8, 8, 8),
259    (18, 18, 18),
260    (28, 28, 28),
261    (38, 38, 38),
262    (48, 48, 48),
263    (58, 58, 58),
264    (68, 68, 68),
265    (78, 78, 78),
266    (88, 88, 88),
267    (98, 98, 98),
268    (108, 108, 108),
269    (118, 118, 118),
270    (128, 128, 128),
271    (138, 138, 138),
272    (148, 148, 148),
273    (158, 158, 158),
274    (168, 168, 168),
275    (178, 178, 178),
276    (188, 188, 188),
277    (198, 198, 198),
278    (208, 208, 208),
279    (218, 218, 218),
280    (228, 228, 228),
281    (238, 238, 238),
282];
283
284const VSCODE_COLOR: [(u8, u8, u8); 16] = [
285    (0, 0, 0),
286    (205, 49, 49),
287    (13, 188, 121),
288    (229, 229, 16),
289    (36, 114, 200),
290    (188, 63, 188),
291    (17, 168, 205),
292    (229, 229, 229),
293    (102, 102, 102),
294    (241, 76, 76),
295    (35, 209, 139),
296    (245, 245, 67),
297    (59, 142, 234),
298    (214, 112, 214),
299    (41, 184, 219),
300    (229, 229, 229),
301];
302
303const UBUNTU_COLOR: [(u8, u8, u8); 16] = [
304    (1, 1, 1),
305    (222, 56, 43),
306    (57, 181, 74),
307    (255, 199, 6),
308    (0, 111, 184),
309    (118, 38, 113),
310    (44, 181, 233),
311    (204, 204, 204),
312    (128, 128, 128),
313    (255, 0, 0),
314    (0, 255, 0),
315    (255, 255, 0),
316    (0, 0, 255),
317    (255, 0, 255),
318    (0, 255, 255),
319    (255, 255, 255),
320];
321
322const VGA_COLOR: [(u8, u8, u8); 16] = [
323    (0, 0, 0),
324    (170, 0, 0),
325    (0, 170, 0),
326    (170, 85, 0),
327    (0, 0, 170),
328    (170, 0, 170),
329    (0, 170, 170),
330    (170, 170, 170),
331    (85, 85, 85),
332    (255, 85, 85),
333    (85, 255, 85),
334    (255, 255, 85),
335    (85, 85, 255),
336    (255, 85, 255),
337    (85, 255, 255),
338    (255, 255, 255),
339];
340
341const XTERM_COLOR: [(u8, u8, u8); 16] = [
342    (0, 0, 0),
343    (128, 0, 0),
344    (0, 128, 0),
345    (128, 128, 0),
346    (0, 0, 128),
347    (128, 0, 128),
348    (0, 128, 128),
349    (192, 192, 192),
350    (128, 128, 128),
351    (255, 0, 0),
352    (0, 255, 0),
353    (255, 255, 0),
354    (0, 0, 255),
355    (255, 0, 255),
356    (0, 255, 255),
357    (255, 255, 255),
358];
359
360const COLORS: [[(u8, u8, u8); 16]; 4] = [VSCODE_COLOR, UBUNTU_COLOR, VGA_COLOR, XTERM_COLOR];
361
362impl Theme {
363    fn discriminant(&self) -> usize {
364        unsafe { (*(self as *const _ as *const u8)) as usize }
365    }
366}
367
368pub trait ColorTable: Copy + Sized {
369    fn black(&self) -> (u8, u8, u8);
370    fn red(&self) -> (u8, u8, u8);
371    fn green(&self) -> (u8, u8, u8);
372    fn yellow(&self) -> (u8, u8, u8);
373    fn blue(&self) -> (u8, u8, u8);
374    fn magenta(&self) -> (u8, u8, u8);
375    fn cyan(&self) -> (u8, u8, u8);
376    fn white(&self) -> (u8, u8, u8);
377
378    fn bright_black(&self) -> (u8, u8, u8);
379    fn bright_red(&self) -> (u8, u8, u8);
380    fn bright_green(&self) -> (u8, u8, u8);
381    fn bright_yellow(&self) -> (u8, u8, u8);
382    fn bright_blue(&self) -> (u8, u8, u8);
383    fn bright_magenta(&self) -> (u8, u8, u8);
384    fn bright_cyan(&self) -> (u8, u8, u8);
385    fn bright_white(&self) -> (u8, u8, u8);
386}
387
388impl ColorTable for Theme {
389    fn black(&self) -> (u8, u8, u8) {
390        COLORS[self.discriminant()][0]
391    }
392
393    fn red(&self) -> (u8, u8, u8) {
394        COLORS[self.discriminant()][1]
395    }
396
397    fn green(&self) -> (u8, u8, u8) {
398        COLORS[self.discriminant()][2]
399    }
400
401    fn yellow(&self) -> (u8, u8, u8) {
402        COLORS[self.discriminant()][3]
403    }
404
405    fn blue(&self) -> (u8, u8, u8) {
406        COLORS[self.discriminant()][4]
407    }
408
409    fn magenta(&self) -> (u8, u8, u8) {
410        COLORS[self.discriminant()][5]
411    }
412
413    fn cyan(&self) -> (u8, u8, u8) {
414        COLORS[self.discriminant()][6]
415    }
416
417    fn white(&self) -> (u8, u8, u8) {
418        COLORS[self.discriminant()][7]
419    }
420
421    fn bright_black(&self) -> (u8, u8, u8) {
422        COLORS[self.discriminant()][8]
423    }
424
425    fn bright_red(&self) -> (u8, u8, u8) {
426        COLORS[self.discriminant()][9]
427    }
428
429    fn bright_green(&self) -> (u8, u8, u8) {
430        COLORS[self.discriminant()][10]
431    }
432
433    fn bright_yellow(&self) -> (u8, u8, u8) {
434        COLORS[self.discriminant()][11]
435    }
436
437    fn bright_blue(&self) -> (u8, u8, u8) {
438        COLORS[self.discriminant()][12]
439    }
440
441    fn bright_magenta(&self) -> (u8, u8, u8) {
442        COLORS[self.discriminant()][13]
443    }
444
445    fn bright_cyan(&self) -> (u8, u8, u8) {
446        COLORS[self.discriminant()][14]
447    }
448
449    fn bright_white(&self) -> (u8, u8, u8) {
450        COLORS[self.discriminant()][15]
451    }
452}