use std::io::IsTerminal;
use std::sync::OnceLock;
use std::sync::atomic::{AtomicBool, Ordering};
static PLAIN: AtomicBool = AtomicBool::new(false);
pub fn set_plain(plain: bool) {
PLAIN.store(plain, Ordering::Relaxed);
}
fn enabled() -> bool {
if PLAIN.load(Ordering::Relaxed) {
return false;
}
static ENABLED: OnceLock<bool> = OnceLock::new();
*ENABLED.get_or_init(|| {
if std::env::var_os("NO_COLOR").is_some() {
return false;
}
if let Some(v) = std::env::var_os("CLICOLOR_FORCE")
&& v != "0"
{
return true;
}
#[cfg(windows)]
let _ = enable_ansi_support::enable_ansi_support();
std::io::stdout().is_terminal()
})
}
fn paint(code: &str, s: &str) -> String {
if enabled() {
format!("\x1b[{code}m{s}\x1b[0m")
} else {
s.to_string()
}
}
pub fn rose(s: &str) -> String {
paint("38;5;204", s)
}
pub fn green(s: &str) -> String {
paint("38;5;42", s)
}
pub fn label(s: &str) -> String {
paint("38;5;245", s)
}
pub fn faint(s: &str) -> String {
paint("38;5;240", s)
}
pub fn value(s: &str) -> String {
paint("38;5;252", s)
}
pub fn bold(s: &str) -> String {
paint("1;38;5;255", s)
}
pub fn red(s: &str) -> String {
paint("38;5;203", s)
}
pub fn is_enabled() -> bool {
enabled()
}
pub fn dot_online() -> String {
green("●")
}
pub fn dot_offline() -> String {
faint("○")
}
pub fn check() -> String {
green("✓")
}
pub fn cross() -> String {
red("✗")
}
pub fn marker(s: &str) -> String {
faint(&format!("·{s}·"))
}
pub fn latency(ms: f64) -> String {
let text = format!("{ms:.0}ms");
let code = if ms < 50.0 {
"38;5;42" } else if ms < 150.0 {
"38;5;221" } else {
"38;5;203" };
paint(code, &text)
}