Coverage Report

Created: 2025-07-23 06:05

/rust/registry/src/index.crates.io-6f17d22bba15001f/anstyle-1.0.10/src/style.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::reset::RESET;
2
3
/// ANSI Text styling
4
///
5
/// You can print a `Style` to render the corresponding ANSI code.
6
/// Using the alternate flag `#` will render the ANSI reset code, if needed.
7
/// Together, this makes it convenient to render styles using inline format arguments.
8
///
9
/// # Examples
10
///
11
/// ```rust
12
/// let style = anstyle::Style::new().bold();
13
///
14
/// let value = 42;
15
/// println!("{style}{value}{style:#}");
16
/// ```
17
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
18
pub struct Style {
19
    fg: Option<crate::Color>,
20
    bg: Option<crate::Color>,
21
    underline: Option<crate::Color>,
22
    effects: crate::Effects,
23
}
24
25
/// # Core
26
impl Style {
27
    /// No effects enabled
28
    ///
29
    /// # Examples
30
    ///
31
    /// ```rust
32
    /// let style = anstyle::Style::new();
33
    /// ```
34
    #[inline]
35
0
    pub const fn new() -> Self {
36
0
        Self {
37
0
            fg: None,
38
0
            bg: None,
39
0
            underline: None,
40
0
            effects: crate::Effects::new(),
41
0
        }
42
0
    }
Unexecuted instantiation: <anstyle::style::Style>::new
Unexecuted instantiation: <anstyle::style::Style>::new
43
44
    /// Set foreground color
45
    ///
46
    /// # Examples
47
    ///
48
    /// ```rust
49
    /// let style = anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into()));
50
    /// ```
51
    #[must_use]
52
    #[inline]
53
0
    pub const fn fg_color(mut self, fg: Option<crate::Color>) -> Self {
54
0
        self.fg = fg;
55
0
        self
56
0
    }
Unexecuted instantiation: <anstyle::style::Style>::fg_color
Unexecuted instantiation: <anstyle::style::Style>::fg_color
Unexecuted instantiation: <anstyle::style::Style>::fg_color
57
58
    /// Set background color
59
    ///
60
    /// # Examples
61
    ///
62
    /// ```rust
63
    /// let style = anstyle::Style::new().bg_color(Some(anstyle::AnsiColor::Red.into()));
64
    /// ```
65
    #[must_use]
66
    #[inline]
67
0
    pub const fn bg_color(mut self, bg: Option<crate::Color>) -> Self {
68
0
        self.bg = bg;
69
0
        self
70
0
    }
Unexecuted instantiation: <anstyle::style::Style>::bg_color
Unexecuted instantiation: <anstyle::style::Style>::bg_color
71
72
    /// Set underline color
73
    ///
74
    /// # Examples
75
    ///
76
    /// ```rust
77
    /// let style = anstyle::Style::new().underline_color(Some(anstyle::AnsiColor::Red.into()));
78
    /// ```
79
    #[must_use]
80
    #[inline]
81
0
    pub const fn underline_color(mut self, underline: Option<crate::Color>) -> Self {
82
0
        self.underline = underline;
83
0
        self
84
0
    }
Unexecuted instantiation: <anstyle::style::Style>::underline_color
Unexecuted instantiation: <anstyle::style::Style>::underline_color
85
86
    /// Set text effects
87
    ///
88
    /// # Examples
89
    ///
90
    /// ```rust
91
    /// let style = anstyle::Style::new().effects(anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE);
92
    /// ```
93
    #[must_use]
94
    #[inline]
95
0
    pub const fn effects(mut self, effects: crate::Effects) -> Self {
96
0
        self.effects = effects;
97
0
        self
98
0
    }
Unexecuted instantiation: <anstyle::style::Style>::effects
Unexecuted instantiation: <anstyle::style::Style>::effects
Unexecuted instantiation: <anstyle::style::Style>::effects
99
100
    /// Render the ANSI code
101
    ///
102
    /// `Style` also implements `Display` directly, so calling this method is optional.
103
    #[inline]
104
0
    pub fn render(self) -> impl core::fmt::Display + Copy {
105
0
        StyleDisplay(self)
106
0
    }
107
108
0
    fn fmt_to(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109
        use core::fmt::Display as _;
110
111
0
        self.effects.render().fmt(f)?;
112
113
0
        if let Some(fg) = self.fg {
114
0
            fg.render_fg().fmt(f)?;
115
0
        }
116
117
0
        if let Some(bg) = self.bg {
118
0
            bg.render_bg().fmt(f)?;
119
0
        }
120
121
0
        if let Some(underline) = self.underline {
122
0
            underline.render_underline().fmt(f)?;
123
0
        }
124
125
0
        Ok(())
126
0
    }
127
128
    /// Write the ANSI code
129
    #[inline]
130
    #[cfg(feature = "std")]
131
0
    pub fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
132
0
        self.effects.write_to(write)?;
133
134
0
        if let Some(fg) = self.fg {
135
0
            fg.write_fg_to(write)?;
136
0
        }
137
138
0
        if let Some(bg) = self.bg {
139
0
            bg.write_bg_to(write)?;
140
0
        }
141
142
0
        if let Some(underline) = self.underline {
143
0
            underline.write_underline_to(write)?;
144
0
        }
145
146
0
        Ok(())
147
0
    }
