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