#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColorMode {
Truecolor,
Ansi256,
Ansi16,
Mono,
}
#[derive(Debug, Clone, Copy)]
pub struct Ink {
pub rgb: (u8, u8, u8),
pub c256: u8,
pub c16: u8,
}
impl ColorMode {
#[must_use]
pub fn paint(self, ink: Ink, text: &str) -> String {
let (r, g, b) = ink.rgb;
match self {
ColorMode::Truecolor => format!("\x1b[38;2;{r};{g};{b}m{text}\x1b[0m"),
ColorMode::Ansi256 => format!("\x1b[38;5;{}m{text}\x1b[0m", ink.c256),
ColorMode::Ansi16 => format!("\x1b[{}m{text}\x1b[0m", ink.c16),
ColorMode::Mono => text.to_string(),
}
}
#[must_use]
pub fn reverse(self, text: &str) -> String {
if self == ColorMode::Mono {
text.to_string()
} else {
format!("\x1b[7m{text}\x1b[0m")
}
}
}
#[must_use]
pub fn detect(
color_arg: &str,
no_color: bool,
is_tty: bool,
colorterm: Option<&str>,
term: Option<&str>,
) -> ColorMode {
match color_arg {
"never" => return ColorMode::Mono,
"always" => {} _ => {
if no_color || !is_tty {
return ColorMode::Mono;
}
}
}
let ct = colorterm.unwrap_or("");
if ct.contains("truecolor") || ct.contains("24bit") {
ColorMode::Truecolor
} else if term.unwrap_or("").contains("256") {
ColorMode::Ansi256
} else {
ColorMode::Ansi16
}
}
pub const GAP: Ink = Ink {
rgb: (0xff, 0x5f, 0x56),
c256: 203,
c16: 31,
}; pub const FOLD: Ink = Ink {
rgb: (0xf5, 0xc5, 0x18),
c256: 220,
c16: 33,
}; pub const LEAP: Ink = Ink {
rgb: (0xc6, 0x78, 0xdd),
c256: 170,
c16: 35,
}; pub const EPOCH: Ink = Ink {
rgb: (0x56, 0xb6, 0xc2),
c256: 80,
c16: 36,
}; pub const ROLLOVER: Ink = Ink {
rgb: (0x61, 0xaf, 0xef),
c256: 75,
c16: 34,
}; pub const MOON_LIT: Ink = Ink {
rgb: (0xf5, 0xf3, 0xce),
c256: 230,
c16: 33,
}; pub const MOON_DARK: Ink = Ink {
rgb: (0x3a, 0x3a, 0x4a),
c256: 237,
c16: 30,
};