#![cfg_attr(not(test), no_std)]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![doc(html_logo_url = "https://jam1.re/img/rust_owo.svg")]
#![warn(missing_docs)]
pub mod colors;
mod combo;
mod dyn_colors;
mod dyn_styles;
pub mod styles;
#[cfg(feature = "supports-colors")]
mod overrides;
#[cfg(feature = "supports-colors")]
pub(crate) use overrides::OVERRIDE;
use core::fmt;
use core::marker::PhantomData;
pub trait Color {
const ANSI_FG: &'static str;
const ANSI_BG: &'static str;
const RAW_ANSI_FG: &'static str;
const RAW_ANSI_BG: &'static str;
#[doc(hidden)]
type DynEquivelant: DynColor;
#[doc(hidden)]
const DYN_EQUIVELANT: Self::DynEquivelant;
#[doc(hidden)]
fn into_dyncolors() -> crate::DynColors;
}
pub trait DynColor {
fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
#[doc(hidden)]
fn get_dyncolors_fg(&self) -> DynColors;
#[doc(hidden)]
fn get_dyncolors_bg(&self) -> DynColors;
}
#[repr(transparent)]
pub struct FgColorDisplay<'a, C: Color, T>(&'a T, PhantomData<C>);
#[repr(transparent)]
pub struct BgColorDisplay<'a, C: Color, T>(&'a T, PhantomData<C>);
pub struct FgDynColorDisplay<'a, Color: DynColor, T>(&'a T, Color);
pub struct BgDynColorDisplay<'a, Color: DynColor, T>(&'a T, Color);
macro_rules! style_methods {
($(#[$meta:meta] $name:ident $ty:ident),* $(,)?) => {
$(
#[$meta]
#[must_use]
#[inline(always)]
fn $name<'a>(&'a self) -> styles::$ty<'a, Self> {
styles::$ty(self)
}
)*
};
}
const _: () = ();
macro_rules! color_methods {
($(
#[$fg_meta:meta] #[$bg_meta:meta] $color:ident $fg_method:ident $bg_method:ident
),* $(,)?) => {
$(
#[$fg_meta]
#[must_use]
#[inline(always)]
fn $fg_method<'a>(&'a self) -> FgColorDisplay<'a, colors::$color, Self> {
FgColorDisplay(self, PhantomData)
}
#[$bg_meta]
#[must_use]
#[inline(always)]
fn $bg_method<'a>(&'a self) -> BgColorDisplay<'a, colors::$color, Self> {
BgColorDisplay(self, PhantomData)
}
)*
};
}
const _: () = ();
pub trait OwoColorize: Sized {
#[must_use]
#[inline(always)]
fn fg<C: Color>(&self) -> FgColorDisplay<'_, C, Self> {
FgColorDisplay(self, PhantomData)
}
#[must_use]
#[inline(always)]
fn bg<C: Color>(&self) -> BgColorDisplay<'_, C, Self> {
BgColorDisplay(self, PhantomData)
}
color_methods! {
Black black on_black,
Red red on_red,
Green green on_green,
Yellow yellow on_yellow,
Blue blue on_blue,
Magenta magenta on_magenta,
Magenta purple on_purple,
Cyan cyan on_cyan,
White white on_white,
Default default_color on_default_color,
BrightBlack bright_black on_bright_black,
BrightRed bright_red on_bright_red,
BrightGreen bright_green on_bright_green,
BrightYellow bright_yellow on_bright_yellow,
BrightBlue bright_blue on_bright_blue,
BrightMagenta bright_magenta on_bright_magenta,
BrightMagenta bright_purple on_bright_purple,
BrightCyan bright_cyan on_bright_cyan,
BrightWhite bright_white on_bright_white,
}
style_methods! {
bold BoldDisplay,
dimmed DimDisplay,
italic ItalicDisplay,
underline UnderlineDisplay,
blink BlinkDisplay,
blink_fast BlinkFastDisplay,
reversed ReversedDisplay,
hidden HiddenDisplay,
strikethrough StrikeThroughDisplay,
}
#[must_use]
#[inline(always)]
fn color<Color: DynColor>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self> {
FgDynColorDisplay(self, color)
}
#[must_use]
#[inline(always)]
fn on_color<Color: DynColor>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self> {
BgDynColorDisplay(self, color)
}
#[must_use]
fn fg_rgb<const R: u8, const G: u8, const B: u8>(
&self,
) -> FgColorDisplay<'_, colors::CustomColor<R, G, B>, Self> {
FgColorDisplay(self, PhantomData)
}
#[must_use]
fn bg_rgb<const R: u8, const G: u8, const B: u8>(
&self,
) -> BgColorDisplay<'_, colors::CustomColor<R, G, B>, Self> {
BgColorDisplay(self, PhantomData)
}
#[must_use]
#[inline(always)]
fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self> {
FgDynColorDisplay(self, Rgb(r, g, b))
}
#[must_use]
#[inline(always)]
fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self> {
BgDynColorDisplay(self, Rgb(r, g, b))
}
#[must_use]
fn style(&self, style: Style) -> Styled<&Self> {
style.style(self)
}
#[must_use]
#[cfg(feature = "supports-colors")]
fn if_supports_color<'a, Out, ApplyFn>(
&'a self,
stream: Stream,
apply: ApplyFn,
) -> SupportsColorsDisplay<'a, Self, Out, ApplyFn>
where
ApplyFn: Fn(&'a Self) -> Out,
{
SupportsColorsDisplay(self, apply, stream)
}
}
#[cfg(feature = "supports-colors")]
mod supports_colors;
#[cfg(feature = "supports-colors")]
pub use {
overrides::{set_override, unset_override},
supports_color::Stream,
supports_colors::SupportsColorsDisplay,
};
pub use colors::{
ansi_colors::AnsiColors, css::dynamic::CssColors, dynamic::Rgb, xterm::dynamic::XtermColors,
};
impl<D: Sized> OwoColorize for D {}
pub use {combo::ComboColorDisplay, dyn_colors::*, dyn_styles::*};
pub mod colored {
pub use crate::AnsiColors as Color;
pub use crate::OwoColorize;
#[cfg(feature = "supports-colors")]
pub mod control {
pub use crate::{set_override, unset_override};
}
}
#[cfg(test)]
mod tests;