use std::io::IsTerminal;
use std::sync::OnceLock;
const BRAND: &str = "\x1b[1;38;2;153;255;0m";
const WARN: &str = "\x1b[1;38;2;255;214;0m"; const ERR: &str = "\x1b[1;38;2;255;85;85m"; const DIM: &str = "\x1b[2m"; const RESET: &str = "\x1b[0m";
fn enabled() -> bool {
static ON: OnceLock<bool> = OnceLock::new();
*ON.get_or_init(|| {
if std::env::var_os("NO_COLOR").is_some() {
return false; }
std::env::var_os("CLICOLOR_FORCE").is_some() || std::io::stderr().is_terminal()
})
}
fn wrap(code: &str, s: &str) -> String {
if enabled() {
format!("{code}{s}{RESET}")
} else {
s.to_string()
}
}
pub fn brand(s: &str) -> String {
wrap(BRAND, s)
}
pub fn warn(s: &str) -> String {
wrap(WARN, s)
}
pub fn err(s: &str) -> String {
wrap(ERR, s)
}
pub fn dim(s: &str) -> String {
wrap(DIM, s)
}
pub fn next_steps(steps: &[(String, &str)]) -> String {
let width = steps
.iter()
.map(|(cmd, _)| cmd.chars().count())
.max()
.unwrap_or(0);
let mut out = brand("Next:");
for (cmd, hint) in steps {
out.push_str(&format!(
"\n {}{} {}",
brand(cmd),
" ".repeat(width.saturating_sub(cmd.chars().count())),
dim(&format!("# {hint}")),
));
}
out
}
pub fn tag() -> String {
brand("xark")
}
pub fn clap_styles() -> clap::builder::Styles {
use clap::builder::styling::{AnsiColor, Color, RgbColor, Style};
let brand = Style::new()
.bold()
.fg_color(Some(Color::Rgb(RgbColor(153, 255, 0))));
clap::builder::Styles::styled()
.header(brand)
.usage(brand)
.literal(Style::new().fg_color(Some(Color::Rgb(RgbColor(153, 255, 0)))))
.placeholder(Style::new().fg_color(Some(Color::Ansi(AnsiColor::White))))
}