1#[macro_export]
2macro_rules! color {
3 ($hex:literal) => {{
4 const COLOR: $crate::term::Color = {
5 let bytes = $hex.as_bytes();
6 assert!(bytes.len() == 7, "expected #RRGGBB format");
7 assert!(bytes[0] == b'#', "expected #RRGGBB format");
8
9 const fn hex_digit(b: u8) -> u8 {
10 match b {
11 b'0'..=b'9' => b - b'0',
12 b'a'..=b'f' => b - b'a' + 10,
13 b'A'..=b'F' => b - b'A' + 10,
14 _ => panic!("invalid hex digit"),
15 }
16 }
17
18 let r = hex_digit(bytes[1]) * 16 + hex_digit(bytes[2]);
19 let g = hex_digit(bytes[3]) * 16 + hex_digit(bytes[4]);
20 let b = hex_digit(bytes[5]) * 16 + hex_digit(bytes[6]);
21 $crate::term::Color::Rgb(r, g, b)
22 };
23 COLOR
24 }};
25}
26
27#[derive(Eq, PartialEq, Debug, Copy, Clone)]
29pub enum Color {
30 Default,
32
33 Idx(u8),
35
36 Rgb(u8, u8, u8),
38}
39
40#[allow(dead_code)]
41impl Color {
42 pub const BLACK: Self = Color::Idx(0);
43 pub const RED: Self = Color::Idx(1);
44 pub const GREEN: Self = Color::Idx(2);
45 pub const YELLOW: Self = Color::Idx(3);
46 pub const BLUE: Self = Color::Idx(4);
47 pub const MAGENTA: Self = Color::Idx(5);
48 pub const CYAN: Self = Color::Idx(6);
49 pub const WHITE: Self = Color::Idx(7);
50
51 pub const BRIGHT_BLACK: Self = Color::Idx(8);
52 pub const BRIGHT_RED: Self = Color::Idx(9);
53 pub const BRIGHT_GREEN: Self = Color::Idx(10);
54 pub const BRIGHT_YELLOW: Self = Color::Idx(11);
55 pub const BRIGHT_BLUE: Self = Color::Idx(12);
56 pub const BRIGHT_MAGENTA: Self = Color::Idx(13);
57 pub const BRIGHT_CYAN: Self = Color::Idx(14);
58 pub const BRIGHT_WHITE: Self = Color::Idx(15);
59}
60
61impl Color {
62 pub fn dim(self, factor: u8) -> Self {
63 match self {
64 Color::Default => self,
65 Color::Idx(_) => self,
66 Color::Rgb(r, g, b) => {
67 let f = factor as u16;
68 Color::Rgb(
69 (r as u16 * f / 255) as u8,
70 (g as u16 * f / 255) as u8,
71 (b as u16 * f / 255) as u8,
72 )
73 }
74 }
75 }
76}
77
78impl Default for Color {
79 fn default() -> Self {
80 Self::Default
81 }
82}