use std::fmt::{Display, Formatter, Result as FmtResult};
#[derive(Copy, Clone, Debug)]
#[allow(unused)]
pub enum Color {
Black = 30,
Red = 31,
Green = 32,
Yellow = 33,
Blue = 34,
Purple = 35,
Cyan = 36,
White = 37,
BrightRed = 91,
}
impl Color {
#[allow(unused)]
pub(crate) fn wrap(&self, content: impl Display) -> Styled {
Styled::with_content(content).colored(*self)
}
}
#[derive(Copy, Clone, Debug)]
#[allow(unused)]
pub enum Decoration {
Bold = 1,
Underline = 4
}
impl Decoration {
#[allow(unused)]
pub(crate) fn wrap(&self, content: impl Display) -> Styled {
Styled::with_content(content)
}
}
#[derive(Debug, Default)]
pub struct Styled {
settings: usize,
content: String,
}
impl Styled {
pub(crate) const ESC: char = '\x1b';
pub(crate) const TERMINATOR: &str = "\x1b[0m";
pub fn new() -> Self {
Self::default()
}
pub fn with_content(content: impl Display) -> Self {
Self { settings: 0, content: format!("{}", content) }
}
pub fn colored(mut self, color: Color) -> Self {
self.settings |= (color as usize) << 16;
self
}
pub fn decorate(mut self, decoration: Decoration) -> Self {
self.settings |= decoration as usize;
self
}
fn fmt(Self { settings, content }: Self) -> String {
let has_decoration = settings & 0xFFFF != 0;
let color_args = settings >> 16;
if has_decoration {
format!("{}[{};{}m{}{}", Styled::ESC, settings & 0xFFFF, color_args, content, Styled::TERMINATOR)
} else {
format!("{}[{}m{}{}", Styled::ESC, color_args, content, Styled::TERMINATOR)
}
}
pub fn into_log(self) -> StyledLog {
StyledLog(Self::fmt(self))
}
}
impl From<Styled> for StyledLog {
fn from(value: Styled) -> Self {
Self(Styled::fmt(value))
}
}
#[derive(Clone)]
#[wasm_bindgen::prelude::wasm_bindgen]
pub struct StyledLog(String);
impl Display for StyledLog {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}", self.0)
}
}