use crate::to_ansi_escape_sequence;
use clap::{Parser, ValueEnum};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, ValueEnum)]
pub enum EscEscapeStyle {
#[default]
Bash,
Hex,
Unicode,
UnicodeRust,
Direct,
}
impl EscEscapeStyle {
pub const fn escape_sequence(&self) -> &'static str {
match self {
Self::Bash => "\\e",
Self::Hex => "\\x1b",
Self::Unicode => "\\u001b",
Self::UnicodeRust => "\\u{1b}",
Self::Direct => "\u{1b}",
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, ValueEnum)]
pub enum AnsiKeyword {
#[value(help = crate::cli::AnsiKeyword::Black.to_help_text())]
Black,
#[value(help = crate::cli::AnsiKeyword::BgBlack.to_help_text())]
BgBlack,
#[value(help = crate::cli::AnsiKeyword::Red.to_help_text())]
Red,
#[value(help = crate::cli::AnsiKeyword::BgRed.to_help_text())]
BgRed,
#[value(help = crate::cli::AnsiKeyword::Green.to_help_text())]
Green,
#[value(help = crate::cli::AnsiKeyword::BgGreen.to_help_text())]
BgGreen,
#[value(help = crate::cli::AnsiKeyword::Yellow.to_help_text())]
Yellow,
#[value(help = crate::cli::AnsiKeyword::BgYellow.to_help_text())]
BgYellow,
#[value(help = crate::cli::AnsiKeyword::Blue.to_help_text())]
Blue,
#[value(help = crate::cli::AnsiKeyword::BgBlue.to_help_text())]
BgBlue,
#[value(help = crate::cli::AnsiKeyword::Magenta.to_help_text())]
Magenta,
#[value(help = crate::cli::AnsiKeyword::BgMagenta.to_help_text())]
BgMagenta,
#[value(help = crate::cli::AnsiKeyword::Cyan.to_help_text())]
Cyan,
#[value(help = crate::cli::AnsiKeyword::BgCyan.to_help_text())]
BgCyan,
#[value(help = crate::cli::AnsiKeyword::White.to_help_text())]
White,
#[value(help = crate::cli::AnsiKeyword::BgWhite.to_help_text())]
BgWhite,
#[value(help = crate::cli::AnsiKeyword::Gray.to_help_text())]
Gray,
#[value(help = crate::cli::AnsiKeyword::BgGray.to_help_text())]
BgGray,
#[value(help = crate::cli::AnsiKeyword::BrightRed.to_help_text())]
BrightRed,
#[value(help = crate::cli::AnsiKeyword::BgBrightRed.to_help_text())]
BgBrightRed,
#[value(help = crate::cli::AnsiKeyword::BrightGreen.to_help_text())]
BrightGreen,
#[value(help = crate::cli::AnsiKeyword::BgBrightGreen.to_help_text())]
BgBrightGreen,
#[value(help = crate::cli::AnsiKeyword::BrightYellow.to_help_text())]
BrightYellow,
#[value(help = crate::cli::AnsiKeyword::BgBrightYellow.to_help_text())]
BgBrightYellow,
#[value(help = crate::cli::AnsiKeyword::BrightBlue.to_help_text())]
BrightBlue,
#[value(help = crate::cli::AnsiKeyword::BgBrightBlue.to_help_text())]
BgBrightBlue,
#[value(help = crate::cli::AnsiKeyword::BrightMagenta.to_help_text())]
BrightMagenta,
#[value(help = crate::cli::AnsiKeyword::BgBrightMagenta.to_help_text())]
BgBrightMagenta,
#[value(help = crate::cli::AnsiKeyword::BrightCyan.to_help_text())]
BrightCyan,
#[value(help = crate::cli::AnsiKeyword::BgBrightCyan.to_help_text())]
BgBrightCyan,
#[value(help = crate::cli::AnsiKeyword::BrightWhite.to_help_text())]
BrightWhite,
#[value(help = crate::cli::AnsiKeyword::BgBrightWhite.to_help_text())]
BgBrightWhite,
Clear,
Reset,
#[value(help = crate::cli::AnsiKeyword::Bold.to_help_text())]
Bold,
#[value(help = crate::cli::AnsiKeyword::Dimmed.to_help_text())]
Dimmed,
#[value(help = crate::cli::AnsiKeyword::Italic.to_help_text())]
Italic,
#[value(help = crate::cli::AnsiKeyword::Underline.to_help_text())]
Underline,
#[value(help = crate::cli::AnsiKeyword::Blink.to_help_text())]
Blink,
#[value(help = crate::cli::AnsiKeyword::Hidden.to_help_text())]
Hidden,
#[value(help = crate::cli::AnsiKeyword::Strike.to_help_text())]
Strike,
#[value(help = crate::cli::AnsiKeyword::Strikethrough.to_help_text())]
Strikethrough,
}
impl AnsiKeyword {
fn to_help_text(self) -> String {
match self {
AnsiKeyword::Black
| AnsiKeyword::Red
| AnsiKeyword::Green
| AnsiKeyword::Yellow
| AnsiKeyword::Blue
| AnsiKeyword::Magenta
| AnsiKeyword::Cyan
| AnsiKeyword::White
| AnsiKeyword::Gray
| AnsiKeyword::BrightRed
| AnsiKeyword::BrightGreen
| AnsiKeyword::BrightYellow
| AnsiKeyword::BrightBlue
| AnsiKeyword::BrightMagenta
| AnsiKeyword::BrightCyan
| AnsiKeyword::BrightWhite => {
let begin_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[self]);
let end_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[Self::Clear]);
format!("{begin_sequence}{self:?}{end_sequence} foreground color")
}
AnsiKeyword::BgBlack
| AnsiKeyword::BgRed
| AnsiKeyword::BgGreen
| AnsiKeyword::BgYellow
| AnsiKeyword::BgBlue
| AnsiKeyword::BgMagenta
| AnsiKeyword::BgCyan
| AnsiKeyword::BgWhite
| AnsiKeyword::BgGray
| AnsiKeyword::BgBrightRed
| AnsiKeyword::BgBrightGreen
| AnsiKeyword::BgBrightYellow
| AnsiKeyword::BgBrightBlue
| AnsiKeyword::BgBrightMagenta
| AnsiKeyword::BgBrightCyan
| AnsiKeyword::BgBrightWhite => {
let begin_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[self]);
let end_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[Self::Clear]);
format!("{begin_sequence}{self:?}{end_sequence} background color")
}
AnsiKeyword::Bold
| AnsiKeyword::Dimmed
| AnsiKeyword::Italic
| AnsiKeyword::Underline
| AnsiKeyword::Blink
| AnsiKeyword::Hidden
| AnsiKeyword::Strike
| AnsiKeyword::Strikethrough => {
let begin_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[self]);
let end_sequence = to_ansi_escape_sequence(EscEscapeStyle::Direct, &[Self::Clear]);
format!("{begin_sequence}{self:?}{end_sequence} font")
}
_ => unimplemented!("No help text for {self:?}"),
}
}
pub const fn to_ansi_code(self) -> &'static str {
match self {
AnsiKeyword::Black => "30",
AnsiKeyword::BgBlack => "40",
AnsiKeyword::Red => "31",
AnsiKeyword::BgRed => "41",
AnsiKeyword::Green => "32",
AnsiKeyword::BgGreen => "42",
AnsiKeyword::Yellow => "33",
AnsiKeyword::BgYellow => "43",
AnsiKeyword::Blue => "34",
AnsiKeyword::BgBlue => "44",
AnsiKeyword::Magenta => "35",
AnsiKeyword::BgMagenta => "45",
AnsiKeyword::Cyan => "36",
AnsiKeyword::BgCyan => "46",
AnsiKeyword::White => "37",
AnsiKeyword::BgWhite => "47",
AnsiKeyword::Gray => "90",
AnsiKeyword::BgGray => "100",
AnsiKeyword::BrightRed => "91",
AnsiKeyword::BgBrightRed => "101",
AnsiKeyword::BrightGreen => "92",
AnsiKeyword::BgBrightGreen => "102",
AnsiKeyword::BrightYellow => "93",
AnsiKeyword::BgBrightYellow => "103",
AnsiKeyword::BrightBlue => "94",
AnsiKeyword::BgBrightBlue => "104",
AnsiKeyword::BrightMagenta => "95",
AnsiKeyword::BgBrightMagenta => "105",
AnsiKeyword::BrightCyan => "96",
AnsiKeyword::BgBrightCyan => "106",
AnsiKeyword::BrightWhite => "97",
AnsiKeyword::BgBrightWhite => "107",
AnsiKeyword::Clear | AnsiKeyword::Reset => "0",
AnsiKeyword::Bold => "1",
AnsiKeyword::Dimmed => "2",
AnsiKeyword::Italic => "3",
AnsiKeyword::Underline => "4",
AnsiKeyword::Blink => "5",
AnsiKeyword::Hidden => "8",
AnsiKeyword::Strike | AnsiKeyword::Strikethrough => "9",
}
}
}
#[derive(Parser, Clone, Debug)]
#[command(version, about, long_about)]
pub struct Cli {
#[arg(short = 'n', long)]
pub new_line: bool,
#[arg(short = 'e', long, value_enum, default_value_t)]
pub escape_style: EscEscapeStyle,
#[arg(required = true)]
pub keywords: Vec<AnsiKeyword>,
}