Skip to main content

recolored/
color.rs

1use std::convert::From;
2use std::str::FromStr;
3
4/// The 8 standard colors.
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6#[allow(missing_docs)]
7pub enum Color {
8    Black,
9    Red,
10    Green,
11    Yellow,
12    Blue,
13    Magenta,
14    Cyan,
15    White,
16    BrightBlack,
17    BrightRed,
18    BrightGreen,
19    BrightYellow,
20    BrightBlue,
21    BrightMagenta,
22    BrightCyan,
23    BrightWhite,
24    Palette(u8),
25    True(u8, u8, u8),
26}
27
28#[allow(missing_docs)]
29impl Color {
30    pub fn to_fg_str(&self) -> String {
31        match *self {
32            Color::Black => "30".to_owned(),
33            Color::Red => "31".to_owned(),
34            Color::Green => "32".to_owned(),
35            Color::Yellow => "33".to_owned(),
36            Color::Blue => "34".to_owned(),
37            Color::Magenta => "35".to_owned(),
38            Color::Cyan => "36".to_owned(),
39            Color::White => "37".to_owned(),
40            Color::BrightBlack => "90".to_owned(),
41            Color::BrightRed => "91".to_owned(),
42            Color::BrightGreen => "92".to_owned(),
43            Color::BrightYellow => "93".to_owned(),
44            Color::BrightBlue => "94".to_owned(),
45            Color::BrightMagenta => "95".to_owned(),
46            Color::BrightCyan => "96".to_owned(),
47            Color::BrightWhite => "97".to_owned(),
48            Color::Palette(code) => format!("38;5;{}", code),
49            Color::True(r, g, b) => format!("38;2;{};{};{}", r, g, b),
50        }
51    }
52
53    pub fn to_bg_str(&self) -> String {
54        match *self {
55            Color::Black => "40".to_owned(),
56            Color::Red => "41".to_owned(),
57            Color::Green => "42".to_owned(),
58            Color::Yellow => "43".to_owned(),
59            Color::Blue => "44".to_owned(),
60            Color::Magenta => "45".to_owned(),
61            Color::Cyan => "46".to_owned(),
62            Color::White => "47".to_owned(),
63            Color::BrightBlack => "100".to_owned(),
64            Color::BrightRed => "101".to_owned(),
65            Color::BrightGreen => "102".to_owned(),
66            Color::BrightYellow => "103".to_owned(),
67            Color::BrightBlue => "104".to_owned(),
68            Color::BrightMagenta => "105".to_owned(),
69            Color::BrightCyan => "106".to_owned(),
70            Color::BrightWhite => "107".to_owned(),
71            Color::Palette(code) => format!("48;5;{}", code),
72            Color::True(r, g, b) => format!("48;2;{};{};{}", r, g, b),
73        }
74    }
75}
76
77impl<'a> From<&'a str> for Color {
78    fn from(src: &str) -> Self {
79        src.parse().unwrap_or(Color::White)
80    }
81}
82
83impl From<String> for Color {
84    fn from(src: String) -> Self {
85        src.parse().unwrap_or(Color::White)
86    }
87}
88
89impl FromStr for Color {
90    type Err = ();
91
92    fn from_str(src: &str) -> Result<Self, Self::Err> {
93        let src = src.to_lowercase();
94
95        match src.as_ref() {
96            "black" => Ok(Color::Black),
97            "red" => Ok(Color::Red),
98            "green" => Ok(Color::Green),
99            "yellow" => Ok(Color::Yellow),
100            "blue" => Ok(Color::Blue),
101            "magenta" => Ok(Color::Magenta),
102            "purple" => Ok(Color::Magenta),
103            "cyan" => Ok(Color::Cyan),
104            "white" => Ok(Color::White),
105            "bright black" => Ok(Color::BrightBlack),
106            "bright red" => Ok(Color::BrightRed),
107            "bright green" => Ok(Color::BrightGreen),
108            "bright yellow" => Ok(Color::BrightYellow),
109            "bright blue" => Ok(Color::BrightBlue),
110            "bright magenta" => Ok(Color::BrightMagenta),
111            "bright cyan" => Ok(Color::BrightCyan),
112            "bright white" => Ok(Color::BrightWhite),
113            _ => Err(()),
114        }
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    pub use super::*;
121
122    mod from_str {
123        pub use super::*;
124
125        macro_rules! make_test {
126            ( $( $name:ident: $src:expr => $dst:expr),* ) => {
127
128                $(
129                    #[test]
130                    fn $name() {
131                        let color : Color = $src.into();
132                        assert_eq!($dst, color)
133                    }
134                )*
135            }
136        }
137
138        make_test!(
139            black: "black" => Color::Black,
140            red: "red" => Color::Red,
141            green: "green" => Color::Green,
142            yellow: "yellow" => Color::Yellow,
143            blue: "blue" => Color::Blue,
144            magenta: "magenta" => Color::Magenta,
145            purple: "purple" => Color::Magenta,
146            cyan: "cyan" => Color::Cyan,
147            white: "white" => Color::White,
148            brightblack: "bright black" => Color::BrightBlack,
149            brightred: "bright red" => Color::BrightRed,
150            brightgreen: "bright green" => Color::BrightGreen,
151            brightyellow: "bright yellow" => Color::BrightYellow,
152            brightblue: "bright blue" => Color::BrightBlue,
153            brightmagenta: "bright magenta" => Color::BrightMagenta,
154            brightcyan: "bright cyan" => Color::BrightCyan,
155            brightwhite: "bright white" => Color::BrightWhite,
156
157            invalid: "invalid" => Color::White,
158            capitalized: "BLUE" => Color::Blue,
159            mixed_case: "bLuE" => Color::Blue
160        );
161    }
162
163    mod from_string {
164        pub use super::*;
165
166        macro_rules! make_test {
167            ( $( $name:ident: $src:expr => $dst:expr),* ) => {
168
169                $(
170                    #[test]
171                    fn $name() {
172                        let src = String::from($src);
173                        let color : Color = src.into();
174                        assert_eq!($dst, color)
175                    }
176                )*
177            }
178        }
179
180        make_test!(
181            black: "black" => Color::Black,
182            red: "red" => Color::Red,
183            green: "green" => Color::Green,
184            yellow: "yellow" => Color::Yellow,
185            blue: "blue" => Color::Blue,
186            magenta: "magenta" => Color::Magenta,
187            cyan: "cyan" => Color::Cyan,
188            white: "white" => Color::White,
189            brightblack: "bright black" => Color::BrightBlack,
190            brightred: "bright red" => Color::BrightRed,
191            brightgreen: "bright green" => Color::BrightGreen,
192            brightyellow: "bright yellow" => Color::BrightYellow,
193            brightblue: "bright blue" => Color::BrightBlue,
194            brightmagenta: "bright magenta" => Color::BrightMagenta,
195            brightcyan: "bright cyan" => Color::BrightCyan,
196            brightwhite: "bright white" => Color::BrightWhite,
197
198            invalid: "invalid" => Color::White,
199            capitalized: "BLUE" => Color::Blue,
200            mixed_case: "bLuE" => Color::Blue
201        );
202    }
203
204    mod fromstr {
205        pub use super::*;
206
207        #[test]
208        fn parse() {
209            let color: Result<Color, _> = "blue".parse();
210            assert_eq!(Ok(Color::Blue), color)
211        }
212
213        #[test]
214        fn error() {
215            let color: Result<Color, ()> = "bloublou".parse();
216            assert_eq!(Err(()), color)
217        }
218    }
219}