dinglebit_terminal/
style.rs1use crate::consts::*;
19use std::fmt;
20
21#[macro_export]
38macro_rules! style {
39 ($($arg:tt)*) => ($crate::style::Style::new(format!($($arg)*)))
40}
41
42pub struct Style {
58 text: String,
59 values: Vec<u8>,
60}
61
62impl Style {
63 pub fn new(text: String) -> Self {
65 Self {
66 text: text,
67 values: Vec::new(),
68 }
69 }
70
71 pub fn bold(&mut self) -> &mut Self {
73 self.values.push(OP_BOLD);
74 self
75 }
76
77 pub fn faint(&mut self) -> &mut Self {
79 self.values.push(OP_FAINT);
80 self
81 }
82
83 pub fn italic(&mut self) -> &mut Self {
85 self.values.push(OP_ITALIC);
86 self
87 }
88
89 pub fn underline(&mut self) -> &mut Self {
91 self.values.push(OP_UNDERLINE);
92 self
93 }
94
95 pub fn slow_blink(&mut self) -> &mut Self {
97 self.values.push(OP_SLOW_BLINK);
98 self
99 }
100
101 pub fn fast_blink(&mut self) -> &mut Self {
103 self.values.push(OP_FAST_BLINK);
104 self
105 }
106
107 pub fn reverse(&mut self) -> &mut Self {
109 self.values.push(OP_REVERSE);
110 self
111 }
112
113 pub fn conceal(&mut self) -> &mut Self {
115 self.values.push(OP_CONCEAL);
116 self
117 }
118
119 pub fn strikethrough(&mut self) -> &mut Self {
121 self.values.push(OP_STRIKETHROUGH);
122 self
123 }
124
125 pub fn black(&mut self) -> &mut Self {
127 self.values.push(FG_BLACK);
128 self
129 }
130
131 pub fn red(&mut self) -> &mut Self {
133 self.values.push(FG_RED);
134 self
135 }
136
137 pub fn green(&mut self) -> &mut Self {
139 self.values.push(FG_GREEN);
140 self
141 }
142
143 pub fn yellow(&mut self) -> &mut Self {
146 self.values.push(FG_YELLOW);
147 self
148 }
149
150 pub fn blue(&mut self) -> &mut Self {
152 self.values.push(FG_BLUE);
153 self
154 }
155
156 pub fn magenta(&mut self) -> &mut Self {
159 self.values.push(FG_MAGENTA);
160 self
161 }
162
163 pub fn cyan(&mut self) -> &mut Self {
165 self.values.push(FG_CYAN);
166 self
167 }
168
169 pub fn white(&mut self) -> &mut Self {
171 self.values.push(FG_WHITE);
172 self
173 }
174
175 pub fn gray(&mut self) -> &mut Self {
177 self.values.push(FG_GRAY);
178 self
179 }
180
181 pub fn bright_red(&mut self) -> &mut Self {
184 self.values.push(FG_BRIGHT_RED);
185 self
186 }
187
188 pub fn bright_green(&mut self) -> &mut Self {
191 self.values.push(FG_BRIGHT_GREEN);
192 self
193 }
194
195 pub fn bright_yellow(&mut self) -> &mut Self {
198 self.values.push(FG_BRIGHT_YELLOW);
199 self
200 }
201
202 pub fn bright_blue(&mut self) -> &mut Self {
205 self.values.push(FG_BRIGHT_BLUE);
206 self
207 }
208
209 pub fn bright_magenta(&mut self) -> &mut Self {
212 self.values.push(FG_BRIGHT_MAGENTA);
213 self
214 }
215
216 pub fn bright_cyan(&mut self) -> &mut Self {
219 self.values.push(FG_BRIGHT_CYAN);
220 self
221 }
222
223 pub fn bright_white(&mut self) -> &mut Self {
226 self.values.push(FG_BRIGHT_WHITE);
227 self
228 }
229
230 pub fn bg_black(&mut self) -> &mut Self {
232 self.values.push(BG_BLACK);
233 self
234 }
235
236 pub fn bg_red(&mut self) -> &mut Self {
238 self.values.push(BG_RED);
239 self
240 }
241
242 pub fn bg_green(&mut self) -> &mut Self {
244 self.values.push(BG_GREEN);
245 self
246 }
247
248 pub fn bg_yellow(&mut self) -> &mut Self {
251 self.values.push(BG_YELLOW);
252 self
253 }
254
255 pub fn bg_blue(&mut self) -> &mut Self {
257 self.values.push(BG_BLUE);
258 self
259 }
260
261 pub fn bg_magenta(&mut self) -> &mut Self {
264 self.values.push(BG_MAGENTA);
265 self
266 }
267
268 pub fn bg_cyan(&mut self) -> &mut Self {
270 self.values.push(BG_CYAN);
271 self
272 }
273
274 pub fn bg_white(&mut self) -> &mut Self {
276 self.values.push(BG_WHITE);
277 self
278 }
279
280 pub fn bg_gray(&mut self) -> &mut Self {
282 self.values.push(BG_GRAY);
283 self
284 }
285
286 pub fn bg_bright_red(&mut self) -> &mut Self {
289 self.values.push(BG_BRIGHT_RED);
290 self
291 }
292
293 pub fn bg_bright_green(&mut self) -> &mut Self {
296 self.values.push(BG_BRIGHT_GREEN);
297 self
298 }
299
300 pub fn bg_bright_yellow(&mut self) -> &mut Self {
303 self.values.push(BG_BRIGHT_YELLOW);
304 self
305 }
306
307 pub fn bg_bright_blue(&mut self) -> &mut Self {
310 self.values.push(BG_BRIGHT_BLUE);
311 self
312 }
313
314 pub fn bg_bright_magenta(&mut self) -> &mut Self {
317 self.values.push(BG_BRIGHT_MAGENTA);
318 self
319 }
320
321 pub fn bg_bright_cyan(&mut self) -> &mut Self {
324 self.values.push(BG_BRIGHT_CYAN);
325 self
326 }
327
328 pub fn bg_bright_white(&mut self) -> &mut Self {
331 self.values.push(BG_BRIGHT_WHITE);
332 self
333 }
334}
335
336impl fmt::Display for Style {
337 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338 write!(f, "{}{}{}", sgm!(self.values.clone()), self.text, reset!())
339 }
340}
341
342#[cfg(test)]
343mod tests {
344 pub use super::*;
345 pub use crate::consts::*;
346
347 macro_rules! style_test {
348 ( $( $name:ident: $exp:expr ),* ) => {
349 $(
350 #[test]
351 fn $name() {
352 let mut s = Style::new("test".to_string());
353 s.$name();
354 assert_eq!($exp, s.values);
355 }
356 )*
357 }
358 }
359
360 style_test! {
361 bold: vec![OP_BOLD],
362 faint: vec![OP_FAINT],
363 italic: vec![OP_ITALIC],
364 underline: vec![OP_UNDERLINE],
365 slow_blink: vec![OP_SLOW_BLINK],
366 fast_blink: vec![OP_FAST_BLINK],
367 reverse: vec![OP_REVERSE],
368 conceal: vec![OP_CONCEAL],
369 strikethrough: vec![OP_STRIKETHROUGH],
370 black: vec![FG_BLACK],
371 red: vec![FG_RED],
372 green: vec![FG_GREEN],
373 yellow: vec![FG_YELLOW],
374 blue: vec![FG_BLUE],
375 magenta: vec![FG_MAGENTA],
376 cyan: vec![FG_CYAN],
377 white: vec![FG_WHITE],
378 gray: vec![FG_GRAY],
379 bright_red: vec![FG_BRIGHT_RED],
380 bright_green: vec![FG_BRIGHT_GREEN],
381 bright_yellow: vec![FG_BRIGHT_YELLOW],
382 bright_blue: vec![FG_BRIGHT_BLUE],
383 bright_magenta: vec![FG_BRIGHT_MAGENTA],
384 bright_cyan: vec![FG_BRIGHT_CYAN],
385 bright_white: vec![FG_BRIGHT_WHITE],
386 bg_black: vec![BG_BLACK],
387 bg_red: vec![BG_RED],
388 bg_green: vec![BG_GREEN],
389 bg_yellow: vec![BG_YELLOW],
390 bg_blue: vec![BG_BLUE],
391 bg_magenta: vec![BG_MAGENTA],
392 bg_cyan: vec![BG_CYAN],
393 bg_white: vec![BG_WHITE],
394 bg_gray: vec![BG_GRAY],
395 bg_bright_red: vec![BG_BRIGHT_RED],
396 bg_bright_green: vec![BG_BRIGHT_GREEN],
397 bg_bright_yellow: vec![BG_BRIGHT_YELLOW],
398 bg_bright_blue: vec![BG_BRIGHT_BLUE],
399 bg_bright_magenta: vec![BG_BRIGHT_MAGENTA],
400 bg_bright_cyan: vec![BG_BRIGHT_CYAN],
401 bg_bright_white: vec![BG_BRIGHT_WHITE]
402 }
403
404 #[test]
405 fn multi_style() {
406 let mut s = style!("test");
407 s.bold().underline().red().bg_green();
408 assert_eq!(s.values, vec![OP_BOLD, OP_UNDERLINE, FG_RED, BG_GREEN]);
409 assert_eq!(
410 format!(
411 "\x1b[{};{};{};{}mtest\x1b[0m",
412 OP_BOLD, OP_UNDERLINE, FG_RED, BG_GREEN
413 ),
414 s.to_string()
415 );
416 }
417}