148
149
    /// Renders the relevant [`Reset`][crate::Reset] code
150
    ///
151
    /// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset.
152
    #[inline]
153
0
    pub fn render_reset(self) -> impl core::fmt::Display + Copy {
154
0
        if self != Self::new() {
155
0
            RESET
156
        } else {
157
0
            ""
158
        }
159
0
    }
Unexecuted instantiation: <anstyle::style::Style>::render_reset
Unexecuted instantiation: <anstyle::style::Style>::render_reset
160
161
    /// Write the relevant [`Reset`][crate::Reset] code
162
    ///
163
    /// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset.
164
    #[inline]
165
    #[cfg(feature = "std")]
166
0
    pub fn write_reset_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
167
0
        if self != Self::new() {
168
0
            write.write_all(RESET.as_bytes())
169
        } else {
170
0
            Ok(())
171
        }
172
0
    }
173
}
174
175
/// # Convenience
176
impl Style {
177
    /// Apply `bold` effect
178
    ///
179
    /// # Examples
180
    ///
181
    /// ```rust
182
    /// let style = anstyle::Style::new().bold();
183
    /// ```
184
    #[must_use]
185
    #[inline]
186
0
    pub const fn bold(mut self) -> Self {
187
0
        self.effects = self.effects.insert(crate::Effects::BOLD);
188
0
        self
189
0
    }
Unexecuted instantiation: <anstyle::style::Style>::bold
Unexecuted instantiation: <anstyle::style::Style>::bold
190
191
    /// Apply `dimmed` effect
192
    ///
193
    /// # Examples
194
    ///
195
    /// ```rust
196
    /// let style = anstyle::Style::new().dimmed();
197
    /// ```
198
    #[must_use]
199
    #[inline]
200
0
    pub const fn dimmed(mut self) -> Self {
201
0
        self.effects = self.effects.insert(crate::Effects::DIMMED);
202
0
        self
203
0
    }
Unexecuted instantiation: <anstyle::style::Style>::dimmed
Unexecuted instantiation: <anstyle::style::Style>::dimmed
204
205
    /// Apply `italic` effect
206
    ///
207
    /// # Examples
208
    ///
209
    /// ```rust
210
    /// let style = anstyle::Style::new().italic();
211
    /// ```
212
    #[must_use]
213
    #[inline]
214
0
    pub const fn italic(mut self) -> Self {
215
0
        self.effects = self.effects.insert(crate::Effects::ITALIC);
216
0
        self
217
0
    }
Unexecuted instantiation: <anstyle::style::Style>::italic
Unexecuted instantiation: <anstyle::style::Style>::italic
218
219
    /// Apply `underline` effect
220
    ///
221
    /// # Examples
222
    ///
223
    /// ```rust
224
    /// let style = anstyle::Style::new().underline();
225
    /// ```
226
    #[must_use]
227
    #[inline]
228
0
    pub const fn underline(mut self) -> Self {
229
0
        self.effects = self.effects.insert(crate::Effects::UNDERLINE);
230
0
        self
231
0
    }
Unexecuted instantiation: <anstyle::style::Style>::underline
Unexecuted instantiation: <anstyle::style::Style>::underline
232
233
    /// Apply `blink` effect
234
    ///
235
    /// # Examples
236
    ///
237
    /// ```rust
238
    /// let style = anstyle::Style::new().blink();
239
    /// ```
240
    #[must_use]
241
    #[inline]
242
0
    pub const fn blink(mut self) -> Self {
243
0
        self.effects = self.effects.insert(crate::Effects::BLINK);
244
0
        self
245
0
    }
246
247
    /// Apply `invert` effect
248
    ///
249
    /// # Examples
250
    ///
251
    /// ```rust
252
    /// let style = anstyle::Style::new().invert();
253
    /// ```
254
    #[must_use]
255
    #[inline]
256
0
    pub const fn invert(mut self) -> Self {
257
0
        self.effects = self.effects.insert(crate::Effects::INVERT);
258
0
        self
259
0
    }
Unexecuted instantiation: <anstyle::style::Style>::invert
Unexecuted instantiation: <anstyle::style::Style>::invert
260
261
    /// Apply `hidden` effect
262
    ///
263
    /// # Examples
264
    ///
265
    /// ```rust
266
    /// let style = anstyle::Style::new().hidden();
267
    /// ```
268
    #[must_use]
269
    #[inline]
270
0
    pub const fn hidden(mut self) -> Self {
271
0
        self.effects = self.effects.insert(crate::Effects::HIDDEN);
272
0
        self
273
0
    }
Unexecuted instantiation: <anstyle::style::Style>::hidden
Unexecuted instantiation: <anstyle::style::Style>::hidden
274
275
    /// Apply `strikethrough` effect
276
    ///
277
    /// # Examples
278
    ///
279
    /// ```rust
280
    /// let style = anstyle::Style::new().strikethrough();
281
    /// ```
282
    #[must_use]
283
    #[inline]
284
0
    pub const fn strikethrough(mut self) -> Self {
285
0
        self.effects = self.effects.insert(crate::Effects::STRIKETHROUGH);
286
0
        self
287
0
    }
Unexecuted instantiation: <anstyle::style::Style>::strikethrough
Unexecuted instantiation: <anstyle::style::Style>::strikethrough
288
}
289
290
/// # Reflection
291
impl Style {
292
    /// Get the foreground color
293
    #[inline]
294
0
    pub const fn get_fg_color(self) -> Option<crate::Color> {
295
0
        self.fg
296
0
    }
297
298
    /// Get the background color
299
    #[inline]
300
    #[allow(missing_docs)]
301
0
    pub const fn get_bg_color(self) -> Option<crate::Color> {
302
0
        self.bg
303
0
    }
304
305
    #[inline]
306
    #[allow(missing_docs)]
307
0
    pub const fn get_underline_color(self) -> Option<crate::Color> {
308
0
        self.underline
309
0
    }
310
311
    #[inline]
312
    #[allow(missing_docs)]
313
0
    pub const fn get_effects(self) -> crate::Effects {
314
0
        self.effects
315
0
    }
Unexecuted instantiation: <anstyle::style::Style>::get_effects
Unexecuted instantiation: <anstyle::style::Style>::get_effects
316
317
    /// Check if no styling is enabled
318
    #[inline]
319
0
    pub const fn is_plain(self) -> bool {
320
0
        self.fg.is_none()
321
0
            && self.bg.is_none()
322
0
            && self.underline.is_none()
323
0
            && self.effects.is_plain()
324
0
    }
325
}
326
327
/// # Examples
328
///
329
/// ```rust
330
/// let style: anstyle::Style = anstyle::Effects::BOLD.into();
331
/// ```
332
impl From<crate::Effects> for Style {
333
    #[inline]
334
0
    fn from(effects: crate::Effects) -> Self {
335
0
        Self::new().effects(effects)
336
0
    }
337
}
338
339
/// # Examples
340
///
341
/// ```rust
342
/// let style = anstyle::Style::new() | anstyle::Effects::BOLD.into();
343
/// ```
344
impl core::ops::BitOr<crate::Effects> for Style {
345
    type Output = Self;
346
347
    #[inline(always)]
348
0
    fn bitor(mut self, rhs: crate::Effects) -> Self {
349
0
        self.effects |= rhs;
350
0
        self
351
0
    }
352
}
353
354
/// # Examples
355
///
356
/// ```rust
357
/// let mut style = anstyle::Style::new();
358
/// style |= anstyle::Effects::BOLD.into();
359
/// ```
360
impl core::ops::BitOrAssign<crate::Effects> for Style {
361
    #[inline]
362
0
    fn bitor_assign(&mut self, other: crate::Effects) {
363
0
        self.effects |= other;
364
0
    }
Unexecuted instantiation: <anstyle::style::Style as core::ops::bit::BitOrAssign<anstyle::effect::Effects>>::bitor_assign
Unexecuted instantiation: <anstyle::style::Style as core::ops::bit::BitOrAssign<anstyle::effect::Effects>>::bitor_assign
365
}
366
367
/// # Examples
368
///
369
/// ```rust
370
/// let style = anstyle::Style::new().bold().underline() - anstyle::Effects::BOLD.into();
371
/// ```
372
impl core::ops::Sub<crate::Effects> for Style {
373
    type Output = Self;
374
375
    #[inline]
376
0
    fn sub(mut self, other: crate::Effects) -> Self {
377
0
        self.effects -= other;
378
0
        self
379
0
    }
380
}
381
382
/// # Examples
383
///
384
/// ```rust
385
/// let mut style = anstyle::Style::new().bold().underline();
386
/// style -= anstyle::Effects::BOLD.into();
387
/// ```
388
impl core::ops::SubAssign<crate::Effects> for Style {
389
    #[inline]
390
0
    fn sub_assign(&mut self, other: crate::Effects) {
391
0
        self.effects -= other;
392
0
    }
393
}
394
395
/// # Examples
396
///
397
/// ```rust
398
/// let effects = anstyle::Effects::BOLD;
399
/// assert_eq!(anstyle::Style::new().effects(effects), effects);
400
/// assert_ne!(anstyle::Effects::UNDERLINE | effects, effects);
401
/// assert_ne!(anstyle::RgbColor(0, 0, 0).on_default() | effects, effects);
402
/// ```
403
impl PartialEq<crate::Effects> for Style {
404
    #[inline]
405
0
    fn eq(&self, other: &crate::Effects) -> bool {
406
0
        let other = Self::from(*other);
407
0
        *self == other
408
0
    }
409
}
410
411
impl core::fmt::Display for Style {
412
    #[inline]
413
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
414
0
        if f.alternate() {
415
0
            self.render_reset().fmt(f)
416
        } else {
417
0
            self.fmt_to(f)
418
        }
419
0
    }
Unexecuted instantiation: <anstyle::style::Style as core::fmt::Display>::fmt
Unexecuted instantiation: <anstyle::style::Style as core::fmt::Display>::fmt
420
}
421
422
#[derive(Copy, Clone, Default, Debug)]
423
struct StyleDisplay(Style);
424
425
impl core::fmt::Display for StyleDisplay {
426
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
427
0
        self.0.fmt_to(f)
428
0
    }
429
}
430
431
#[test]
432
#[cfg(feature = "std")]
433
fn print_size_of() {
434
    use std::mem::size_of;
435
    dbg!(size_of::<Style>());
436
    dbg!(size_of::<StyleDisplay>());
437
}