mod ansi;
mod color;
mod colorize;
mod gradient;
mod style;
use ansi::*;
pub use color::*;
pub use colorize::*;
pub use gradient::*;
pub use style::*;
use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StyledText {
foreground_color_style: ColorStyle,
background_color_style: ColorStyle,
style: Style,
pub text: String,
}
impl StyledText {
#[inline]
pub fn new(text: &str) -> Self {
Self {
foreground_color_style: ColorStyle::Colorless,
background_color_style: ColorStyle::Colorless,
style: Style::new(),
text: text.to_string(),
}
}
#[inline]
pub fn foreground(&self) -> ColorStyle {
self.foreground_color_style
}
#[inline]
pub fn background(&self) -> ColorStyle {
self.background_color_style
}
pub fn styles(&self) -> Vec<StyleMode> {
self.style.styles()
}
#[inline]
fn with_foreground_color<C: Into<ColorStyle>>(&self, color: C) -> Self {
Self {
foreground_color_style: color.into(),
background_color_style: self.background_color_style,
style: self.style,
text: self.text.clone(),
}
}
#[inline]
fn with_background_color<C: Into<ColorStyle>>(&self, color: C) -> Self {
Self {
foreground_color_style: self.foreground_color_style,
background_color_style: color.into(),
style: self.style,
text: self.text.clone(),
}
}
fn with_style_mode(&self, mode: StyleMode) -> Self {
Self {
foreground_color_style: self.foreground_color_style,
background_color_style: self.background_color_style,
style: self.style.add_style_mode(mode),
text: self.text.clone(),
}
}
}
impl From<String> for StyledText {
fn from(s: String) -> Self {
StyledText::new(&s)
}
}
impl From<&str> for StyledText {
fn from(s: &str) -> Self {
StyledText::new(s)
}
}
impl fmt::Display for StyledText {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\x1B[{}m", self.style.ansi_code())?;
match (self.foreground_color_style, self.background_color_style) {
(ColorStyle::Single(fg), ColorStyle::Single(bg)) => {
write!(
f,
"\x1B[{};{}m{}\x1B[0m",
fg.ansi_color_code(TargetGround::Foreground),
bg.ansi_color_code(TargetGround::Background),
self.text
)
}
(ColorStyle::Single(fg), ColorStyle::Gradient(bg)) => {
write!(
f,
"\x1B[{}m{}",
fg.ansi_color_code(TargetGround::Foreground),
bg.build(&self.text, TargetGround::Background)
)
}
(ColorStyle::Single(fg), ColorStyle::Colorless) => {
write!(
f,
"\x1B[{}m{}\x1B[0m",
fg.ansi_color_code(TargetGround::Foreground),
self.text
)
}
(ColorStyle::Gradient(fg), ColorStyle::Single(bg)) => {
write!(
f,
"\x1B[{}m{}",
bg.ansi_color_code(TargetGround::Background),
fg.build(&self.text, TargetGround::Foreground)
)
}
(ColorStyle::Gradient(fg), ColorStyle::Gradient(bg)) => {
write!(f, "{}", build_all_gradient_text(&self.text, fg, bg))
}
(ColorStyle::Gradient(fg), ColorStyle::Colorless) => {
write!(f, "{}", fg.build(&self.text, TargetGround::Foreground))
}
(ColorStyle::Colorless, ColorStyle::Single(bg)) => {
write!(
f,
"\x1B[{}m{}\x1B[0m",
bg.ansi_color_code(TargetGround::Background),
self.text
)
}
(ColorStyle::Colorless, ColorStyle::Gradient(bg)) => {
write!(f, "{}", bg.build(&self.text, TargetGround::Background))
}
(ColorStyle::Colorless, ColorStyle::Colorless) => {
write!(f, "{}\x1B[0m", self.text)
}
}
}
}
pub trait ColorApply: Into<ColorStyle> {
fn to<C>(self, c: C) -> StyledText
where
C: Colorize + ?Sized,
{
c.fg::<Self>(self)
}
fn under<C>(self, c: C) -> StyledText
where
C: Colorize + ?Sized,
{
c.bg::<Self>(self)
}
}
impl ColorApply for RGB {}
impl ColorApply for HSL {}
impl ColorApply for Color {}
impl ColorApply for Gradient {}