Skip to main content

tiny_table/
color.rs

1/// A color used for foreground and background text styling.
2///
3/// Named variants map to the standard 16 ANSI terminal colors. [`AnsiColor`]
4/// selects one of the 256 extended palette entries. [`TrueColor`] accepts
5/// arbitrary 24-bit RGB values when the terminal supports it.
6///
7/// [`AnsiColor`]: Color::AnsiColor
8/// [`TrueColor`]: Color::TrueColor
9#[derive(Clone, Copy, Debug, Eq, PartialEq)]
10pub enum Color {
11    /// Standard black (ANSI 30 / 40).
12    Black,
13    /// Standard red (ANSI 31 / 41).
14    Red,
15    /// Standard green (ANSI 32 / 42).
16    Green,
17    /// Standard yellow (ANSI 33 / 43).
18    Yellow,
19    /// Standard blue (ANSI 34 / 44).
20    Blue,
21    /// Standard magenta (ANSI 35 / 45).
22    Magenta,
23    /// Standard cyan (ANSI 36 / 46).
24    Cyan,
25    /// Standard white (ANSI 37 / 47).
26    White,
27    /// Bright black / dark gray (ANSI 90 / 100).
28    BrightBlack,
29    /// Bright red (ANSI 91 / 101).
30    BrightRed,
31    /// Bright green (ANSI 92 / 102).
32    BrightGreen,
33    /// Bright yellow (ANSI 93 / 103).
34    BrightYellow,
35    /// Bright blue (ANSI 94 / 104).
36    BrightBlue,
37    /// Bright magenta (ANSI 95 / 105).
38    BrightMagenta,
39    /// Bright cyan (ANSI 96 / 106).
40    BrightCyan,
41    /// Bright white (ANSI 97 / 107).
42    BrightWhite,
43    /// One of the 256-color extended palette entries (`\x1b[38;5;n`).
44    AnsiColor(u8),
45    /// A 24-bit truecolor value (`\x1b[38;2;r;g;b`).
46    TrueColor {
47        /// Red component (0–255).
48        r: u8,
49        /// Green component (0–255).
50        g: u8,
51        /// Blue component (0–255).
52        b: u8,
53    },
54}
55
56impl Color {
57    /// Return the ANSI escape sequence for this color used as a foreground.
58    pub(crate) fn ansi_fg(self) -> String {
59        match self {
60            Self::Black => "\x1b[30m".to_string(),
61            Self::Red => "\x1b[31m".to_string(),
62            Self::Green => "\x1b[32m".to_string(),
63            Self::Yellow => "\x1b[33m".to_string(),
64            Self::Blue => "\x1b[34m".to_string(),
65            Self::Magenta => "\x1b[35m".to_string(),
66            Self::Cyan => "\x1b[36m".to_string(),
67            Self::White => "\x1b[37m".to_string(),
68            Self::BrightBlack => "\x1b[90m".to_string(),
69            Self::BrightRed => "\x1b[91m".to_string(),
70            Self::BrightGreen => "\x1b[92m".to_string(),
71            Self::BrightYellow => "\x1b[93m".to_string(),
72            Self::BrightBlue => "\x1b[94m".to_string(),
73            Self::BrightMagenta => "\x1b[95m".to_string(),
74            Self::BrightCyan => "\x1b[96m".to_string(),
75            Self::BrightWhite => "\x1b[97m".to_string(),
76            Self::AnsiColor(n) => format!("\x1b[38;5;{n}m"),
77            Self::TrueColor { r, g, b } => format!("\x1b[38;2;{r};{g};{b}m"),
78        }
79    }
80
81    /// Return the ANSI escape sequence for this color used as a background.
82    pub(crate) fn ansi_bg(self) -> String {
83        match self {
84            Self::Black => "\x1b[40m".to_string(),
85            Self::Red => "\x1b[41m".to_string(),
86            Self::Green => "\x1b[42m".to_string(),
87            Self::Yellow => "\x1b[43m".to_string(),
88            Self::Blue => "\x1b[44m".to_string(),
89            Self::Magenta => "\x1b[45m".to_string(),
90            Self::Cyan => "\x1b[46m".to_string(),
91            Self::White => "\x1b[47m".to_string(),
92            Self::BrightBlack => "\x1b[100m".to_string(),
93            Self::BrightRed => "\x1b[101m".to_string(),
94            Self::BrightGreen => "\x1b[102m".to_string(),
95            Self::BrightYellow => "\x1b[103m".to_string(),
96            Self::BrightBlue => "\x1b[104m".to_string(),
97            Self::BrightMagenta => "\x1b[105m".to_string(),
98            Self::BrightCyan => "\x1b[106m".to_string(),
99            Self::BrightWhite => "\x1b[107m".to_string(),
100            Self::AnsiColor(n) => format!("\x1b[48;5;{n}m"),
101            Self::TrueColor { r, g, b } => format!("\x1b[48;2;{r};{g};{b}m"),
102        }
103    }
104}
105
106/// A truecolor value specified by red, green, and blue byte components.
107///
108/// Primarily used with the [`custom_color`](crate::Cell::custom_color) and
109/// [`on_custom_color`](crate::Cell::on_custom_color) methods.
110pub struct CustomColor {
111    /// Red component (0–255).
112    pub r: u8,
113    /// Green component (0–255).
114    pub g: u8,
115    /// Blue component (0–255).
116    pub b: u8,
117}
118
119impl CustomColor {
120    /// Create a new [`CustomColor`] from red, green, and blue byte components.
121    pub fn new(r: u8, g: u8, b: u8) -> Self {
122        Self { r, g, b }
123    }
124}
125
126impl From<(u8, u8, u8)> for CustomColor {
127    fn from((r, g, b): (u8, u8, u8)) -> Self {
128        Self { r, g, b }
129    }
130}