use anstyle::{AnsiColor, Effects, Style};
use std::sync::OnceLock;
const HEADER: Style = Style::new()
.fg_color(Some(anstyle::Color::Ansi(AnsiColor::Blue)))
.effects(Effects::BOLD);
const SUCCESS: Style = Style::new().fg_color(Some(anstyle::Color::Ansi(AnsiColor::Green)));
const DIM: Style = Style::new().effects(Effects::DIMMED);
const LABEL: Style = Style::new().effects(Effects::BOLD);
pub fn is_color_enabled() -> bool {
static ENABLED: OnceLock<bool> = OnceLock::new();
*ENABLED.get_or_init(|| std::env::var_os("NO_COLOR").is_none())
}
fn styled(text: &str, style: Style) -> String {
if is_color_enabled() {
format!("{}{}{}", style.render(), text, style.render_reset())
} else {
text.to_string()
}
}
pub fn header(text: &str) -> String {
styled(text, HEADER)
}
pub fn success(text: &str) -> String {
styled(text, SUCCESS)
}
pub fn dim(text: &str) -> String {
styled(text, DIM)
}
pub fn label(text: &str) -> String {
styled(text, LABEL)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_styled_returns_plain_text_when_no_color() {
let text = "hello";
let result = format!("{}{}{}", Style::new().render(), text, Style::new().render_reset());
assert_eq!(result, "hello");
}
#[test]
fn test_styled_applies_ansi_when_style_present() {
let style = Style::new().fg_color(Some(anstyle::Color::Ansi(AnsiColor::Green)));
let rendered = format!("{}{}{}", style.render(), "ok", style.render_reset());
assert!(rendered.contains("\x1b["));
assert!(rendered.contains("ok"));
}
#[test]
fn test_helper_functions_return_strings() {
assert!(!header("h").is_empty());
assert!(!success("s").is_empty());
assert!(!dim("d").is_empty());
assert!(!label("l").is_empty());
}
#[test]
fn test_is_color_enabled_respects_no_color_env() {
let has_no_color = std::env::var_os("NO_COLOR").is_some();
assert_eq!(is_color_enabled(), !has_no_color);
}
}