pub trait Colorize {
fn black(&self) -> String;
fn gray(&self) -> String;
fn red(&self) -> String;
fn bright_red(&self) -> String;
fn blue(&self) -> String;
fn bright_blue(&self) -> String;
fn green(&self) -> String;
fn bright_green(&self) -> String;
fn yellow(&self) -> String;
fn bright_yellow(&self) -> String;
fn magenta(&self) -> String;
fn bright_magenta(&self) -> String;
fn cyan(&self) -> String;
fn bright_cyan(&self) -> String;
fn white(&self) -> String;
fn bright_white(&self) -> String;
fn bg_black(&self) -> String;
fn bg_gray(&self) -> String;
fn bg_red(&self) -> String;
fn bg_bright_red(&self) -> String;
fn bg_green(&self) -> String;
fn bg_bright_green(&self) -> String;
fn bg_yellow(&self) -> String;
fn bg_bright_yellow(&self) -> String;
fn bg_blue(&self) -> String;
fn bg_bright_blue(&self) -> String;
fn bg_magenta(&self) -> String;
fn bg_bright_magenta(&self) -> String;
fn bg_cyan(&self) -> String;
fn bg_bright_cyan(&self) -> String;
fn bg_white(&self) -> String;
fn bg_bright_white(&self) -> String;
fn fg_rgb(&self, r: u8, g: u8, b: u8) -> String;
fn bg_rgb(&self, r: u8, g: u8, b: u8) -> String;
fn fg_hex(&self, hex_color: &str) -> String;
fn bg_hex(&self, hex_color: &str) -> String;
fn fg_gradient(&self, from: (u8, u8, u8), to: (u8, u8, u8)) -> String;
fn bg_gradient(&self, from: (u8, u8, u8), to: (u8, u8, u8)) -> String;
fn fg_hex_gradient(&self, from: &str, to: &str) -> String;
fn bg_hex_gradient(&self, from: &str, to: &str) -> String;
fn clear(&self) -> String;
fn bold(&self) -> String;
fn faint(&self) -> String;
fn italic(&self) -> String;
fn underline(&self) -> String;
fn blink(&self) -> String;
fn invert(&self) -> String;
fn hide(&self) -> String;
fn fg_default(&self) -> String;
fn bg_default(&self) -> String;
fn overline(&self) -> String;
fn remove_weight(&self) -> String;
fn remove_underline(&self) -> String;
fn remove_blink(&self) -> String;
fn reveal(&self) -> String;
}
impl<T> Colorize for T
where
T: std::fmt::Display,
{
fn black(&self) -> String {
format!("\x1B[30m{}\x1B[0m", self)
}
fn gray(&self) -> String {
format!("\x1B[90m{}\x1B[0m", self)
}
fn red(&self) -> String {
format!("\x1B[31m{}\x1B[0m", self)
}
fn bright_red(&self) -> String {
format!("\x1B[91m{}\x1B[0m", self)
}
fn blue(&self) -> String {
format!("\x1B[34m{}\x1B[0m", self)
}
fn bright_blue(&self) -> String {
format!("\x1B[94m{}\x1B[0m", self)
}
fn green(&self) -> String {
format!("\x1B[32m{}\x1B[0m", self)
}
fn bright_green(&self) -> String {
format!("\x1B[92m{}\x1B[0m", self)
}
fn yellow(&self) -> String {
format!("\x1B[33m{}\x1B[0m", self)
}
fn bright_yellow(&self) -> String {
format!("\x1B[93m{}\x1B[0m", self)
}
fn magenta(&self) -> String {
format!("\x1B[35m{}\x1B[0m", self)
}
fn bright_magenta(&self) -> String {
format!("\x1B[95m{}\x1B[0m", self)
}
fn cyan(&self) -> String {
format!("\x1B[36m{}\x1B[0m", self)
}
fn bright_cyan(&self) -> String {
format!("\x1B[96m{}\x1B[0m", self)
}
fn white(&self) -> String {
format!("\x1B[37m{}\x1B[0m", self)
}
fn bright_white(&self) -> String {
format!("\x1B[97m{}\x1B[0m", self)
}
fn bg_black(&self) -> String {
format!("\x1B[40m{}\x1B[0m", self)
}
fn bg_gray(&self) -> String {
format!("\x1B[100m{}\x1B[0m", self)
}
fn bg_red(&self) -> String {
format!("\x1B[41m{}\x1B[0m", self)
}
fn bg_bright_red(&self) -> String {
format!("\x1B[101m{}\x1B[0m", self)
}
fn bg_green(&self) -> String {
format!("\x1B[42m{}\x1B[0m", self)
}
fn bg_bright_green(&self) -> String {
format!("\x1B[102m{}\x1B[0m", self)
}
fn bg_yellow(&self) -> String {
format!("\x1B[43m{}\x1B[0m", self)
}
fn bg_bright_yellow(&self) -> String {
format!("\x1B[103m{}\x1B[0m", self)
}
fn bg_blue(&self) -> String {
format!("\x1B[44m{}\x1B[0m", self)
}
fn bg_bright_blue(&self) -> String {
format!("\x1B[104m{}\x1B[0m", self)
}
fn bg_magenta(&self) -> String {
format!("\x1B[45m{}\x1B[0m", self)
}
fn bg_bright_magenta(&self) -> String {
format!("\x1B[105m{}\x1B[0m", self)
}
fn bg_cyan(&self) -> String {
format!("\x1B[46m{}\x1B[0m", self)
}
fn bg_bright_cyan(&self) -> String {
format!("\x1B[106m{}\x1B[0m", self)
}
fn bg_white(&self) -> String {
format!("\x1B[47m{}\x1B[0m", self)
}
fn bg_bright_white(&self) -> String {
format!("\x1B[107m{}\x1B[0m", self)
}
fn clear(&self) -> String {
format!("\x1B[0m{}", self)
}
fn bold(&self) -> String {
format!("\x1B[1m{}\x1B[22m\x1B[0m", self)
}
fn faint(&self) -> String {
format!("\x1B[2m{}\x1B[22m\x1B[0m", self)
}
fn italic(&self) -> String {
format!("\x1B[3m{}\x1B[23m\x1B[0m", self)
}
fn underline(&self) -> String {
format!("\x1B[4m{}\x1B[24m\x1B[0m", self)
}
fn blink(&self) -> String {
format!("\x1B[5m{}\x1B[25m\x1B[0m", self)
}
fn invert(&self) -> String {
format!("\x1B[7m{}\x1B[27m\x1B[0m", self)
}
fn hide(&self) -> String {
format!("\x1B[8m{}\x1B[28m\x1B[0m", self)
}
fn reveal(&self) -> String {
self.hide()
}
fn remove_weight(&self) -> String {
format!("\x1B[22m{}", self)
}
fn remove_underline(&self) -> String {
format!("\x1B[24m{}", self)
}
fn remove_blink(&self) -> String {
format!("\x1B[25m{}", self)
}
fn fg_default(&self) -> String {
format!("\x1B[39m{}", self)
}
fn bg_default(&self) -> String {
format!("\x1B[49m{}", self)
}
fn overline(&self) -> String {
format!("\x1B[53m{}\x1B[55m", self)
}
fn fg_rgb(&self, r: u8, g: u8, b: u8) -> String {
format!("\x1B[38;2;{};{};{}m{}\x1B[39m", r, g, b, self)
}
fn bg_rgb(&self, r: u8, g: u8, b: u8) -> String {
format!("\x1B[48;2;{};{};{}m{}\x1B[49m", r, g, b, self)
}
fn fg_hex(&self, hex: &str) -> String {
let (r, g, b) = hex_to_rgb(hex).unwrap_or((0, 0, 0));
format!("\x1B[38;2;{};{};{}m{}\x1B[39m", r, g, b, self)
}
fn bg_hex(&self, hex: &str) -> String {
let (r, g, b) = hex_to_rgb(hex).unwrap_or((0, 0, 0));
format!("\x1B[48;2;{};{};{}m{}\x1B[49m", r, g, b, self)
}
fn fg_gradient(&self, from: (u8, u8, u8), to: (u8, u8, u8)) -> String {
let mut result = String::new();
let steps = self.to_string().len();
let mut colors = vec![];
for i in 0..steps {
let r = from.0 as i32 + i as i32 * (to.0 as i32 - from.0 as i32) / (steps - 1) as i32;
let g = from.1 as i32 + i as i32 * (to.1 as i32 - from.1 as i32) / (steps - 1) as i32;
let b = from.2 as i32 + i as i32 * (to.2 as i32 - from.2 as i32) / (steps - 1) as i32;
colors.push((r as u8, g as u8, b as u8));
}
for (i, c) in self.to_string().chars().enumerate() {
let (r, g, b) = colors.get(i).unwrap();
result.push_str(&c.fg_rgb(*r, *g, *b));
}
result
}
fn bg_gradient(&self, from: (u8, u8, u8), to: (u8, u8, u8)) -> String {
let mut result = String::new();
let steps = self.to_string().len();
let mut colors = vec![];
for i in 0..steps {
let r = from.0 as i32 + i as i32 * (to.0 as i32 - from.0 as i32) / (steps - 1) as i32;
let g = from.1 as i32 + i as i32 * (to.1 as i32 - from.1 as i32) / (steps - 1) as i32;
let b = from.2 as i32 + i as i32 * (to.2 as i32 - from.2 as i32) / (steps - 1) as i32;
colors.push((r as u8, g as u8, b as u8));
}
for (i, c) in self.to_string().chars().enumerate() {
let (r, g, b) = colors.get(i).unwrap();
result.push_str(&c.bg_rgb(*r, *g, *b));
}
result
}
fn fg_hex_gradient(&self, from: &str, to: &str) -> String {
let from = hex_to_rgb(from).unwrap();
let to = hex_to_rgb(to).unwrap();
let mut result = String::new();
let steps = self.to_string().len();
let mut colors = vec![];
for i in 0..steps {
let r = from.0 as i32 + i as i32 * (to.0 as i32 - from.0 as i32) / (steps - 1) as i32;
let g = from.1 as i32 + i as i32 * (to.1 as i32 - from.1 as i32) / (steps - 1) as i32;
let b = from.2 as i32 + i as i32 * (to.2 as i32 - from.2 as i32) / (steps - 1) as i32;
colors.push((r as u8, g as u8, b as u8));
}
for (i, c) in self.to_string().chars().enumerate() {
let (r, g, b) = colors.get(i).unwrap();
result.push_str(&c.fg_rgb(*r, *g, *b));
}
result
}
fn bg_hex_gradient(&self, from: &str, to: &str) -> String {
let from = hex_to_rgb(from).unwrap();
let to = hex_to_rgb(to).unwrap();
let mut result = String::new();
let steps = self.to_string().len();
let mut colors = vec![];
for i in 0..steps {
let r = from.0 as i32 + i as i32 * (to.0 as i32 - from.0 as i32) / (steps - 1) as i32;
let g = from.1 as i32 + i as i32 * (to.1 as i32 - from.1 as i32) / (steps - 1) as i32;
let b = from.2 as i32 + i as i32 * (to.2 as i32 - from.2 as i32) / (steps - 1) as i32;
colors.push((r as u8, g as u8, b as u8));
}
for (i, c) in self.to_string().chars().enumerate() {
let (r, g, b) = colors.get(i).unwrap();
result.push_str(&c.bg_rgb(*r, *g, *b));
}
result
}
}
fn hex_to_rgb(hex_color: &str) -> Option<(u8, u8, u8)> {
let hex = hex_color.trim_start_matches('#');
if hex.len() != 6 {
return None;
}
let mut rgb = [0u8; 3];
for i in 0..3 {
match u8::from_str_radix(&hex[i * 2..i * 2 + 2], 16) {
Ok(val) => rgb[i] = val,
Err(_) => return None,
}
}
Some((rgb[0], rgb[1], rgb[2]))
}