use crate::cell::Cell;
use regex::Regex;
use std::str;
pub trait Colorizer {
fn color(&self, hex: &str) -> Cell;
fn bg(&self, hex: &str) -> Cell;
fn font(&self, font: Font) -> Cell;
}
pub enum Font {
Bold = 1,
Light = 2,
Italic = 3,
Underlined = 4,
SlowBlinking = 5,
Blinking = 6,
Inverse = 7,
Invisible = 8,
Strikethrough = 9,
}
impl Colorizer for Cell {
fn color(&self, hex: &str) -> Cell {
let color = new_ansi(hex, 38);
let mut data = vec![];
for cell in &self.data {
let c = format!("{}{}\x1b[0m", color, cell);
data.push(c);
}
Cell {
data,
height: self.height,
width: self.width,
}
}
fn bg(&self, hex: &str) -> Cell {
let color = new_ansi(hex, 48);
let mut data = vec![];
for cell in &self.data {
let c = format!("{}{}\x1b[0m", color, cell);
data.push(c);
}
Cell {
data,
height: self.height,
width: self.width,
}
}
fn font(&self, font: Font) -> Cell {
let color = format!("\x1B[{}m", font as usize);
let mut data = vec![];
for cell in &self.data {
let c = format!("{}{}\x1b[0m", color, cell);
data.push(c);
}
Cell {
data,
height: self.height,
width: self.width,
}
}
}
fn new_ansi(hex: &str, value: usize) -> String {
let mut color = String::new();
if hex.starts_with('#') && hex.len() == 7 {
color.push_str(&format!("\x1B[{};2;", value));
color.push_str(
format!(
"{};{};{}m",
i16::from_str_radix(&hex[1..3], 16).unwrap(),
i16::from_str_radix(&hex[3..5], 16).unwrap(),
i16::from_str_radix(&hex[5..7], 16).unwrap()
)
.as_str(),
);
}
color
}
pub fn split_colors(color: &str) -> String {
let re = Regex::new(r"\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]").unwrap();
if re.is_match(color) {
let strip_ansi_escapes = strip_ansi_escapes::strip(color).unwrap();
let color = str::from_utf8(&strip_ansi_escapes).unwrap();
return color.to_string();
}
color.to_string()
}
#[cfg(test)]
mod tests {
use crate::cell::ICell;
use crate::styles::color::{split_colors, Colorizer, Font};
#[test]
fn test_colorize_white() {
let colour = "string".cell().color("#ffffff");
assert_eq!(
colour.to_string(),
"\u{1b}[38;2;255;255;255mstring\u{1b}[0m"
)
}
#[test]
fn test_colorize_black() {
let colour = "string".cell().color("#000000");
assert_eq!(colour.to_string(), "\u{1b}[38;2;0;0;0mstring\u{1b}[0m")
}
#[test]
fn test_bg_black() {
let colour = "string".cell().bg("#000000");
assert_eq!(colour.to_string(), "\u{1b}[48;2;0;0;0mstring\u{1b}[0m")
}
#[test]
fn test_font() {
let font = "string".cell().font(Font::Bold);
assert_eq!(font.to_string(), "\u{1b}[1mstring\u{1b}[0m")
}
#[test]
fn test_colorize_not_hex() {
let colour = "string".cell().color("black");
assert_eq!(colour.to_string(), "string\u{1b}[0m")
}
#[test]
fn test_split_colors() {
let string = String::from("\u{1b}[38;2;255;255;255mstring\u{1b}[0m");
let split_color = split_colors(&string);
assert_eq!(split_color, "string")
}
}