owo_colors/styles.rs
1//! Different display styles (strikethrough, bold, etc.)
2use core::fmt;
3
4#[allow(unused_imports)]
5use crate::OwoColorize;
6use crate::{Style, Styled};
7
8macro_rules! impl_fmt_for_style {
9 ($(($ty:ident, $trait:path, $ansi:literal)),* $(,)?) => {
10 $(
11 impl<'a, T: ?Sized + $trait> $trait for $ty<'a, T> {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 f.write_str($ansi)?;
14 <_ as $trait>::fmt(&self.0, f)?;
15 f.write_str("\x1b[0m")
16 }
17 }
18 )*
19 };
20}
21
22/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
23/// with the addition of boldening it. Recommended to be constructed using
24/// [`OwoColorize`](OwoColorize::bold).
25#[repr(transparent)]
26pub struct BoldDisplay<'a, T: ?Sized>(pub &'a T);
27
28impl<'a, T: ?Sized> BoldDisplay<'a, T> {
29 /// Convert self to a generic [`Styled`].
30 ///
31 /// This method erases color-related type parameters, and can be
32 /// used to unify types across branches.
33 ///
34 /// # Example
35 ///
36 /// ```rust
37 /// use owo_colors::OwoColorize;
38 ///
39 /// fn is_bold() -> bool {
40 /// // ...
41 /// # true
42 /// }
43 ///
44 /// let styled_str = if is_bold() {
45 /// "hello".bold().into_styled()
46 /// } else {
47 /// "hello".dimmed().into_styled()
48 /// };
49 ///
50 /// println!("{}", styled_str);
51 /// # assert_eq!(styled_str.to_string(), "\x1b[1mhello\x1b[0m");
52 /// ```
53 pub const fn into_styled(self) -> Styled<&'a T> {
54 let style = Style::new().bold();
55 Styled {
56 style,
57 target: self.0,
58 }
59 }
60}
61
62/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
63/// with the addition of dimming it. Recommended to be constructed using
64/// [`OwoColorize`](OwoColorize::dimmed).
65#[repr(transparent)]
66pub struct DimDisplay<'a, T: ?Sized>(pub &'a T);
67
68impl<'a, T: ?Sized> DimDisplay<'a, T> {
69 /// Convert self to a generic [`Styled`].
70 ///
71 /// This method erases color-related type parameters, and can be
72 /// used to unify types across branches.
73 ///
74 /// # Example
75 ///
76 /// ```rust
77 /// use owo_colors::OwoColorize;
78 ///
79 /// fn is_dimmed() -> bool {
80 /// // ...
81 /// # true
82 /// }
83 ///
84 /// let styled_str = if is_dimmed() {
85 /// "hello".dimmed().into_styled()
86 /// } else {
87 /// "hello".bold().into_styled()
88 /// };
89 ///
90 /// println!("{}", styled_str);
91 /// # assert_eq!(styled_str.to_string(), "\x1b[2mhello\x1b[0m");
92 /// ```
93 pub const fn into_styled(self) -> Styled<&'a T> {
94 let style = Style::new().dimmed();
95 Styled {
96 style,
97 target: self.0,
98 }
99 }
100}
101
102/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
103/// with the addition of italics. Recommended to be constructed using
104/// [`OwoColorize`](OwoColorize::italic).
105#[repr(transparent)]
106pub struct ItalicDisplay<'a, T: ?Sized>(pub &'a T);
107
108impl<'a, T: ?Sized> ItalicDisplay<'a, T> {
109 /// Convert self to a generic [`Styled`].
110 ///
111 /// This method erases color-related type parameters, and can be
112 /// used to unify types across branches.
113 ///
114 /// # Example
115 ///
116 /// ```rust
117 /// use owo_colors::OwoColorize;
118 ///
119 /// fn is_italic() -> bool {
120 /// // ...
121 /// # true
122 /// }
123 ///
124 /// let styled_str = if is_italic() {
125 /// "hello".italic().into_styled()
126 /// } else {
127 /// "hello".underline().into_styled()
128 /// };
129 ///
130 /// println!("{}", styled_str);
131 /// # assert_eq!(styled_str.to_string(), "\x1b[3mhello\x1b[0m");
132 /// ```
133 pub const fn into_styled(self) -> Styled<&'a T> {
134 let style = Style::new().italic();
135 Styled {
136 style,
137 target: self.0,
138 }
139 }
140}
141
142/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
143/// while underlining it. Recommended to be constructed using
144/// [`OwoColorize`](OwoColorize::underline).
145#[repr(transparent)]
146pub struct UnderlineDisplay<'a, T: ?Sized>(pub &'a T);
147
148impl<'a, T: ?Sized> UnderlineDisplay<'a, T> {
149 /// Convert self to a generic [`Styled`].
150 ///
151 /// This method erases color-related type parameters, and can be
152 /// used to unify types across branches.
153 ///
154 /// # Example
155 ///
156 /// ```rust
157 /// use owo_colors::OwoColorize;
158 ///
159 /// fn is_underline() -> bool {
160 /// // ...
161 /// # true
162 /// }
163 ///
164 /// let styled_str = if is_underline() {
165 /// "hello".underline().into_styled()
166 /// } else {
167 /// "hello".italic().into_styled()
168 /// };
169 ///
170 /// println!("{}", styled_str);
171 /// # assert_eq!(styled_str.to_string(), "\x1b[4mhello\x1b[0m");
172 /// ```
173 pub const fn into_styled(self) -> Styled<&'a T> {
174 let style = Style::new().underline();
175 Styled {
176 style,
177 target: self.0,
178 }
179 }
180}
181
182/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
183/// while blinking. Recommended to be constructed using
184/// [`OwoColorize`](OwoColorize::blink).
185#[repr(transparent)]
186pub struct BlinkDisplay<'a, T: ?Sized>(pub &'a T);
187
188impl<'a, T: ?Sized> BlinkDisplay<'a, T> {
189 /// Convert self to a generic [`Styled`].
190 ///
191 /// This method erases color-related type parameters, and can be
192 /// used to unify types across branches.
193 ///
194 /// # Example
195 ///
196 /// ```rust
197 /// use owo_colors::OwoColorize;
198 ///
199 /// fn is_blink() -> bool {
200 /// // ...
201 /// # true
202 /// }
203 ///
204 /// let styled_str = if is_blink() {
205 /// "hello".blink().into_styled()
206 /// } else {
207 /// "hello".hidden().into_styled()
208 /// };
209 ///
210 /// println!("{}", styled_str);
211 /// # assert_eq!(styled_str.to_string(), "\x1b[5mhello\x1b[0m");
212 /// ```
213 pub const fn into_styled(self) -> Styled<&'a T> {
214 let style = Style::new().blink();
215 Styled {
216 style,
217 target: self.0,
218 }
219 }
220}
221
222/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
223/// with the addition of making it blink fast. Use [`OwoColorize`](OwoColorize::blink_fast)
224#[repr(transparent)]
225pub struct BlinkFastDisplay<'a, T: ?Sized>(pub &'a T);
226
227impl<'a, T: ?Sized> BlinkFastDisplay<'a, T> {
228 /// Convert self to a generic [`Styled`].
229 ///
230 /// This method erases color-related type parameters, and can be
231 /// used to unify types across branches.
232 ///
233 /// # Example
234 ///
235 /// ```rust
236 /// use owo_colors::OwoColorize;
237 ///
238 /// fn is_blink_fast() -> bool {
239 /// // ...
240 /// # true
241 /// }
242 ///
243 /// let styled_str = if is_blink_fast() {
244 /// "hello".blink_fast().into_styled()
245 /// } else {
246 /// "hello".reversed().into_styled()
247 /// };
248 ///
249 /// println!("{}", styled_str);
250 /// # assert_eq!(styled_str.to_string(), "\x1b[6mhello\x1b[0m");
251 /// ```
252 pub const fn into_styled(self) -> Styled<&'a T> {
253 let style = Style::new().blink_fast();
254 Styled {
255 style,
256 target: self.0,
257 }
258 }
259}
260
261/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
262/// with the addition of swapping fg and bg colors. Use [`OwoColorize`](OwoColorize::reversed)
263#[repr(transparent)]
264pub struct ReversedDisplay<'a, T: ?Sized>(pub &'a T);
265
266impl<'a, T: ?Sized> ReversedDisplay<'a, T> {
267 /// Convert self to a generic [`Styled`].
268 ///
269 /// This method erases color-related type parameters, and can be
270 /// used to unify types across branches.
271 ///
272 /// # Example
273 ///
274 /// ```rust
275 /// use owo_colors::OwoColorize;
276 ///
277 /// fn is_reversed() -> bool {
278 /// // ...
279 /// # true
280 /// }
281 ///
282 /// let styled_str = if is_reversed() {
283 /// "hello".reversed().into_styled()
284 /// } else {
285 /// "hello".blink_fast().into_styled()
286 /// };
287 ///
288 /// println!("{}", styled_str);
289 /// # assert_eq!(styled_str.to_string(), "\x1b[7mhello\x1b[0m");
290 /// ```
291 pub const fn into_styled(self) -> Styled<&'a T> {
292 let style = Style::new().reversed();
293 Styled {
294 style,
295 target: self.0,
296 }
297 }
298}
299
300/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
301/// with the addition of hiding the text. Use [`OwoColorize`](OwoColorize::hidden).
302#[repr(transparent)]
303pub struct HiddenDisplay<'a, T: ?Sized>(pub &'a T);
304
305impl<'a, T: ?Sized> HiddenDisplay<'a, T> {
306 /// Convert self to a generic [`Styled`].
307 ///
308 /// This method erases color-related type parameters, and can be
309 /// used to unify types across branches.
310 ///
311 /// # Example
312 ///
313 /// ```rust
314 /// use owo_colors::OwoColorize;
315 ///
316 /// fn is_hidden() -> bool {
317 /// // ...
318 /// # true
319 /// }
320 ///
321 /// let styled_str = if is_hidden() {
322 /// "hello".hidden().into_styled()
323 /// } else {
324 /// "hello".blink().into_styled()
325 /// };
326 ///
327 /// println!("{}", styled_str);
328 /// # assert_eq!(styled_str.to_string(), "\x1b[8mhello\x1b[0m");
329 /// ```
330 pub const fn into_styled(self) -> Styled<&'a T> {
331 let style = Style::new().hidden();
332 Styled {
333 style,
334 target: self.0,
335 }
336 }
337}
338
339/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
340/// crossed out. Recommended to be constructed using
341/// [`OwoColorize`](OwoColorize::strikethrough).
342#[repr(transparent)]
343pub struct StrikeThroughDisplay<'a, T: ?Sized>(pub &'a T);
344
345impl<'a, T: ?Sized> StrikeThroughDisplay<'a, T> {
346 /// Convert self to a generic [`Styled`].
347 ///
348 /// This method erases color-related type parameters, and can be
349 /// used to unify types across branches.
350 ///
351 /// # Example
352 ///
353 /// ```rust
354 /// use owo_colors::OwoColorize;
355 ///
356 /// fn is_strike_through() -> bool {
357 /// // ...
358 /// # true
359 /// }
360 ///
361 /// let styled_str = if is_strike_through() {
362 /// "hello".strikethrough().into_styled()
363 /// } else {
364 /// "hello".hidden().into_styled()
365 /// };
366 ///
367 /// println!("{}", styled_str);
368 /// # assert_eq!(styled_str.to_string(), "\x1b[9mhello\x1b[0m");
369 /// ```
370 pub const fn into_styled(self) -> Styled<&'a T> {
371 let style = Style::new().strikethrough();
372 Styled {
373 style,
374 target: self.0,
375 }
376 }
377}
378
379impl_fmt_for_style! {
380 // Bold
381 (BoldDisplay, fmt::Display, "\x1b[1m"),
382 (BoldDisplay, fmt::Debug, "\x1b[1m"),
383 (BoldDisplay, fmt::UpperHex, "\x1b[1m"),
384 (BoldDisplay, fmt::LowerHex, "\x1b[1m"),
385 (BoldDisplay, fmt::Binary, "\x1b[1m"),
386 (BoldDisplay, fmt::UpperExp, "\x1b[1m"),
387 (BoldDisplay, fmt::LowerExp, "\x1b[1m"),
388 (BoldDisplay, fmt::Octal, "\x1b[1m"),
389 (BoldDisplay, fmt::Pointer, "\x1b[1m"),
390
391 // Dim
392 (DimDisplay, fmt::Display, "\x1b[2m"),
393 (DimDisplay, fmt::Debug, "\x1b[2m"),
394 (DimDisplay, fmt::UpperHex, "\x1b[2m"),
395 (DimDisplay, fmt::LowerHex, "\x1b[2m"),
396 (DimDisplay, fmt::Binary, "\x1b[2m"),
397 (DimDisplay, fmt::UpperExp, "\x1b[2m"),
398 (DimDisplay, fmt::LowerExp, "\x1b[2m"),
399 (DimDisplay, fmt::Octal, "\x1b[2m"),
400 (DimDisplay, fmt::Pointer, "\x1b[2m"),
401
402 // Italic
403 (ItalicDisplay, fmt::Display, "\x1b[3m"),
404 (ItalicDisplay, fmt::Debug, "\x1b[3m"),
405 (ItalicDisplay, fmt::UpperHex, "\x1b[3m"),
406 (ItalicDisplay, fmt::LowerHex, "\x1b[3m"),
407 (ItalicDisplay, fmt::Binary, "\x1b[3m"),
408 (ItalicDisplay, fmt::UpperExp, "\x1b[3m"),
409 (ItalicDisplay, fmt::LowerExp, "\x1b[3m"),
410 (ItalicDisplay, fmt::Octal, "\x1b[3m"),
411 (ItalicDisplay, fmt::Pointer, "\x1b[3m"),
412
413 // Underline
414 (UnderlineDisplay, fmt::Display, "\x1b[4m"),
415 (UnderlineDisplay, fmt::Debug, "\x1b[4m"),
416 (UnderlineDisplay, fmt::UpperHex, "\x1b[4m"),
417 (UnderlineDisplay, fmt::LowerHex, "\x1b[4m"),
418 (UnderlineDisplay, fmt::Binary, "\x1b[4m"),
419 (UnderlineDisplay, fmt::UpperExp, "\x1b[4m"),
420 (UnderlineDisplay, fmt::LowerExp, "\x1b[4m"),
421 (UnderlineDisplay, fmt::Octal, "\x1b[4m"),
422 (UnderlineDisplay, fmt::Pointer, "\x1b[4m"),
423
424 // Blink
425 (BlinkDisplay, fmt::Display, "\x1b[5m"),
426 (BlinkDisplay, fmt::Debug, "\x1b[5m"),
427 (BlinkDisplay, fmt::UpperHex, "\x1b[5m"),
428 (BlinkDisplay, fmt::LowerHex, "\x1b[5m"),
429 (BlinkDisplay, fmt::Binary, "\x1b[5m"),
430 (BlinkDisplay, fmt::UpperExp, "\x1b[5m"),
431 (BlinkDisplay, fmt::LowerExp, "\x1b[5m"),
432 (BlinkDisplay, fmt::Octal, "\x1b[5m"),
433 (BlinkDisplay, fmt::Pointer, "\x1b[5m"),
434
435 // Blink fast
436 (BlinkFastDisplay, fmt::Display, "\x1b[6m"),
437 (BlinkFastDisplay, fmt::Debug, "\x1b[6m"),
438 (BlinkFastDisplay, fmt::UpperHex, "\x1b[6m"),
439 (BlinkFastDisplay, fmt::LowerHex, "\x1b[6m"),
440 (BlinkFastDisplay, fmt::Binary, "\x1b[6m"),
441 (BlinkFastDisplay, fmt::UpperExp, "\x1b[6m"),
442 (BlinkFastDisplay, fmt::LowerExp, "\x1b[6m"),
443 (BlinkFastDisplay, fmt::Octal, "\x1b[6m"),
444 (BlinkFastDisplay, fmt::Pointer, "\x1b[6m"),
445
446 // Reverse video
447 (ReversedDisplay, fmt::Display, "\x1b[7m"),
448 (ReversedDisplay, fmt::Debug, "\x1b[7m"),
449 (ReversedDisplay, fmt::UpperHex, "\x1b[7m"),
450 (ReversedDisplay, fmt::LowerHex, "\x1b[7m"),
451 (ReversedDisplay, fmt::Binary, "\x1b[7m"),
452 (ReversedDisplay, fmt::UpperExp, "\x1b[7m"),
453 (ReversedDisplay, fmt::LowerExp, "\x1b[7m"),
454 (ReversedDisplay, fmt::Octal, "\x1b[7m"),
455 (ReversedDisplay, fmt::Pointer, "\x1b[7m"),
456
457 // Hide the text
458 (HiddenDisplay, fmt::Display, "\x1b[8m"),
459 (HiddenDisplay, fmt::Debug, "\x1b[8m"),
460 (HiddenDisplay, fmt::UpperHex, "\x1b[8m"),
461 (HiddenDisplay, fmt::LowerHex, "\x1b[8m"),
462 (HiddenDisplay, fmt::Binary, "\x1b[8m"),
463 (HiddenDisplay, fmt::UpperExp, "\x1b[8m"),
464 (HiddenDisplay, fmt::LowerExp, "\x1b[8m"),
465 (HiddenDisplay, fmt::Octal, "\x1b[8m"),
466 (HiddenDisplay, fmt::Pointer, "\x1b[8m"),
467
468 // StrikeThrough
469 (StrikeThroughDisplay, fmt::Display, "\x1b[9m"),
470 (StrikeThroughDisplay, fmt::Debug, "\x1b[9m"),
471 (StrikeThroughDisplay, fmt::UpperHex, "\x1b[9m"),
472 (StrikeThroughDisplay, fmt::LowerHex, "\x1b[9m"),
473 (StrikeThroughDisplay, fmt::Binary, "\x1b[9m"),
474 (StrikeThroughDisplay, fmt::UpperExp, "\x1b[9m"),
475 (StrikeThroughDisplay, fmt::LowerExp, "\x1b[9m"),
476 (StrikeThroughDisplay, fmt::Octal, "\x1b[9m"),
477 (StrikeThroughDisplay, fmt::Pointer, "\x1b[9m"),
478}