1pub mod input;
2
3#[cfg(feature = "fancy")]
4pub mod fancy;
5
6#[cfg(feature = "output")]
7use std::fmt::Display;
8#[cfg(feature = "output")]
9use std::fmt;
10
11#[cfg(feature = "output")]
20#[derive(PartialEq, Clone, Copy)]
21pub enum Color {
22 Black,
23 Red,
24 Green,
25 Yellow,
26 Blue,
27 Purple,
28 Cyan,
29 White,
30 BrightBlack,
31 BrightRed,
32 BrightGreen,
33 BrightYellow,
34 BrightBlue,
35 BrightPurple,
36 BrightCyan,
37 BrightWhite,
38 Fixed(u8),
39 RGB(u8,u8,u8),
40 Hex(u32),
41 Default,
42}
43
44impl Color {
45 pub fn to_style_fg(self) -> Style {
47 Style::new().fg(self)
48 }
49 pub fn to_style_bg(self) -> Style {
51 Style::new().bg(self)
52 }
53
54 pub fn hex_to_rgb(hex: u32) -> Color {
56 Color::RGB(((hex >> (16u8)) & 0xFF) as u8, ((hex >> (8u8)) & 0xFF) as u8, ((hex) & 0xFF) as u8)
57 }
58
59 pub fn as_fg(&self) -> String {
61 match *self {
62 Color::Black => String::from("30"),
63 Color::Red => String::from("31"),
64 Color::Green => String::from("32"),
65 Color::Yellow => String::from("33"),
66 Color::Blue => String::from("34"),
67 Color::Purple => String::from("35"),
68 Color::Cyan => String::from("36"),
69 Color::White => String::from("37"),
70 Color::BrightBlack => String::from("90"),
71 Color::BrightRed => String::from("91"),
72 Color::BrightGreen => String::from("92"),
73 Color::BrightYellow => String::from("93"),
74 Color::BrightBlue => String::from("94"),
75 Color::BrightPurple => String::from("95"),
76 Color::BrightCyan => String::from("96"),
77 Color::BrightWhite => String::from("97"),
78 Color::Fixed(u) => format!("38;5;{}", &u),
79 Color::RGB(r,g,b) => format!("38;2;{};{};{}", &r,&g,&b),
80 Color::Hex(hex) => Color::hex_to_rgb(hex).as_fg(),
81 Color::Default => String::from("37"),
82 }
83 }
84 pub fn as_bg(&self) -> String {
86 match *self {
87 Color::Black => String::from("40"),
88 Color::Red => String::from("41"),
89 Color::Green => String::from("42"),
90 Color::Yellow => String::from("43"),
91 Color::Blue => String::from("44"),
92 Color::Purple => String::from("45"),
93 Color::Cyan => String::from("46"),
94 Color::White => String::from("47"),
95 Color::BrightBlack => String::from("100"),
96 Color::BrightRed => String::from("101"),
97 Color::BrightGreen => String::from("102"),
98 Color::BrightYellow => String::from("103"),
99 Color::BrightBlue => String::from("104"),
100 Color::BrightPurple => String::from("105"),
101 Color::BrightCyan => String::from("106"),
102 Color::BrightWhite => String::from("107"),
103 Color::Fixed(u) => format!("48;5;{}", &u).to_string(),
104 Color::RGB(r,g,b) => format!("48;2;{};{};{}", &r,&g,&b).to_string(),
105 Color::Hex(hex) => Color::hex_to_rgb(hex).as_bg(),
106 Color::Default => String::from("40"),
107 }
108 }
109}
110
111impl Display for Color {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 self.to_style_fg().fmt(f)
114 }
115}
116
117#[cfg(feature = "output")]
129#[derive(PartialEq, Clone, Copy)]
130pub struct Style {
131 fg: Option<Color>,
132 bg: Option<Color>,
133 overwrite: bool,
134 bold: bool,
135 dim: bool,
136 italic: bool,
137 underline: bool,
138 blink: bool,
139 invert: bool,
140 hide: bool,
141 strikethrough: bool,
142}
143
144impl Style {
145 pub fn new() -> Style {
147 Style::default()
148 }
149
150 pub fn reset() -> Style {
152 Style::default().overwrite()
153 }
154
155 pub fn fg(self, c: Color) -> Style {
157 Style { fg: Some(c), .. self }
158 }
159
160 pub fn clear_fg(self) -> Style {
162 Style { fg: None, .. self }
163 }
164
165 pub fn bg(self, c: Color) -> Style {
167 Style { bg: Some(c), .. self }
168 }
169
170 pub fn clear_bg(self) -> Style {
172 Style { bg: None, .. self }
173 }
174
175 pub fn overwrite(self) -> Style {
177 Style { overwrite: true, .. self }
178 }
179
180 pub fn bold(self) -> Style {
182 Style { bold: true, .. self }
183 }
184
185 pub fn dim(self) -> Style {
187 Style { dim: true, .. self }
188 }
189
190 pub fn italic(self) -> Style {
192 Style { italic: true, .. self }
193 }
194
195 pub fn underline(self) -> Style {
197 Style { underline: true, .. self }
198 }
199
200 pub fn blink(self) -> Style {
203 Style { blink: true, .. self }
204 }
205
206 pub fn invert(self) -> Style {
208 Style { invert: true, .. self }
209 }
210
211 pub fn hide(self) -> Style {
213 Style { hide: true, .. self }
214 }
215
216 pub fn strikethrough(self) -> Style {
218 Style { strikethrough: true, .. self }
219 }
220
221 #[doc(hidden)]
222 fn gen(&self) -> String {
223 let mut s = String::from("\x1b[");
224 let mut has_written = false;
225
226 {
227 let mut write_c = |c| {
228 if has_written { s += ";"; }
229 has_written = true;
230 s += c;
231 };
232
233 if self.overwrite { write_c("0") }
234
235 if self.bold { write_c("1"); }
236 if self.dim { write_c("2"); }
237 if self.italic { write_c("3"); }
238 if self.underline { write_c("4"); }
239 if self.blink { write_c("5"); }
240 if self.invert { write_c("7"); }
241 if self.hide { write_c("8"); }
242 if self.strikethrough { write_c("9"); }
243 }
244
245 if let Some(bg) = self.bg {
246 if has_written { s += ";"; }
247 has_written = true;
248 s += bg.as_bg().as_str();
249 }
250
251 if let Some(fg) = self.fg {
252 if has_written { s += ";"; }
253 s += fg.as_fg().as_str();
254 }
255
256 s += "m";
257
258 s
259 }
260}
261
262impl Default for Style {
263 fn default() -> Self {
266 Style {
267 fg: None,
268 bg: None,
269 overwrite: false,
270 bold: false,
271 dim: false,
272 italic: false,
273 underline: false,
274 blink: false,
275 invert: false,
276 hide: false,
277 strikethrough: false,
278 }
279 }
280}
281
282impl Display for Style {
283 #[doc(hidden)]
284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
285 write!(f, "{}", self.gen())
286 }
287}
288
289pub fn flush_styles() {
303 print!("{}", Style::default());
304}