use std::sync::OnceLock;
use std::time::Instant;
const RESET: &str = "\x1b[0m";
const CYAN: &str = "\x1b[36m";
const GREEN: &str = "\x1b[32m";
const YELLOW: &str = "\x1b[33m";
const RED: &str = "\x1b[31m";
const DIM: &str = "\x1b[2m";
const WHITE: &str = "\x1b[37m";
fn color_enabled() -> bool {
static DECISION: OnceLock<bool> = OnceLock::new();
*DECISION.get_or_init(|| {
if std::env::var_os("NO_COLOR").is_some() {
return false;
}
use std::io::IsTerminal;
std::io::stdout().is_terminal()
})
}
pub(super) fn paint(color: &str, text: &str) -> String {
if color_enabled() {
format!("{color}{text}{RESET}")
} else {
text.to_string()
}
}
pub(super) fn dim(text: &str) -> String {
paint(DIM, text)
}
pub(super) fn cyan(text: &str) -> String {
paint(CYAN, text)
}
pub(super) fn green(text: &str) -> String {
paint(GREEN, text)
}
pub(super) fn yellow(text: &str) -> String {
paint(YELLOW, text)
}
pub(super) fn red(text: &str) -> String {
paint(RED, text)
}
pub(super) fn white(text: &str) -> String {
paint(WHITE, text)
}
pub(super) fn duration_tag(start: Instant) -> Option<String> {
let ms = start.elapsed().as_millis();
if ms == 0 {
None
} else {
Some(dim(&format!("[{ms} ms]")))
}
}
pub(super) fn source_tag(addr: Option<&str>) -> Option<String> {
addr.map(|a| dim(&format!("- source {a}")))
}