use std::io::Write;
use std::sync::atomic::{AtomicU8, Ordering};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
static VERBOSITY: AtomicU8 = AtomicU8::new(2);
pub fn set_verbosity(level: u8) {
VERBOSITY.store(level, Ordering::Relaxed);
}
#[must_use]
pub const fn is_enabled_for(level: u8) -> bool {
level >= 2
}
#[must_use]
pub fn enabled() -> bool {
if !is_enabled_for(VERBOSITY.load(Ordering::Relaxed)) {
return false;
}
if std::env::var_os("KAZE_TESTING").is_some() && std::env::var_os("KAZE_LOGS").is_none() {
return false;
}
true
}
pub fn info(msg: impl AsRef<str>) {
if !enabled() {
return;
}
let mut stream = StandardStream::stdout(ColorChoice::Auto);
if write_info(&mut stream, msg.as_ref()).is_err()
&& writeln!(stream, "kaze: {}", msg.as_ref()).is_err()
{
drop(stream);
}
}
pub fn error(msg: impl AsRef<str>) {
let mut stream = StandardStream::stderr(ColorChoice::Auto);
if write_error(&mut stream, msg.as_ref()).is_err()
&& writeln!(stream, "{}", msg.as_ref()).is_err()
{
drop(stream);
}
}
fn write_info(out: &mut dyn WriteColor, msg: &str) -> std::io::Result<()> {
let mut spec = ColorSpec::new();
spec.set_fg(Some(Color::Green));
out.set_color(&spec)?;
writeln!(out, "kaze: {msg}")?;
out.reset()?;
Ok(())
}
fn write_error(out: &mut dyn WriteColor, msg: &str) -> std::io::Result<()> {
let mut spec = ColorSpec::new();
spec.set_fg(Some(Color::Red));
out.set_color(&spec)?;
writeln!(out, "{msg}")?;
out.reset()?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn write_info_includes_color_when_ansi_enabled() {
let mut buf = termcolor::Buffer::ansi();
write_info(&mut buf, "hello").expect("write info");
let output = std::str::from_utf8(buf.as_slice()).expect("utf8");
assert!(output.contains("kaze: hello"));
assert!(output.contains("\u{1b}["));
}
#[test]
fn write_info_no_color_when_disabled() {
let mut buf = termcolor::Buffer::no_color();
write_info(&mut buf, "hello").expect("write info");
let output = std::str::from_utf8(buf.as_slice()).expect("utf8");
assert_eq!(output, "kaze: hello\n");
}
#[test]
fn write_error_includes_color_when_ansi_enabled() {
let mut buf = termcolor::Buffer::ansi();
write_error(&mut buf, "error: boom").expect("write error");
let output = std::str::from_utf8(buf.as_slice()).expect("utf8");
assert!(output.contains("error: boom"));
assert!(output.contains("\u{1b}["));
}
#[test]
fn write_error_no_color_when_disabled() {
let mut buf = termcolor::Buffer::no_color();
write_error(&mut buf, "error: boom").expect("write error");
let output = std::str::from_utf8(buf.as_slice()).expect("utf8");
assert_eq!(output, "error: boom\n");
}
}