clap_builder/builder/
styling.rs

1//! Terminal [`Styles`] for help and error output
2
3pub use anstyle::*;
4
5/// Terminal styling definitions
6///
7/// See also [`Command::styles`][crate::Command::styles].
8///
9/// # Example
10///
11/// clap v3 styling
12/// ```rust
13/// # use clap_builder as clap;
14/// # use clap::builder::styling::*;
15/// let styles = Styles::styled()
16///     .header(AnsiColor::Yellow.on_default())
17///     .usage(AnsiColor::Green.on_default())
18///     .literal(AnsiColor::Green.on_default())
19///     .placeholder(AnsiColor::Green.on_default());
20/// ```
21#[derive(Clone, Debug)]
22#[allow(missing_copy_implementations)] // Large enough type that I want an explicit `clone()` for now
23pub struct Styles {
24    header: Style,
25    error: Style,
26    usage: Style,
27    literal: Style,
28    placeholder: Style,
29    valid: Style,
30    invalid: Style,
31}
32
33impl Styles {
34    /// No terminal styling
35    pub const fn plain() -> Self {
36        Self {
37            header: Style::new(),
38            error: Style::new(),
39            usage: Style::new(),
40            literal: Style::new(),
41            placeholder: Style::new(),
42            valid: Style::new(),
43            invalid: Style::new(),
44        }
45    }
46
47    /// Default terminal styling
48    pub const fn styled() -> Self {
49        #[cfg(feature = "color")]
50        {
51            Self {
52                header: Style::new().bold().underline(),
53                error: Style::new()
54                    .fg_color(Some(Color::Ansi(AnsiColor::Red)))
55                    .bold(),
56                usage: Style::new().bold().underline(),
57                literal: Style::new().bold(),
58                placeholder: Style::new(),
59                valid: Style::new().fg_color(Some(Color::Ansi(AnsiColor::Green))),
60                invalid: Style::new().fg_color(Some(Color::Ansi(AnsiColor::Yellow))),
61            }
62        }
63        #[cfg(not(feature = "color"))]
64        {
65            Self::plain()
66        }
67    }
68
69    /// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
70    #[inline]
71    pub const fn header(mut self, style: Style) -> Self {
72        self.header = style;
73        self
74    }
75
76    /// Error heading
77    #[inline]
78    pub const fn error(mut self, style: Style) -> Self {
79        self.error = style;
80        self
81    }
82
83    /// Usage heading
84    #[inline]
85    pub const fn usage(mut self, style: Style) -> Self {
86        self.usage = style;
87        self
88    }
89
90    /// Literal command-line syntax, e.g. `--help`
91    #[inline]
92    pub const fn literal(mut self, style: Style) -> Self {
93        self.literal = style;
94        self
95    }
96
97    /// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
98    #[inline]
99    pub const fn placeholder(mut self, style: Style) -> Self {
100        self.placeholder = style;
101        self
102    }
103
104    /// Highlight suggested usage
105    #[inline]
106    pub const fn valid(mut self, style: Style) -> Self {
107        self.valid = style;
108        self
109    }
110
111    /// Highlight invalid usage
112    #[inline]
113    pub const fn invalid(mut self, style: Style) -> Self {
114        self.invalid = style;
115        self
116    }
117}
118
119/// Reflection
120impl Styles {
121    /// General Heading style, e.g. [`help_heading`][crate::Arg::help_heading]
122    #[inline(always)]
123    pub const fn get_header(&self) -> &Style {
124        &self.header
125    }
126
127    /// Error heading
128    #[inline(always)]
129    pub const fn get_error(&self) -> &Style {
130        &self.error
131    }
132
133    /// Usage heading
134    #[inline(always)]
135    pub const fn get_usage(&self) -> &Style {
136        &self.usage
137    }
138
139    /// Literal command-line syntax, e.g. `--help`
140    #[inline(always)]
141    pub const fn get_literal(&self) -> &Style {
142        &self.literal
143    }
144
145    /// Descriptions within command-line syntax, e.g. [`value_name`][crate::Arg::value_name]
146    #[inline(always)]
147    pub const fn get_placeholder(&self) -> &Style {
148        &self.placeholder
149    }
150
151    /// Highlight suggested usage
152    #[inline(always)]
153    pub const fn get_valid(&self) -> &Style {
154        &self.valid
155    }
156
157    /// Highlight invalid usage
158    #[inline(always)]
159    pub const fn get_invalid(&self) -> &Style {
160        &self.invalid
161    }
162}
163
164impl super::AppExt for Styles {}
165
166impl Default for Styles {
167    fn default() -> Self {
168        Self::styled()
169    }
170}
171
172impl Default for &'_ Styles {
173    fn default() -> Self {
174        const STYLES: Styles = Styles::styled();
175        &STYLES
176    }
177}