use std::fmt;
use anstyle::{AnsiColor, Style};
pub const ERROR: Style = AnsiColor::Red.on_default().bold();
pub const ERROR_BODY: Style = AnsiColor::Red.on_default();
pub const PM: Style = AnsiColor::Green.on_default().bold();
pub const LABEL: Style = Style::new().bold();
pub const DIM: Style = Style::new().dimmed();
pub fn paint<T: fmt::Display>(style: Style, text: T) -> Painted<T> {
Painted { style, text }
}
pub fn padded(style: Style, width: usize, text: impl fmt::Display) -> Painted<String> {
paint(style, format!("{text:<width$}"))
}
pub fn label(width: usize, text: &str) -> Painted<String> {
padded(LABEL, width, text)
}
pub struct Painted<T> {
style: Style,
text: T,
}
impl<T: fmt::Display> fmt::Display for Painted<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}{}{}",
self.style.render(),
self.text,
self.style.render_reset()
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paint_keeps_the_text() {
assert!(paint(DIM, "x").to_string().contains('x'));
assert!(paint(ERROR, "boom").to_string().contains("boom"));
}
#[test]
fn padded_keeps_the_text_and_the_padding() {
assert!(padded(PM, 6, "pnpm").to_string().contains("pnpm "));
assert!(label(12, "Start").to_string().contains("Start "));
}
}