xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/anstyle-1.0.6/src/style.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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]
new() -> Self35     pub const fn new() -> Self {
36         Self {
37             fg: None,
38             bg: None,
39             underline: None,
40             effects: crate::Effects::new(),
41         }
42     }
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]
fg_color(mut self, fg: Option<crate::Color>) -> Self53     pub const fn fg_color(mut self, fg: Option<crate::Color>) -> Self {
54         self.fg = fg;
55         self
56     }
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]
bg_color(mut self, bg: Option<crate::Color>) -> Self67     pub const fn bg_color(mut self, bg: Option<crate::Color>) -> Self {
68         self.bg = bg;
69         self
70     }
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]
underline_color(mut self, underline: Option<crate::Color>) -> Self81     pub const fn underline_color(mut self, underline: Option<crate::Color>) -> Self {
82         self.underline = underline;
83         self
84     }
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]
effects(mut self, effects: crate::Effects) -> Self95     pub const fn effects(mut self, effects: crate::Effects) -> Self {
96         self.effects = effects;
97         self
98     }
99 
100     /// Render the ANSI code
101     ///
102     /// `Style` also implements `Display` directly, so calling this method is optional.
103     #[inline]
render(self) -> impl core::fmt::Display + Copy + Clone104     pub fn render(self) -> impl core::fmt::Display + Copy + Clone {
105         StyleDisplay(self)
106     }
107 
fmt_to(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result108     fn fmt_to(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
109         use core::fmt::Display as _;
110 
111         self.effects.render().fmt(f)?;
112 
113         if let Some(fg) = self.fg {
114             fg.render_fg().fmt(f)?;
115         }
116 
117         if let Some(bg) = self.bg {
118             bg.render_bg().fmt(f)?;
119         }
120 
121         if let Some(underline) = self.underline {
122             underline.render_underline().fmt(f)?;
123         }
124 
125         Ok(())
126     }
127 
128     /// Write the ANSI code
129     #[inline]
130     #[cfg(feature = "std")]
write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()>131     pub fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
132         self.effects.write_to(write)?;
133 
134         if let Some(fg) = self.fg {
135             fg.write_fg_to(write)?;
136         }
137 
138         if let Some(bg) = self.bg {
139             bg.write_bg_to(write)?;
140         }
141 
142         if let Some(underline) = self.underline {
143             underline.write_underline_to(write)?;
144         }
145 
146         Ok(())
147     }
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]
render_reset(self) -> impl core::fmt::Display + Copy + Clone153     pub fn render_reset(self) -> impl core::fmt::Display + Copy + Clone {
154         if self != Self::new() {
155             RESET
156         } else {
157             ""
158         }
159     }
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")]
write_reset_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()>166     pub fn write_reset_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> {
167         if self != Self::new() {
168             write.write_all(RESET.as_bytes())
169         } else {
170             Ok(())
171         }
172     }
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]
bold(mut self) -> Self186     pub const fn bold(mut self) -> Self {
187         self.effects = self.effects.insert(crate::Effects::BOLD);
188         self
189     }
190 
191     /// Apply `dimmed` effect
192     ///
193     /// # Examples
194     ///
195     /// ```rust
196     /// let style = anstyle::Style::new().dimmed();
197     /// ```
198     #[must_use]
199     #[inline]
dimmed(mut self) -> Self200     pub const fn dimmed(mut self) -> Self {
201         self.effects = self.effects.insert(crate::Effects::DIMMED);
202         self
203     }
204 
205     /// Apply `italic` effect
206     ///
207     /// # Examples
208     ///
209     /// ```rust
210     /// let style = anstyle::Style::new().italic();
211     /// ```
212     #[must_use]
213     #[inline]
italic(mut self) -> Self214     pub const fn italic(mut self) -> Self {
215         self.effects = self.effects.insert(crate::Effects::ITALIC);
216         self
217     }
218 
219     /// Apply `underline` effect
220     ///
221     /// # Examples
222     ///
223     /// ```rust
224     /// let style = anstyle::Style::new().underline();
225     /// ```
226     #[must_use]
227     #[inline]
underline(mut self) -> Self228     pub const fn underline(mut self) -> Self {
229         self.effects = self.effects.insert(crate::Effects::UNDERLINE);
230         self
231     }
232 
233     /// Apply `blink` effect
234     ///
235     /// # Examples
236     ///
237     /// ```rust
238     /// let style = anstyle::Style::new().blink();
239     /// ```
240     #[must_use]
241     #[inline]
blink(mut self) -> Self242     pub const fn blink(mut self) -> Self {
243         self.effects = self.effects.insert(crate::Effects::BLINK);
244         self
245     }
246 
247     /// Apply `invert` effect
248     ///
249     /// # Examples
250     ///
251     /// ```rust
252     /// let style = anstyle::Style::new().invert();
253     /// ```
254     #[must_use]
255     #[inline]
invert(mut self) -> Self256     pub const fn invert(mut self) -> Self {
257         self.effects = self.effects.insert(crate::Effects::INVERT);
258         self
259     }
260 
261     /// Apply `hidden` effect
262     ///
263     /// # Examples
264     ///
265     /// ```rust
266     /// let style = anstyle::Style::new().hidden();
267     /// ```
268     #[must_use]
269     #[inline]
hidden(mut self) -> Self270     pub const fn hidden(mut self) -> Self {
271         self.effects = self.effects.insert(crate::Effects::HIDDEN);
272         self
273     }
274 
275     /// Apply `strikethrough` effect
276     ///
277     /// # Examples
278     ///
279     /// ```rust
280     /// let style = anstyle::Style::new().strikethrough();
281     /// ```
282     #[must_use]
283     #[inline]
strikethrough(mut self) -> Self284     pub const fn strikethrough(mut self) -> Self {
285         self.effects = self.effects.insert(crate::Effects::STRIKETHROUGH);
286         self
287     }
288 }
289 
290 /// # Reflection
291 impl Style {
292     #[inline]
get_fg_color(self) -> Option<crate::Color>293     pub const fn get_fg_color(self) -> Option<crate::Color> {
294         self.fg
295     }
296 
297     #[inline]
get_bg_color(self) -> Option<crate::Color>298     pub const fn get_bg_color(self) -> Option<crate::Color> {
299         self.bg
300     }
301 
302     #[inline]
get_underline_color(self) -> Option<crate::Color>303     pub const fn get_underline_color(self) -> Option<crate::Color> {
304         self.underline
305     }
306 
307     #[inline]
get_effects(self) -> crate::Effects308     pub const fn get_effects(self) -> crate::Effects {
309         self.effects
310     }
311 
312     /// Check if no effects are enabled
313     #[inline]
is_plain(self) -> bool314     pub const fn is_plain(self) -> bool {
315         self.fg.is_none()
316             && self.bg.is_none()
317             && self.underline.is_none()
318             && self.effects.is_plain()
319     }
320 }
321 
322 /// # Examples
323 ///
324 /// ```rust
325 /// let style: anstyle::Style = anstyle::Effects::BOLD.into();
326 /// ```
327 impl From<crate::Effects> for Style {
328     #[inline]
from(effects: crate::Effects) -> Self329     fn from(effects: crate::Effects) -> Self {
330         Self::new().effects(effects)
331     }
332 }
333 
334 /// # Examples
335 ///
336 /// ```rust
337 /// let style = anstyle::Style::new() | anstyle::Effects::BOLD.into();
338 /// ```
339 impl core::ops::BitOr<crate::Effects> for Style {
340     type Output = Self;
341 
342     #[inline(always)]
bitor(mut self, rhs: crate::Effects) -> Self343     fn bitor(mut self, rhs: crate::Effects) -> Self {
344         self.effects |= rhs;
345         self
346     }
347 }
348 
349 /// # Examples
350 ///
351 /// ```rust
352 /// let mut style = anstyle::Style::new();
353 /// style |= anstyle::Effects::BOLD.into();
354 /// ```
355 impl core::ops::BitOrAssign<crate::Effects> for Style {
356     #[inline]
bitor_assign(&mut self, other: crate::Effects)357     fn bitor_assign(&mut self, other: crate::Effects) {
358         self.effects |= other;
359     }
360 }
361 
362 /// # Examples
363 ///
364 /// ```rust
365 /// let style = anstyle::Style::new().bold().underline() - anstyle::Effects::BOLD.into();
366 /// ```
367 impl core::ops::Sub<crate::Effects> for Style {
368     type Output = Self;
369 
370     #[inline]
sub(mut self, other: crate::Effects) -> Self371     fn sub(mut self, other: crate::Effects) -> Self {
372         self.effects -= other;
373         self
374     }
375 }
376 
377 /// # Examples
378 ///
379 /// ```rust
380 /// let mut style = anstyle::Style::new().bold().underline();
381 /// style -= anstyle::Effects::BOLD.into();
382 /// ```
383 impl core::ops::SubAssign<crate::Effects> for Style {
384     #[inline]
sub_assign(&mut self, other: crate::Effects)385     fn sub_assign(&mut self, other: crate::Effects) {
386         self.effects -= other;
387     }
388 }
389 
390 /// # Examples
391 ///
392 /// ```rust
393 /// let effects = anstyle::Effects::BOLD;
394 /// assert_eq!(anstyle::Style::new().effects(effects), effects);
395 /// assert_ne!(anstyle::Effects::UNDERLINE | effects, effects);
396 /// assert_ne!(anstyle::RgbColor(0, 0, 0).on_default() | effects, effects);
397 /// ```
398 impl core::cmp::PartialEq<crate::Effects> for Style {
399     #[inline]
eq(&self, other: &crate::Effects) -> bool400     fn eq(&self, other: &crate::Effects) -> bool {
401         let other = Self::from(*other);
402         *self == other
403     }
404 }
405 
406 impl core::fmt::Display for Style {
407     #[inline]
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result408     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
409         if f.alternate() {
410             self.render_reset().fmt(f)
411         } else {
412             self.fmt_to(f)
413         }
414     }
415 }
416 
417 #[derive(Copy, Clone, Default, Debug)]
418 struct StyleDisplay(Style);
419 
420 impl core::fmt::Display for StyleDisplay {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result421     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
422         self.0.fmt_to(f)
423     }
424 }
425 
426 #[test]
print_size_of()427 fn print_size_of() {
428     use std::mem::size_of;
429     dbg!(size_of::<Style>());
430     dbg!(size_of::<StyleDisplay>());
431 }
432