Coverage Report

Created: 2025-08-28 07:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/nu-ansi-term-0.46.0/src/style.rs
Line
Count
Source (jump to first uncovered line)
1
/// A style is a collection of properties that can format a string
2
/// using ANSI escape codes.
3
///
4
/// # Examples
5
///
6
/// ```
7
/// use nu_ansi_term::{Style, Color};
8
///
9
/// let style = Style::new().bold().on(Color::Black);
10
/// println!("{}", style.paint("Bold on black"));
11
/// ```
12
#[derive(PartialEq, Clone, Copy)]
13
#[cfg_attr(
14
    feature = "derive_serde_style",
15
    derive(serde::Deserialize, serde::Serialize)
16
)]
17
pub struct Style {
18
    /// The style's foreground color, if it has one.
19
    pub foreground: Option<Color>,
20
21
    /// The style's background color, if it has one.
22
    pub background: Option<Color>,
23
24
    /// Whether this style is bold.
25
    pub is_bold: bool,
26
27
    /// Whether this style is dimmed.
28
    pub is_dimmed: bool,
29
30
    /// Whether this style is italic.
31
    pub is_italic: bool,
32
33
    /// Whether this style is underlined.
34
    pub is_underline: bool,
35
36
    /// Whether this style is blinking.
37
    pub is_blink: bool,
38
39
    /// Whether this style has reverse colors.
40
    pub is_reverse: bool,
41
42
    /// Whether this style is hidden.
43
    pub is_hidden: bool,
44
45
    /// Whether this style is struckthrough.
46
    pub is_strikethrough: bool,
47
}
48
49
impl Style {
50
    /// Creates a new Style with no properties set.
51
    ///
52
    /// # Examples
53
    ///
54
    /// ```
55
    /// use nu_ansi_term::Style;
56
    ///
57
    /// let style = Style::new();
58
    /// println!("{}", style.paint("hi"));
59
    /// ```
60
0
    pub fn new() -> Style {
61
0
        Style::default()
62
0
    }
63
64
    /// Returns a `Style` with the bold property set.
65
    ///
66
    /// # Examples
67
    ///
68
    /// ```
69
    /// use nu_ansi_term::Style;
70
    ///
71
    /// let style = Style::new().bold();
72
    /// println!("{}", style.paint("hey"));
73
    /// ```
74
0
    pub fn bold(&self) -> Style {
75
0
        Style {
76
0
            is_bold: true,
77
0
            ..*self
78
0
        }
79
0
    }
80
81
    /// Returns a `Style` with the dimmed property set.
82
    ///
83
    /// # Examples
84
    ///
85
    /// ```
86
    /// use nu_ansi_term::Style;
87
    ///
88
    /// let style = Style::new().dimmed();
89
    /// println!("{}", style.paint("sup"));
90
    /// ```
91
0
    pub fn dimmed(&self) -> Style {
92
0
        Style {
93
0
            is_dimmed: true,
94
0
            ..*self
95
0
        }
96
0
    }
97
98
    /// Returns a `Style` with the italic property set.
99
    ///
100
    /// # Examples
101
    ///
102
    /// ```
103
    /// use nu_ansi_term::Style;
104
    ///
105
    /// let style = Style::new().italic();
106
    /// println!("{}", style.paint("greetings"));
107
    /// ```
108
0
    pub fn italic(&self) -> Style {
109
0
        Style {
110
0
            is_italic: true,
111
0
            ..*self
112
0
        }
113
0
    }
114
115
    /// Returns a `Style` with the underline property set.
116
    ///
117
    /// # Examples
118
    ///
119
    /// ```
120
    /// use nu_ansi_term::Style;
121
    ///
122
    /// let style = Style::new().underline();
123
    /// println!("{}", style.paint("salutations"));
124
    /// ```
125
0
    pub fn underline(&self) -> Style {
126
0
        Style {
127
0
            is_underline: true,
128
0
            ..*self
129
0
        }
130
0
    }
131
132
    /// Returns a `Style` with the blink property set.
133
    /// # Examples
134
    ///
135
    /// ```
136
    /// use nu_ansi_term::Style;
137
    ///
138
    /// let style = Style::new().blink();
139
    /// println!("{}", style.paint("wazzup"));
140
    /// ```
141
0
    pub fn blink(&self) -> Style {
142
0
        Style {
143
0
            is_blink: true,
144
0
            ..*self
145
0
        }
146
0
    }
147
148
    /// Returns a `Style` with the reverse property set.
149
    ///
150
    /// # Examples
151
    ///
152
    /// ```
153
    /// use nu_ansi_term::Style;
154
    ///
155
    /// let style = Style::new().reverse();
156
    /// println!("{}", style.paint("aloha"));
157
    /// ```
158
0
    pub fn reverse(&self) -> Style {
159
0
        Style {
160
0
            is_reverse: true,
161
0
            ..*self
162
0
        }
163
0
    }
164
165
    /// Returns a `Style` with the hidden property set.
166
    ///
167
    /// # Examples
168
    ///
169
    /// ```
170
    /// use nu_ansi_term::Style;
171
    ///
172
    /// let style = Style::new().hidden();
173
    /// println!("{}", style.paint("ahoy"));
174
    /// ```
175
0
    pub fn hidden(&self) -> Style {
176
0
        Style {
177
0
            is_hidden: true,
178
0
            ..*self
179
0
        }
180
0
    }
181
182
    /// Returns a `Style` with the strikethrough property set.
183
    ///
184
    /// # Examples
185
    ///
186
    /// ```
187
    /// use nu_ansi_term::Style;
188
    ///
189
    /// let style = Style::new().strikethrough();
190
    /// println!("{}", style.paint("yo"));
191
    /// ```
192
0
    pub fn strikethrough(&self) -> Style {
193
0
        Style {
194
0
            is_strikethrough: true,
195
0
            ..*self
196
0
        }
197
0
    }
198
199
    /// Returns a `Style` with the foreground color property set.
200
    ///
201
    /// # Examples
202
    ///
203
    /// ```
204
    /// use nu_ansi_term::{Style, Color};
205
    ///
206
    /// let style = Style::new().fg(Color::Yellow);
207
    /// println!("{}", style.paint("hi"));
208
    /// ```
209
0
    pub fn fg(&self, foreground: Color) -> Style {
210
0
        Style {
211
0
            foreground: Some(foreground),
212
0
            ..*self
213
0
        }
214
0
    }
215
216
    /// Returns a `Style` with the background color property set.
217
    ///
218
    /// # Examples
219
    ///
220
    /// ```
221
    /// use nu_ansi_term::{Style, Color};
222
    ///
223
    /// let style = Style::new().on(Color::Blue);
224
    /// println!("{}", style.paint("eyyyy"));
225
    /// ```
226
0
    pub fn on(&self, background: Color) -> Style {
227
0
        Style {
228
0
            background: Some(background),
229
0
            ..*self
230
0
        }
231
0
    }
232
233
    /// Return true if this `Style` has no actual styles, and can be written
234
    /// without any control characters.
235
    ///
236
    /// # Examples
237
    ///
238
    /// ```
239
    /// use nu_ansi_term::Style;
240
    ///
241
    /// assert_eq!(true,  Style::default().is_plain());
242
    /// assert_eq!(false, Style::default().bold().is_plain());
243
    /// ```
244
0
    pub fn is_plain(self) -> bool {
245
0
        self == Style::default()
246
0
    }
247
}
248
249
impl Default for Style {
250
    /// Returns a style with *no* properties set. Formatting text using this
251
    /// style returns the exact same text.
252
    ///
253
    /// ```
254
    /// use nu_ansi_term::Style;
255
    /// assert_eq!(None,  Style::default().foreground);
256
    /// assert_eq!(None,  Style::default().background);
257
    /// assert_eq!(false, Style::default().is_bold);
258
    /// assert_eq!("txt", Style::default().paint("txt").to_string());
259
    /// ```
260
0
    fn default() -> Style {
261
0
        Style {
262
0
            foreground: None,
263
0
            background: None,
264
0
            is_bold: false,
265
0
            is_dimmed: false,
266
0
            is_italic: false,
267
0
            is_underline: false,
268
0
            is_blink: false,
269
0
            is_reverse: false,
270
0
            is_hidden: false,
271
0
            is_strikethrough: false,
272
0
        }
273
0
    }
274
}
275
276
// ---- colors ----
277
278
/// A color is one specific type of ANSI escape code, and can refer
279
/// to either the foreground or background color.
280
///
281
/// These use the standard numeric sequences.
282
/// See <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html>
283
#[derive(PartialEq, Clone, Copy, Debug)]
284
#[cfg_attr(
285
    feature = "derive_serde_style",
