use console::{Alignment, StyledObject, pad_str, style};
use std::sync::LazyLock;
use std::{
fmt::Display,
io::{IsTerminal, stdout},
};
pub static PAD_OUTPUT: LazyLock<bool> = LazyLock::new(|| stdout().is_terminal());
pub const LABEL_WIDTH: usize = 12;
#[derive(Default)]
pub enum OutputLabel<'a> {
Error(&'a str),
Warning(&'a str),
Info(&'a str),
Success(&'a str),
Custom(StyledObject<&'a str>),
#[default]
None,
}
pub fn println_label<M: AsRef<str> + Display>(label: OutputLabel, message: M) {
match label {
OutputLabel::Error(_) => {
eprintln!("{}", pretty_output(label, message));
}
_ => {
println!("{}", pretty_output(label, message));
}
}
}
pub fn pretty_output<M: AsRef<str> + Display>(out_label: OutputLabel, message: M) -> String {
let (label, label_is_empty) = match out_label {
OutputLabel::Error(error) => (style(error).bold().red(), false),
OutputLabel::Warning(warn) => (style(warn).bold().yellow(), false),
OutputLabel::Info(info) => (style(info).bold().cyan(), false),
OutputLabel::Success(success) => (style(success).bold().green(), false),
OutputLabel::Custom(custom) => (custom, false),
OutputLabel::None => (style(""), true),
};
if *PAD_OUTPUT {
format!(
"{} {}",
pad_str(
label.to_string().as_str(),
LABEL_WIDTH,
Alignment::Right,
None
),
message
)
} else {
if label_is_empty {
format!("\t{message}")
} else {
format!("{label} {message}")
}
}
}