use std::fmt;
#[derive(Clone, Copy)]
pub enum Color {
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
BrightBlack,
BrightRed,
BrightGreen,
BrightYellow,
BrightBlue,
BrightMagenta,
BrightCyan,
BrightWhite,
Rgb(u8, u8, u8),
Color256(u8),
Hex(u32),
}
impl Color {
fn to_ansi_code(self) -> String {
match self {
Color::Black => "30",
Color::Red => "31",
Color::Green => "32",
Color::Yellow => "33",
Color::Blue => "34",
Color::Magenta => "35",
Color::Cyan => "36",
Color::White => "37",
Color::BrightBlack => "90",
Color::BrightRed => "91",
Color::BrightGreen => "92",
Color::BrightYellow => "93",
Color::BrightBlue => "94",
Color::BrightMagenta => "95",
Color::BrightCyan => "96",
Color::BrightWhite => "97",
Color::Rgb(r, g, b) => return format!("38;2;{};{};{}", r, g, b),
Color::Color256(c) => return format!("38;5;{}", c),
Color::Hex(h) => {
let r = (h >> 16) as u8;
let g = ((h >> 8) & 0xFF) as u8;
let b = (h & 0xFF) as u8;
println!("{} {} {}", r, g, b);
return format!("38;2;{};{};{}", r, g, b);
}
}
.to_string()
}
fn to_bg_ansi_code(self) -> String {
match self {
Color::Rgb(r, g, b) => format!("48;2;{};{};{}", r, g, b),
Color::Color256(c) => format!("48;5;{}", c),
Color::Hex(h) => {
let r = (h >> 16) as u8;
let g = ((h >> 8) & 0xFF) as u8;
let b = (h & 0xFF) as u8;
format!("48;2;{};{};{}", r, g, b)
}
_ => (self.to_ansi_code().parse::<u8>().unwrap_or(30) + 10).to_string(),
}
}
}
#[derive(Clone, Copy)]
pub enum Style {
Bold = 1,
Dim = 2,
Italic = 3,
Underline = 4,
Blink = 5,
Reverse = 7,
Hidden = 8,
Strikethrough = 9,
}
impl Style {
fn to_ansi_code(self) -> String {
match self {
Style::Bold => "1",
Style::Dim => "2",
Style::Italic => "3",
Style::Underline => "4",
Style::Blink => "5",
Style::Reverse => "7",
Style::Hidden => "8",
Style::Strikethrough => "9",
}
.to_string()
}
}
pub struct CLW {
value: String,
bg: Option<Color>,
text: Option<Color>,
font: Vec<Style>,
}
impl CLW {
fn new<S: Into<String>>(value: S) -> Self {
CLW {
value: value.into(),
text: None,
bg: None,
font: Vec::new(),
}
}
pub fn text(mut self, color: Color) -> Self {
self.text = Some(color);
self
}
pub fn bg(mut self, color: Color) -> Self {
self.bg = Some(color);
self
}
pub fn font(mut self, style: Style) -> Self {
self.font.push(style);
self
}
pub fn text_black(self) -> Self {
self.text(Color::Black)
}
pub fn text_red(self) -> Self {
self.text(Color::Red)
}
pub fn text_green(self) -> Self {
self.text(Color::Green)
}
pub fn text_yellow(self) -> Self {
self.text(Color::Yellow)
}
pub fn text_blue(self) -> Self {
self.text(Color::Blue)
}
pub fn text_magenta(self) -> Self {
self.text(Color::Magenta)
}
pub fn text_cyan(self) -> Self {
self.text(Color::Cyan)
}
pub fn text_white(self) -> Self {
self.text(Color::White)
}
pub fn text_bright_black(self) -> Self {
self.text(Color::BrightBlack)
}
pub fn text_bright_red(self) -> Self {
self.text(Color::BrightRed)
}
pub fn text_bright_green(self) -> Self {
self.text(Color::BrightGreen)
}
pub fn text_bright_yellow(self) -> Self {
self.text(Color::BrightYellow)
}
pub fn text_bright_blue(self) -> Self {
self.text(Color::BrightBlue)
}
pub fn text_bright_magenta(self) -> Self {
self.text(Color::BrightMagenta)
}
pub fn text_bright_cyan(self) -> Self {
self.text(Color::BrightCyan)
}
pub fn text_bright_white(self) -> Self {
self.text(Color::BrightWhite)
}
pub fn bg_black(self) -> Self {
self.bg(Color::Black)
}
pub fn bg_red(self) -> Self {
self.bg(Color::Red)
}
pub fn bg_green(self) -> Self {
self.bg(Color::Green)
}
pub fn bg_yellow(self) -> Self {
self.bg(Color::Yellow)
}
pub fn bg_blue(self) -> Self {
self.bg(Color::Blue)
}
pub fn bg_magenta(self) -> Self {
self.bg(Color::Magenta)
}
pub fn bg_cyan(self) -> Self {
self.bg(Color::Cyan)
}
pub fn bg_white(self) -> Self {
self.bg(Color::White)
}
pub fn bg_bright_black(self) -> Self {
self.bg(Color::BrightBlack)
}
pub fn bg_bright_red(self) -> Self {
self.bg(Color::BrightRed)
}
pub fn bg_bright_green(self) -> Self {
self.bg(Color::BrightGreen)
}
pub fn bg_bright_yellow(self) -> Self {
self.bg(Color::BrightYellow)
}
pub fn bg_bright_blue(self) -> Self {
self.bg(Color::BrightBlue)
}
pub fn bg_bright_magenta(self) -> Self {
self.bg(Color::BrightMagenta)
}
pub fn bg_bright_cyan(self) -> Self {
self.bg(Color::BrightCyan)
}
pub fn bg_bright_white(self) -> Self {
self.bg(Color::BrightWhite)
}
pub fn font_bold(self) -> Self {
self.font(Style::Bold)
}
pub fn font_dim(self) -> Self {
self.font(Style::Dim)
}
pub fn font_italic(self) -> Self {
self.font(Style::Italic)
}
pub fn font_underline(self) -> Self {
self.font(Style::Underline)
}
pub fn font_blink(self) -> Self {
self.font(Style::Blink)
}
pub fn font_reverse(self) -> Self {
self.font(Style::Reverse)
}
pub fn font_hidden(self) -> Self {
self.font(Style::Hidden)
}
pub fn font_strikethrough(self) -> Self {
self.font(Style::Strikethrough)
}
pub fn print(&self) {
print!("{}", self);
}
pub fn println(&self) {
println!("{}", self);
}
pub fn eprint(&self) {
eprint!("{}", self);
}
pub fn eprintln(&self) {
eprintln!("{}", self);
}
}
impl fmt::Display for CLW {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut codes = Vec::new();
if let Some(color) = self.text {
codes.push(color.to_ansi_code());
}
if let Some(color) = self.bg {
codes.push(color.to_bg_ansi_code());
}
for style in &self.font {
codes.push(style.to_ansi_code());
}
match codes.len() {
0 => write!(f, "{}", self.value),
_ => write!(f, "\x1b[{}m{}\x1b[0m", codes.join(";"), self.value),
}
}
}
pub fn clw(str: &str) -> CLW {
CLW::new(str)
}