286
    derive(serde::Deserialize, serde::Serialize)
287
)]
288
pub enum Color {
289
    /// Color #0 (foreground code `30`, background code `40`).
290
    ///
291
    /// This is not necessarily the background color, and using it as one may
292
    /// render the text hard to read on terminals with dark backgrounds.
293
    Black,
294
295
    /// Color #0 (foreground code `90`, background code `100`).
296
    DarkGray,
297
298
    /// Color #1 (foreground code `31`, background code `41`).
299
    Red,
300
301
    /// Color #1 (foreground code `91`, background code `101`).
302
    LightRed,
303
304
    /// Color #2 (foreground code `32`, background code `42`).
305
    Green,
306
307
    /// Color #2 (foreground code `92`, background code `102`).
308
    LightGreen,
309
310
    /// Color #3 (foreground code `33`, background code `43`).
311
    Yellow,
312
313
    /// Color #3 (foreground code `93`, background code `103`).
314
    LightYellow,
315
316
    /// Color #4 (foreground code `34`, background code `44`).
317
    Blue,
318
319
    /// Color #4 (foreground code `94`, background code `104`).
320
    LightBlue,
321
322
    /// Color #5 (foreground code `35`, background code `45`).
323
    Purple,
324
325
    /// Color #5 (foreground code `95`, background code `105`).
326
    LightPurple,
327
328
    /// Color #5 (foreground code `35`, background code `45`).
329
    Magenta,
330
331
    /// Color #5 (foreground code `95`, background code `105`).
332
    LightMagenta,
333
334
    /// Color #6 (foreground code `36`, background code `46`).
335
    Cyan,
336
337
    /// Color #6 (foreground code `96`, background code `106`).
338
    LightCyan,
339
340
    /// Color #7 (foreground code `37`, background code `47`).
341
    ///
342
    /// As above, this is not necessarily the foreground color, and may be
343
    /// hard to read on terminals with light backgrounds.
344
    White,
345
346
    /// Color #7 (foreground code `97`, background code `107`).
347
    LightGray,
348
349
    /// A color number from 0 to 255, for use in 256-color terminal
350
    /// environments.
351
    ///
352
    /// - colors 0 to 7 are the `Black` to `White` variants respectively.
353
    ///   These colors can usually be changed in the terminal emulator.
354
    /// - colors 8 to 15 are brighter versions of the eight colors above.
355
    ///   These can also usually be changed in the terminal emulator, or it
356
    ///   could be configured to use the original colors and show the text in
357
    ///   bold instead. It varies depending on the program.
358
    /// - colors 16 to 231 contain several palettes of bright colors,
359
    ///   arranged in six squares measuring six by six each.
360
    /// - colors 232 to 255 are shades of grey from black to white.
361
    ///
362
    /// It might make more sense to look at a [color chart][cc].
363
    ///
364
    /// [cc]: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
365
    Fixed(u8),
366
367
    /// A 24-bit Rgb color, as specified by ISO-8613-3.
368
    Rgb(u8, u8, u8),
369
370
    /// The default color (foreground code `39`, background codr `49`).
371
    Default,
372
}
373
374
impl Default for Color {
375
0
    fn default() -> Self {
376
0
        Color::White
377
0
    }
378
}
379
380
impl Color {
381
    /// Returns a `Style` with the foreground color set to this color.
382
    ///
383
    /// # Examples
384
    ///
385
    /// ```
386
    /// use nu_ansi_term::Color;
387
    ///
388
    /// let style = Color::Red.normal();
389
    /// println!("{}", style.paint("hi"));
390
    /// ```
391
0
    pub fn normal(self) -> Style {
392
0
        Style {
393
0
            foreground: Some(self),
394
0
            ..Style::default()
395
0
        }
396
0
    }
397
398
    /// Returns a `Style` with the foreground color set to this color and the
399
    /// bold property set.
400
    ///
401
    /// # Examples
402
    ///
403
    /// ```
404
    /// use nu_ansi_term::Color;
405
    ///
406
    /// let style = Color::Green.bold();
407
    /// println!("{}", style.paint("hey"));
408
    /// ```
409
0
    pub fn bold(self) -> Style {
410
0
        Style {
411
0
            foreground: Some(self),
412
0
            is_bold: true,
413
0
            ..Style::default()
414
0
        }
415
0
    }
416
417
    /// Returns a `Style` with the foreground color set to this color and the
418
    /// dimmed property set.
419
    ///
420
    /// # Examples
421
    ///
422
    /// ```
423
    /// use nu_ansi_term::Color;
424
    ///
425
    /// let style = Color::Yellow.dimmed();
426
    /// println!("{}", style.paint("sup"));
427
    /// ```
428
0
    pub fn dimmed(self) -> Style {
429
0
        Style {
430
0
            foreground: Some(self),
431
0
            is_dimmed: true,
432
0
            ..Style::default()
433
0
        }
434
0
    }
435
436
    /// Returns a `Style` with the foreground color set to this color and the
437
    /// italic property set.
438
    ///
439
    /// # Examples
440
    ///
441
    /// ```
442
    /// use nu_ansi_term::Color;
443
    ///
444
    /// let style = Color::Blue.italic();
445
    /// println!("{}", style.paint("greetings"));
446
    /// ```
447
0
    pub fn italic(self) -> Style {
448
0
        Style {
449
0
            foreground: Some(self),
450
0
            is_italic: true,
451
0
            ..Style::default()
452
0
        }
453
0
    }
454
455
    /// Returns a `Style` with the foreground color set to this color and the
456
    /// underline property set.
457
    ///
458
    /// # Examples
459
    ///
460
    /// ```
461
    /// use nu_ansi_term::Color;
462
    ///
463
    /// let style = Color::Purple.underline();
464
    /// println!("{}", style.paint("salutations"));
465
    /// ```
466
0
    pub fn underline(self) -> Style {
467
0
        Style {
468
0
            foreground: Some(self),
469
0
            is_underline: true,
470
0
            ..Style::default()
471
0
        }
472
0
    }
473
474
    /// Returns a `Style` with the foreground color set to this color and the
475
    /// blink property set.
476
    ///
477
    /// # Examples
478
    ///
479
    /// ```
480
    /// use nu_ansi_term::Color;
481
    ///
482
    /// let style = Color::Cyan.blink();
483
    /// println!("{}", style.paint("wazzup"));
484
    /// ```
485
0
    pub fn blink(self) -> Style {
486
0
        Style {
487
0
            foreground: Some(self),
488
0
            is_blink: true,
489
0
            ..Style::default()
490
0
        }
491
0
    }
492
493
    /// Returns a `Style` with the foreground color set to this color and the
494
    /// reverse property set.
495
    ///
496
    /// # Examples
497
    ///
498
    /// ```
499
    /// use nu_ansi_term::Color;
500
    ///
501
    /// let style = Color::Black.reverse();
502
    /// println!("{}", style.paint("aloha"));
503
    /// ```
504
0
    pub fn reverse(self) -> Style {
505
0
        Style {
506
0
            foreground: Some(self),
507
0
            is_reverse: true,
508
0
            ..Style::default()
509
0
        }
510
0
    }
511
512
    /// Returns a `Style` with the foreground color set to this color and the
513
    /// hidden property set.
514
    ///
515
    /// # Examples
516
    ///
517
    /// ```
518
    /// use nu_ansi_term::Color;
519
    ///
520
    /// let style = Color::White.hidden();
521
    /// println!("{}", style.paint("ahoy"));
522
    /// ```
523
0
    pub fn hidden(self) -> Style {
524
0
        Style {
525
0
            foreground: Some(self),
526
0
            is_hidden: true,
527
0
            ..Style::default()
528
0
        }
529
0
    }
530
531
    /// Returns a `Style` with the foreground color set to this color and the
532
    /// strikethrough property set.
533
    ///
534
    /// # Examples
535
    ///
536
    /// ```
537
    /// use nu_ansi_term::Color;
538
    ///
539
    /// let style = Color::Fixed(244).strikethrough();
540
    /// println!("{}", style.paint("yo"));
541
    /// ```
542
0
    pub fn strikethrough(self) -> Style {
543
0
        Style {
544
0
            foreground: Some(self),
545
0
            is_strikethrough: true,
546
0
            ..Style::default()
547
0
        }
548
0
    }
549
550
    /// Returns a `Style` with the foreground color set to this color and the
551
    /// background color property set to the given color.
552
    ///
553
    /// # Examples
554
    ///
555
    /// ```
556
    /// use nu_ansi_term::Color;
557
    ///
558
    /// let style = Color::Rgb(31, 31, 31).on(Color::White);
559
    /// println!("{}", style.paint("eyyyy"));
560
    /// ```
561
0
    pub fn on(self, background: Color) -> Style {
562
0
        Style {
563
0
            foreground: Some(self),
564
0
            background: Some(background),
565
0
            ..Style::default()
566
0
        }
567
0
    }
568
}
569
570
impl From<Color> for Style {
571
    /// You can turn a `Color` into a `Style` with the foreground color set
572
    /// with the `From` trait.
573
    ///
574
    /// ```
575
    /// use nu_ansi_term::{Style, Color};
576
    /// let green_foreground = Style::default().fg(Color::Green);
577
    /// assert_eq!(green_foreground, Color::Green.normal());
578
    /// assert_eq!(green_foreground, Color::Green.into());
579
    /// assert_eq!(green_foreground, Style::from(Color::Green));
580
    /// ```
581
0
    fn from(color: Color) -> Style {
582
0
        color.normal()
583
0
    }
584
}
585
586
#[cfg(test)]
587
#[cfg(feature = "derive_serde_style")]
588
mod serde_json_tests {
589
    use super::{Color, Style};
590
591
    #[test]
592
    fn color_serialization() {
593
        let colors = &[
594
            Color::Red,
595
            Color::Blue,
596
            Color::Rgb(123, 123, 123),
597
            Color::Fixed(255),
598
        ];
599
600
        assert_eq!(
601
            serde_json::to_string(&colors).unwrap(),
602
            String::from("[\"Red\",\"Blue\",{\"Rgb\":[123,123,123]},{\"Fixed\":255}]")
603
        );
604
    }
605
606
    #[test]
607
    fn color_deserialization() {
608
        let colors = [
609
            Color::Red,
610
            Color::Blue,
611
            Color::Rgb(123, 123, 123),
612
            Color::Fixed(255),
613
        ];
614
615
        for color in colors {
616
            let serialized = serde_json::to_string(&color).unwrap();
617
            let deserialized: Color = serde_json::from_str(&serialized).unwrap();
618
619
            assert_eq!(color, deserialized);
620
        }
621
    }
622
623
    #[test]
624
    fn style_serialization() {
625
        let style = Style::default();
626
627
        assert_eq!(serde_json::to_string(&style).unwrap(), "{\"foreground\":null,\"background\":null,\"is_bold\":false,\"is_dimmed\":false,\"is_italic\":false,\"is_underline\":false,\"is_blink\":false,\"is_reverse\":false,\"is_hidden\":false,\"is_strikethrough\":false}".to_string());
628
    }
629
}