#![cfg_attr(not(test), no_std)]
#![doc(html_logo_url = "https://jam1.re/img/rust_owo.svg")]
#![warn(missing_docs)]
use core::fmt;
use core::marker::PhantomData;
pub trait Color {
const ANSI_FG: &'static str;
const ANSI_BG: &'static str;
#[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;
#[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! color_methods {
($(
#[$fg_meta:meta] #[$bg_meta:meta] $color:ident $fg_method:ident $bg_method:ident
),* $(,)?) => {
$(
#[$fg_meta]
#[inline(always)]
fn $fg_method<'a>(&'a self) -> FgColorDisplay<'a, colors::$color, Self> {
FgColorDisplay(self, PhantomData)
}
#[$fg_meta]
#[inline(always)]
fn $bg_method<'a>(&'a self) -> BgColorDisplay<'a, colors::$color, Self> {
BgColorDisplay(self, PhantomData)
}
)*
};
}
macro_rules! style_methods {
($(#[$meta:meta] $name:ident $ty:ident),* $(,)?) => {
$(
#[$meta]
#[inline(always)]
fn $name<'a>(&'a self) -> styles::$ty<'a, Self> {
styles::$ty(self)
}
)*
};
}
pub trait OwoColorize: Sized {
#[inline(always)]
fn fg<'a, C: Color>(&'a self) -> FgColorDisplay<'a, C, Self> {
FgColorDisplay(self, PhantomData)
}
#[inline(always)]
fn bg<'a, C: Color>(&'a self) -> BgColorDisplay<'a, 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,
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,
}
#[inline(always)]
fn color<'a, Color: DynColor>(&'a self, color: Color) -> FgDynColorDisplay<'a, Color, Self> {
FgDynColorDisplay(self, color)
}
#[inline(always)]
fn on_color<'a, Color: DynColor>(&'a self, color: Color) -> BgDynColorDisplay<'a, Color, Self> {
BgDynColorDisplay(self, color)
}
fn fg_rgb<'a, const R: u8, const G: u8, const B: u8>(
&'a self,
) -> FgColorDisplay<'a, colors::CustomColor<R, G, B>, Self> {
FgColorDisplay(self, PhantomData)
}
fn bg_rgb<'a, const R: u8, const G: u8, const B: u8>(
&'a self,
) -> BgColorDisplay<'a, colors::CustomColor<R, G, B>, Self> {
BgColorDisplay(self, PhantomData)
}
#[inline(always)]
fn truecolor<'a>(&'a self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'a, Rgb, Self> {
FgDynColorDisplay(self, Rgb(r, g, b))
}
#[inline(always)]
fn on_truecolor<'a>(&'a self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'a, Rgb, Self> {
BgDynColorDisplay(self, Rgb(r, g, b))
}
fn style(&self, style: Style) -> Styled<&Self> {
style.style(self)
}
#[cfg(feature = "tty")]
fn if_stdout_tty<'a, Out, ApplyFn>(
&'a self,
apply: ApplyFn,
) -> TtyDisplay<'a, StdOut, Self, Out, ApplyFn>
where
ApplyFn: Fn(&'a Self) -> Out,
{
TtyDisplay(self, apply, StdOut)
}
#[cfg(feature = "tty")]
fn if_stderr_tty<'a, Out, ApplyFn>(
&'a self,
apply: ApplyFn,
) -> TtyDisplay<'a, StdErr, Self, Out, ApplyFn>
where
ApplyFn: Fn(&'a Self) -> Out,
{
TtyDisplay(self, apply, StdErr)
}
}
pub use colors::{
ansi_colors::AnsiColors, css::dynamic::CssColors, dynamic::Rgb, xterm::dynamic::XtermColors,
};
impl<D: Sized> OwoColorize for D {}
mod dyn_colors;
pub use dyn_colors::*;
mod dyn_styles;
pub use dyn_styles::*;
#[cfg(feature = "tty")]
mod tty_display;
#[cfg(feature = "tty")]
pub use tty_display::TtyDisplay;
#[cfg(feature = "tty")]
use tty_display::{StdErr, StdOut};
pub mod colors;
pub mod styles;
pub mod colored {
pub use crate::AnsiColors as Color;
pub use crate::OwoColorize;
}
#[cfg(test)]
mod tests;