use console::Style;
use owo_colors::OwoColorize;
use std::sync::LazyLock;
pub static THEME: LazyLock<Theme> = LazyLock::new(Theme::default);
#[derive(Debug, Clone)]
pub struct Theme {
pub success: Style,
pub error: Style,
pub warning: Style,
pub info: Style,
pub header: Style,
pub emphasis: Style,
pub dim: Style,
pub path: Style,
pub number: Style,
pub code: Style,
}
impl Default for Theme {
fn default() -> Self {
Self {
success: Style::new().green().bright(),
error: Style::new().red().bright(),
warning: Style::new().yellow().bright(),
info: Style::new().blue().bright(),
header: Style::new().cyan().bold(),
emphasis: Style::new().bold(),
dim: Style::new().dim(),
path: Style::new().magenta(),
number: Style::new().cyan(),
code: Style::new().yellow(),
}
}
}
impl Theme {
pub fn success_with_icon(&self, text: &str) -> String {
if Self::should_disable_colors() {
format!("✓ {text}")
} else {
format!("{} {}", "✓".green(), self.success.apply_to(text))
}
}
pub fn error_with_icon(&self, text: &str) -> String {
if Self::should_disable_colors() {
format!("✗ {text}")
} else {
format!("{} {}", "✗".red(), self.error.apply_to(text))
}
}
pub fn warning_with_icon(&self, text: &str) -> String {
if Self::should_disable_colors() {
format!("⚠ {text}")
} else {
format!("{} {}", "⚠".yellow(), self.warning.apply_to(text))
}
}
pub fn should_disable_colors() -> bool {
use is_terminal::IsTerminal;
std::env::var("NO_COLOR").is_ok() || !std::io::stdout().is_terminal()
}
pub fn apply<T: std::fmt::Display>(&self, style: &Style, text: T) -> String {
if Self::should_disable_colors() {
text.to_string()
} else {
style.apply_to(text).to_string()
}
}
}