1 use std::fmt;
2 
3 /// A color.
4 ///
5 /// This is **NOT** a full ANSI sequence. `Color` must be used along with
6 /// the:
7 ///
8 /// * [`SetBackgroundColor`](struct.SetBackgroundColor.html)
9 /// * [`SetForegroundColor`](struct.SetForegroundColor.html)
10 ///
11 /// # Examples
12 ///
13 /// ```no_run
14 /// use std::io::{stdout, Write};
15 /// use anes::{Color, SetForegroundColor};
16 ///
17 /// let mut stdout = stdout();
18 /// // Set the foreground color to red
19 /// write!(stdout, "{}", SetForegroundColor(Color::Red));
20 /// ```
21 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
22 pub enum Color {
23     /// Default color.
24     Default,
25     /// Black color.
26     Black,
27     /// Dark red color.
28     DarkRed,
29     /// Dark green color.
30     DarkGreen,
31     /// Dark yellow color.
32     DarkYellow,
33     /// Dark blue color.
34     DarkBlue,
35     /// Dark magenta color.
36     DarkMagenta,
37     /// Dark cyan color.
38     DarkCyan,
39     /// Dark gray color.
40     ///
41     /// Also knows as light (bright) black.
42     DarkGray,
43     /// Light (bright) gray color.
44     ///
45     /// Also known as dark white.
46     Gray,
47     /// Light (bright) red color.
48     Red,
49     /// Light (bright) green color.
50     Green,
51     /// Light (bright) yellow color.
52     Yellow,
53     /// Light (bright) blue color.
54     Blue,
55     /// Light (bright) magenta color.
56     Magenta,
57     /// Light (bright) cyan color.
58     Cyan,
59     /// White color.
60     White,
61     /// A color from the predefined set of ANSI colors.
62     ///
63     /// ```text
64     ///    0 - 7:  standard colors (as in ESC [ 30–37 m)
65     ///    8- 15:  high intensity colors (as in ESC [ 90–97 m)
66     ///   16-231:  6 × 6 × 6 cube (216 colors): 16 + 36 × r + 6 × g + b (0 ≤ r, g, b ≤ 5)
67     ///  232-255:  grayscale from black to white in 24 steps
68     /// ```
69     ///
70     /// See [8-bit](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) for more information.
71     Ansi(u8),
72     /// An RGB color.
73     ///
74     /// See [24-bit](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit) for more information.
75     Rgb(u8, u8, u8),
76 }
77 
78 impl fmt::Display for Color {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result79     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80         match self {
81             // Color::Default is handled in the SetBackgroundColor & SetForegroundColor
82             Color::Default => Ok(()),
83             Color::Black => write!(f, "5;0"),
84             Color::DarkRed => write!(f, "5;1"),
85             Color::DarkGreen => write!(f, "5;2"),
86             Color::DarkYellow => write!(f, "5;3"),
87             Color::DarkBlue => write!(f, "5;4"),
88             Color::DarkMagenta => write!(f, "5;5"),
89             Color::DarkCyan => write!(f, "5;6"),
90             Color::Gray => write!(f, "5;7"),
91             Color::DarkGray => write!(f, "5;8"),
92             Color::Red => write!(f, "5;9"),
93             Color::Green => write!(f, "5;10"),
94             Color::Yellow => write!(f, "5;11"),
95             Color::Blue => write!(f, "5;12"),
96             Color::Magenta => write!(f, "5;13"),
97             Color::Cyan => write!(f, "5;14"),
98             Color::White => write!(f, "5;15"),
99             Color::Ansi(value) => write!(f, "5;{}", value),
100             Color::Rgb(r, g, b) => write!(f, "2;{};{};{}", r, g, b),
101         }
102     }
103 }
104 
105 sequence! {
106     /// Sets the foreground color.
107     ///
108     /// # Examples
109     ///
110     /// ```no_run
111     /// use std::io::{stdout, Write};
112     /// use anes::{Color, SetForegroundColor};
113     ///
114     /// let mut stdout = stdout();
115     /// // Set the foreground color to blue
116     /// write!(stdout, "{}", SetForegroundColor(Color::Blue));
117     /// ```
118     struct SetForegroundColor(Color) =>
119     |this, f| match this.0 {
120         Color::Default => write!(f, sgr!("39")),
121         _ => write!(f, sgr!("38;{}"), this.0),
122     }
123 }
124 
125 sequence! {
126     /// Sets the background color.
127     ///
128     /// # Examples
129     ///
130     /// ```no_run
131     /// use std::io::{stdout, Write};
132     /// use anes::{Color, SetBackgroundColor};
133     ///
134     /// let mut stdout = stdout();
135     /// // Set the background color to yellow
136     /// write!(stdout, "{}", SetBackgroundColor(Color::Yellow));
137     /// ```
138     struct SetBackgroundColor(Color) =>
139     |this, f| match this.0 {
140         Color::Default => write!(f, sgr!("49")),
141         _ => write!(f, sgr!("48;{}"), this.0),
142     }
143 }
144 
145 #[cfg(test)]
146 test_sequences!(
147     set_foreground_color(
148         SetForegroundColor(Color::Default) => "\x1B[39m",
149         SetForegroundColor(Color::Black) => "\x1B[38;5;0m",
150         SetForegroundColor(Color::DarkRed) => "\x1B[38;5;1m",
151         SetForegroundColor(Color::DarkGreen) => "\x1B[38;5;2m",
152         SetForegroundColor(Color::DarkYellow) => "\x1B[38;5;3m",
153         SetForegroundColor(Color::DarkBlue) => "\x1B[38;5;4m",
154         SetForegroundColor(Color::DarkMagenta) => "\x1B[38;5;5m",
155         SetForegroundColor(Color::DarkCyan) => "\x1B[38;5;6m",
156         SetForegroundColor(Color::DarkGray) => "\x1B[38;5;8m",
157         SetForegroundColor(Color::Gray) => "\x1B[38;5;7m",
158         SetForegroundColor(Color::Red) => "\x1B[38;5;9m",
159         SetForegroundColor(Color::Green) => "\x1B[38;5;10m",
160         SetForegroundColor(Color::Yellow) => "\x1B[38;5;11m",
161         SetForegroundColor(Color::Blue) => "\x1B[38;5;12m",
162         SetForegroundColor(Color::Magenta) => "\x1B[38;5;13m",
163         SetForegroundColor(Color::Cyan) => "\x1B[38;5;14m",
164         SetForegroundColor(Color::White) => "\x1B[38;5;15m",
165         SetForegroundColor(Color::Ansi(200)) => "\x1B[38;5;200m",
166         SetForegroundColor(Color::Rgb(1, 2, 3)) => "\x1B[38;2;1;2;3m",
167     ),
168     set_background_color(
169         SetBackgroundColor(Color::Default) => "\x1B[49m",
170         SetBackgroundColor(Color::Black) => "\x1B[48;5;0m",
171         SetBackgroundColor(Color::DarkRed) => "\x1B[48;5;1m",
172         SetBackgroundColor(Color::DarkGreen) => "\x1B[48;5;2m",
173         SetBackgroundColor(Color::DarkYellow) => "\x1B[48;5;3m",
174         SetBackgroundColor(Color::DarkBlue) => "\x1B[48;5;4m",
175         SetBackgroundColor(Color::DarkMagenta) => "\x1B[48;5;5m",
176         SetBackgroundColor(Color::DarkCyan) => "\x1B[48;5;6m",
177         SetBackgroundColor(Color::DarkGray) => "\x1B[48;5;8m",
178         SetBackgroundColor(Color::Gray) => "\x1B[48;5;7m",
179         SetBackgroundColor(Color::Red) => "\x1B[48;5;9m",
180         SetBackgroundColor(Color::Green) => "\x1B[48;5;10m",
181         SetBackgroundColor(Color::Yellow) => "\x1B[48;5;11m",
182         SetBackgroundColor(Color::Blue) => "\x1B[48;5;12m",
183         SetBackgroundColor(Color::Magenta) => "\x1B[48;5;13m",
184         SetBackgroundColor(Color::Cyan) => "\x1B[48;5;14m",
185         SetBackgroundColor(Color::White) => "\x1B[48;5;15m",
186         SetBackgroundColor(Color::Ansi(200)) => "\x1B[48;5;200m",
187         SetBackgroundColor(Color::Rgb(1, 2, 3)) => "\x1B[48;2;1;2;3m",
188     )
189 );
190