kxxt_owo_colors/
lib.rs

1//! |**Quick Links**|[`OwoColorize`](OwoColorize)|[`Style`]|[`StyledList`]|[`github`](https://github.com/jam1garner/owo-colors)|
2//! |-|-|-|-|-|
3//!
4//! ---
5//!
6//! This crate provides [`OwoColorize`](OwoColorize), an extension trait for colorizing a
7//! given type.
8//!
9//! ## Example
10//!
11//! ```rust
12//! use owo_colors::OwoColorize;
13//!
14//! fn main() {
15//!     // Foreground colors
16//!     println!("My number is {:#x}!", 10.green());
17//!     // Background colors
18//!     println!("My number is not {}!", 4.on_red());
19//! }
20//! ```
21//!
22//! ## Generically color
23//!
24//! ```rust
25//! use owo_colors::OwoColorize;
26//! use owo_colors::colors::*;
27//!
28//! fn main() {
29//!     // Generically color
30//!     println!("My number might be {}!", 4.fg::<Black>().bg::<Yellow>());
31//! }
32//! ```
33//!
34//! ## Stylize
35//!
36//! ```rust
37//! use owo_colors::OwoColorize;
38//!
39//! println!("{}", "strikethrough".strikethrough());
40//! ```
41//!
42//! ## Only Style on Supported Terminals
43//!
44//! ```rust
45//! # #[cfg(feature = "supports-color")] {
46//! use owo_colors::{OwoColorize, Stream::Stdout};
47//!
48//! println!(
49//!     "{}",
50//!     "colored blue if a supported terminal"
51//!         .if_supports_color(Stdout, |text| text.bright_blue())
52//! );
53//! # }
54//! ```
55//!
56//! Supports `NO_COLOR`/`FORCE_COLOR` environment variables, checks if it's a tty, checks
57//! if it's running in CI (and thus likely supports color), and checks which terminal is being
58//! used. (Note: requires `supports-colors` feature)
59//!
60//! ## Style Objects
61//!
62//! owo-colors also features the ability to create a [`Style`] object and use it to
63//! apply the same set of colors/effects to any number of things to display.
64//!
65//! ```rust
66//! use owo_colors::{OwoColorize, Style};
67//!
68//! let my_style = Style::new()
69//!     .red()
70//!     .on_white()
71//!     .strikethrough();
72//!
73//! let text = "red text, white background, struck through";
74//! println!("{}", text.style(my_style));
75//! ```
76#![cfg_attr(all(not(test), not(feature = "global-colorized-control")), no_std)]
77#![cfg_attr(doc_cfg, feature(doc_cfg))]
78#![doc(html_logo_url = "https://jam1.re/img/rust_owo.svg")]
79#![warn(missing_docs)]
80
81pub mod colors;
82mod combo;
83#[cfg(feature = "global-colorized-control")]
84pub mod control;
85mod dyn_colors;
86mod dyn_styles;
87mod styled_list;
88pub mod styles;
89
90#[cfg(feature = "supports-colors")]
91mod overrides;
92
93#[cfg(feature = "supports-colors")]
94pub(crate) use overrides::OVERRIDE;
95
96use core::fmt;
97use core::marker::PhantomData;
98
99/// A trait for describing a type which can be used with [`FgColorDisplay`](FgColorDisplay) or
100/// [`BgColorDisplay`](BgColorDisplay)
101pub trait Color {
102    /// The ANSI format code for setting this color as the foreground
103    const ANSI_FG: &'static str;
104
105    /// The ANSI format code for setting this color as the background
106    const ANSI_BG: &'static str;
107
108    /// The raw ANSI format for settings this color as the foreground without the ANSI
109    /// delimiters ("\x1b" and "m")
110    const RAW_ANSI_FG: &'static str;
111
112    /// The raw ANSI format for settings this color as the background without the ANSI
113    /// delimiters ("\x1b" and "m")
114    const RAW_ANSI_BG: &'static str;
115
116    #[doc(hidden)]
117    type DynEquivalent: DynColor;
118
119    #[doc(hidden)]
120    const DYN_EQUIVALENT: Self::DynEquivalent;
121
122    #[doc(hidden)]
123    fn into_dyncolors() -> crate::DynColors;
124}
125
126/// A trait describing a runtime-configurable color which can displayed using [`FgDynColorDisplay`](FgDynColorDisplay)
127/// or [`BgDynColorDisplay`](BgDynColorDisplay). If your color will be known at compile time it
128/// is recommended you avoid this.
129pub trait DynColor {
130    /// A function to output a ANSI code to a formatter to set the foreground to this color
131    fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
132    /// A function to output a ANSI code to a formatter to set the background to this color
133    fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
134
135    /// A function to output a raw ANSI code to a formatter to set the foreground to this color,
136    /// but without including the ANSI delimiters.
137    fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
138
139    /// A function to output a raw ANSI code to a formatter to set the background to this color,
140    /// but without including the ANSI delimiters.
141    fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
142
143    #[doc(hidden)]
144    fn get_dyncolors_fg(&self) -> DynColors;
145    #[doc(hidden)]
146    fn get_dyncolors_bg(&self) -> DynColors;
147}
148
149/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
150/// with the addition of changing the foreground color. Recommended to be constructed using
151/// [`OwoColorize`](OwoColorize).
152#[repr(transparent)]
153pub struct FgColorDisplay<'a, C: Color, T>(&'a T, PhantomData<C>);
154
155/// Transparent wrapper around a type which implements all the formatters the wrapped type does,
156/// with the addition of changing the background color. Recommended to be constructed using
157/// [`OwoColorize`](OwoColorize).
158#[repr(transparent)]
159pub struct BgColorDisplay<'a, C: Color, T>(&'a T, PhantomData<C>);
160
161/// Wrapper around a type which implements all the formatters the wrapped type does,
162/// with the addition of changing the foreground color. Is not recommended unless compile-time
163/// coloring is not an option.
164pub struct FgDynColorDisplay<'a, Color: DynColor, T>(&'a T, Color);
165
166/// Wrapper around a type which implements all the formatters the wrapped type does,
167/// with the addition of changing the background color. Is not recommended unless compile-time
168/// coloring is not an option.
169pub struct BgDynColorDisplay<'a, Color: DynColor, T>(&'a T, Color);
170
171macro_rules! style_methods {
172    ($(#[$meta:meta] $name:ident $ty:ident),* $(,)?) => {
173        $(
174            #[$meta]
175            #[must_use]
176            #[inline(always)]
177            fn $name(&self) -> styles::$ty<'_, Self> {
178                styles::$ty(self)
179            }
180         )*
181    };
182}
183
184const _: () = (); // workaround for syntax highlighting bug
185
186macro_rules! color_methods {
187    ($(
188        #[$fg_meta:meta] #[$bg_meta:meta] $color:ident $fg_method:ident $bg_method:ident
189    ),* $(,)?) => {
190        $(
191            #[$fg_meta]
192            #[must_use]
193            #[inline(always)]
194            fn $fg_method(&self) -> FgColorDisplay<'_, colors::$color, Self> {
195                FgColorDisplay(self, PhantomData)
196            }
197
198            #[$bg_meta]
199            #[must_use]
200            #[inline(always)]
201            fn $bg_method(&self) -> BgColorDisplay<'_, colors::$color, Self> {
202                BgColorDisplay(self, PhantomData)
203            }
204         )*
205    };
206}
207
208const _: () = (); // workaround for syntax highlighting bug
209
210/// Extension trait for colorizing a type which implements any std formatter
211/// ([`Display`](core::fmt::Display), [`Debug`](core::fmt::Debug), [`UpperHex`](core::fmt::UpperHex),
212/// etc.)
213///
214/// ## Example
215///
216/// ```rust
217/// use owo_colors::OwoColorize;
218///
219/// println!("My number is {:#x}!", 10.green());
220/// println!("My number is not {}!", 4.on_red());
221/// ```
222///
223/// ## How to decide which method to use
224///
225/// **Do you have a specific color you want to use?**
226///
227/// Use the specific color's method, such as [`blue`](OwoColorize::blue) or
228/// [`on_green`](OwoColorize::on_green).
229///
230///
231/// **Do you want your colors configurable via generics?**
232///
233/// Use [`fg`](OwoColorize::fg) and [`bg`](OwoColorize::bg) to make it compile-time configurable.
234///
235///
236/// **Do you need to pick a color at runtime?**
237///
238/// Use the [`color`](OwoColorize::color), [`on_color`](OwoColorize::on_color),
239/// [`truecolor`](OwoColorize::truecolor) or [`on_truecolor`](OwoColorize::on_truecolor).
240///
241/// **Do you need some other text modifier?**
242///
243/// * [`bold`](OwoColorize::bold)
244/// * [`dimmed`](OwoColorize::dimmed)
245/// * [`italic`](OwoColorize::italic)
246/// * [`underline`](OwoColorize::underline)
247/// * [`blink`](OwoColorize::blink)
248/// * [`blink_fast`](OwoColorize::blink_fast)
249/// * [`reversed`](OwoColorize::reversed)
250/// * [`hidden`](OwoColorize::hidden)
251/// * [`strikethrough`](OwoColorize::strikethrough)
252///
253/// **Do you want it to only display colors if it's a terminal?**
254///
255/// 1. Enable the `supports-colors` feature
256/// 2. Colorize inside [`if_supports_color`](OwoColorize::if_supports_color)
257///
258/// **Do you need to store a set of colors/effects to apply to multiple things?**
259///
260/// Use [`style`](OwoColorize::style) to apply a [`Style`]
261///
262pub trait OwoColorize: Sized {
263    /// Set the foreground color generically
264    ///
265    /// ```rust
266    /// use owo_colors::{OwoColorize, colors::*};
267    ///
268    /// println!("{}", "red foreground".fg::<Red>());
269    /// ```
270    #[must_use]
271    #[inline(always)]
272    fn fg<C: Color>(&self) -> FgColorDisplay<'_, C, Self> {
273        FgColorDisplay(self, PhantomData)
274    }
275
276    /// Set the background color generically.
277    ///
278    /// ```rust
279    /// use owo_colors::{OwoColorize, colors::*};
280    ///
281    /// println!("{}", "black background".bg::<Black>());
282    /// ```
283    #[must_use]
284    #[inline(always)]
285    fn bg<C: Color>(&self) -> BgColorDisplay<'_, C, Self> {
286        BgColorDisplay(self, PhantomData)
287    }
288
289    color_methods! {
290        /// Change the foreground color to black
291        /// Change the background color to black
292        Black    black    on_black,
293        /// Change the foreground color to red
294        /// Change the background color to red
295        Red      red      on_red,
296        /// Change the foreground color to green
297        /// Change the background color to green
298        Green    green    on_green,
299        /// Change the foreground color to yellow
300        /// Change the background color to yellow
301        Yellow   yellow   on_yellow,
302        /// Change the foreground color to blue
303        /// Change the background color to blue
304        Blue     blue     on_blue,
305        /// Change the foreground color to magenta
306        /// Change the background color to magenta
307        Magenta  magenta  on_magenta,
308        /// Change the foreground color to purple
309        /// Change the background color to purple
310        Magenta  purple   on_purple,
311        /// Change the foreground color to cyan
312        /// Change the background color to cyan
313        Cyan     cyan     on_cyan,
314        /// Change the foreground color to white
315        /// Change the background color to white
316        White    white    on_white,
317
318        /// Change the foreground color to the terminal default
319        /// Change the background color to the terminal default
320        Default default_color on_default_color,
321
322        /// Change the foreground color to bright black
323        /// Change the background color to bright black
324        BrightBlack    bright_black    on_bright_black,
325        /// Change the foreground color to bright red
326        /// Change the background color to bright red
327        BrightRed      bright_red      on_bright_red,
328        /// Change the foreground color to bright green
329        /// Change the background color to bright green
330        BrightGreen    bright_green    on_bright_green,
331        /// Change the foreground color to bright yellow
332        /// Change the background color to bright yellow
333        BrightYellow   bright_yellow   on_bright_yellow,
334        /// Change the foreground color to bright blue
335        /// Change the background color to bright blue
336        BrightBlue     bright_blue     on_bright_blue,
337        /// Change the foreground color to bright magenta
338        /// Change the background color to bright magenta
339        BrightMagenta  bright_magenta  on_bright_magenta,
340        /// Change the foreground color to bright purple
341        /// Change the background color to bright purple
342        BrightMagenta  bright_purple   on_bright_purple,
343        /// Change the foreground color to bright cyan
344        /// Change the background color to bright cyan
345        BrightCyan     bright_cyan     on_bright_cyan,
346        /// Change the foreground color to bright white
347        /// Change the background color to bright white
348        BrightWhite    bright_white    on_bright_white,
349    }
350
351    style_methods! {
352        /// Make the text bold
353        bold BoldDisplay,
354        /// Make the text dim
355        dimmed DimDisplay,
356        /// Make the text italicized
357        italic ItalicDisplay,
358        /// Make the text underlined
359        underline UnderlineDisplay,
360        /// Make the text blink
361        blink BlinkDisplay,
362        /// Make the text blink (but fast!)
363        blink_fast BlinkFastDisplay,
364        /// Swap the foreground and background colors
365        reversed ReversedDisplay,
366        /// Hide the text
367        hidden HiddenDisplay,
368        /// Cross out the text
369        strikethrough StrikeThroughDisplay,
370    }
371
372    /// Set the foreground color at runtime. Only use if you do not know which color will be used at
373    /// compile-time. If the color is constant, use either [`OwoColorize::fg`](OwoColorize::fg) or
374    /// a color-specific method, such as [`OwoColorize::green`](OwoColorize::green),
375    ///
376    /// ```rust
377    /// use owo_colors::{OwoColorize, AnsiColors};
378    ///
379    /// println!("{}", "green".color(AnsiColors::Green));
380    /// ```
381    #[must_use]
382    #[inline(always)]
383    fn color<Color: DynColor>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self> {
384        FgDynColorDisplay(self, color)
385    }
386
387    /// Set the background color at runtime. Only use if you do not know what color to use at
388    /// compile-time. If the color is constant, use either [`OwoColorize::bg`](OwoColorize::bg) or
389    /// a color-specific method, such as [`OwoColorize::on_yellow`](OwoColorize::on_yellow),
390    ///
391    /// ```rust
392    /// use owo_colors::{OwoColorize, AnsiColors};
393    ///
394    /// println!("{}", "yellow background".on_color(AnsiColors::BrightYellow));
395    /// ```
396    #[must_use]
397    #[inline(always)]
398    fn on_color<Color: DynColor>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self> {
399        BgDynColorDisplay(self, color)
400    }
401
402    /// Set the foreground color to a specific RGB value.
403    #[must_use]
404    fn fg_rgb<const R: u8, const G: u8, const B: u8>(
405        &self,
406    ) -> FgColorDisplay<'_, colors::CustomColor<R, G, B>, Self> {
407        FgColorDisplay(self, PhantomData)
408    }
409
410    /// Set the background color to a specific RGB value.
411    #[must_use]
412    fn bg_rgb<const R: u8, const G: u8, const B: u8>(
413        &self,
414    ) -> BgColorDisplay<'_, colors::CustomColor<R, G, B>, Self> {
415        BgColorDisplay(self, PhantomData)
416    }
417
418    /// Sets the foreground color to an RGB value.
419    #[must_use]
420    #[inline(always)]
421    fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self> {
422        FgDynColorDisplay(self, Rgb(r, g, b))
423    }
424
425    /// Sets the background color to an RGB value.
426    #[must_use]
427    #[inline(always)]
428    fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self> {
429        BgDynColorDisplay(self, Rgb(r, g, b))
430    }
431
432    /// Apply a runtime-determined style
433    #[must_use]
434    fn style(&self, style: Style) -> Styled<&Self> {
435        style.style(self)
436    }
437
438    /// Apply a given transformation function to all formatters if the given stream
439    /// supports at least basic ANSI colors, allowing you to conditionally apply
440    /// given styles/colors.
441    ///
442    /// Requires the `supports-colors` feature.
443    ///
444    /// ```rust
445    /// use owo_colors::{Stream, OwoColorize};
446    ///
447    /// println!(
448    ///     "{}",
449    ///     "woah! error! if this terminal supports colors, it's blue"
450    ///         .if_supports_color(Stream::Stdout, |text| text.bright_blue())
451    /// );
452    /// ```
453    ///
454    /// This function also accepts `supports_color` version 2's `Stream`, and also the deprecated
455    /// `supports_color` version 1's `Stream`.
456    ///
457    /// ```rust
458    /// use owo_colors::OwoColorize;
459    /// #[cfg(feature = "supports-colors")]
460    /// use supports_color::Stream;
461    ///
462    /// println!(
463    ///    "{}",
464    ///    "woah! error! if this terminal supports colors, it's blue"
465    ///       .if_supports_color(Stream::Stdout, |text| text.bright_blue())
466    /// );
467    #[must_use]
468    #[cfg(feature = "supports-colors")]
469    fn if_supports_color<'a, Out, ApplyFn>(
470        &'a self,
471        stream: impl Into<Stream>,
472        apply: ApplyFn,
473    ) -> SupportsColorsDisplay<'a, Self, Out, ApplyFn>
474    where
475        ApplyFn: Fn(&'a Self) -> Out,
476    {
477        SupportsColorsDisplay(self, apply, stream.into())
478    }
479}
480
481#[cfg(feature = "supports-colors")]
482mod supports_colors;
483
484#[cfg(feature = "supports-colors")]
485pub use {
486    overrides::{set_override, unset_override, with_override},
487    supports_colors::SupportsColorsDisplay,
488};
489
490#[cfg(feature = "supports-colors")]
491#[doc(no_inline)]
492pub use supports_colors::Stream;
493
494pub use colors::{
495    ansi_colors::AnsiColors, css::dynamic::CssColors, dynamic::Rgb, xterm::dynamic::XtermColors,
496};
497
498// TODO: figure out some wait to only implement for fmt::Display | fmt::Debug | ...
499impl<D: Sized> OwoColorize for D {}
500
501pub use {combo::ComboColorDisplay, dyn_colors::*, dyn_styles::*};
502
503/// Module for drop-in [`colored`](https://docs.rs/colored) support to aid in porting code from
504/// [`colored`](https://docs.rs/colored) to owo-colors.
505///
506/// Just replace:
507///
508/// ```rust
509/// # mod colored {}
510/// use colored::*;
511/// ```
512///
513/// with
514///
515/// ```rust
516/// use owo_colors::colored::*;
517/// ```
518pub mod colored {
519    pub use crate::AnsiColors as Color;
520    pub use crate::OwoColorize;
521
522    /// A couple of functions to enable and disable coloring similarly to `colored`
523    #[cfg(feature = "supports-colors")]
524    pub mod control {
525        pub use crate::{set_override, unset_override};
526    }
527}
528
529pub use styled_list::StyledList;
530#[cfg(feature = "alloc")]
531pub use styled_list::StyledVec;
532
533#[cfg(test)]
534mod tests;