Skip to main content

ctl_core/
style.rs

1//! ANSI styles for pretty views.
2
3use anstyle::{AnsiColor, Style};
4
5/// Section heading (cyan bold).
6pub const HEADING: Style = Style::new()
7    .bold()
8    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Cyan)));
9/// Success text (green bold).
10pub const SUCCESS: Style = Style::new()
11    .bold()
12    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Green)));
13/// Warning text (yellow bold).
14pub const WARNING: Style = Style::new()
15    .bold()
16    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Yellow)));
17/// Error text (red bold).
18pub const ERROR: Style = Style::new()
19    .bold()
20    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Red)));
21/// Value / metavar text (yellow bold).
22pub const VALUE: Style = Style::new()
23    .bold()
24    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Yellow)));
25/// Secondary text (bright black).
26pub const MUTED: Style = Style::new().fg_color(Some(anstyle::Color::Ansi(AnsiColor::BrightBlack)));
27/// Flag text (green bold).
28pub const OPTION: Style = Style::new()
29    .bold()
30    .fg_color(Some(anstyle::Color::Ansi(AnsiColor::Green)));
31
32#[must_use]
33/// Wrap `value` in `style` and reset.
34pub fn styled(style: Style, value: &str) -> String {
35    if value.is_empty() {
36        String::new()
37    } else {
38        format!("{}{value}{}", style.render(), style.render_reset())
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::{OPTION, styled};
45
46    #[test]
47    fn empty_stays_empty() {
48        assert_eq!(styled(OPTION, ""), "");
49    }
50
51    #[test]
52    fn wraps_nonempty() {
53        let out = styled(OPTION, "--help");
54        assert!(out.contains("--help"));
55        assert_ne!(out, "--help");
56    }
57}