use std::io::Write;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use owo_colors::{OwoColorize, Stream};
static QUIET: AtomicBool = AtomicBool::new(false);
static VERBOSE: AtomicU8 = AtomicU8::new(0);
pub fn set_quiet(quiet: bool) {
QUIET.store(quiet, Ordering::Relaxed);
}
pub fn is_quiet() -> bool {
QUIET.load(Ordering::Relaxed)
}
pub fn set_verbose(count: u8) {
VERBOSE.store(count, Ordering::Relaxed);
}
pub fn is_verbose() -> bool {
VERBOSE.load(Ordering::Relaxed) > 0
}
fn write_stderr(line: &str) {
let _ = writeln!(std::io::stderr(), "{line}");
}
pub fn step(msg: &str) {
if is_quiet() {
return;
}
let glyph = "→".if_supports_color(Stream::Stderr, |t| t.dimmed());
write_stderr(&format!("{glyph} {msg}"));
}
pub fn ok(msg: &str) {
if is_quiet() {
return;
}
let mark = "✔".if_supports_color(Stream::Stderr, |t| t.green());
let body = msg.if_supports_color(Stream::Stderr, |t| t.green());
write_stderr(&format!("{mark} {body}"));
}
pub fn warn(msg: &str) {
let mark = "!".if_supports_color(Stream::Stderr, |t| t.yellow());
let body = msg.if_supports_color(Stream::Stderr, |t| t.yellow());
write_stderr(&format!("{mark} {body}"));
}
#[allow(dead_code)]
pub fn hint(lines: &[&str]) {
if lines.is_empty() {
return;
}
let head = "Hint:".if_supports_color(Stream::Stderr, |t| t.cyan().bold().to_string());
let mut err = std::io::stderr();
let _ = writeln!(err, "\n{head} {}", lines[0]);
for l in &lines[1..] {
let _ = writeln!(err, " {l}");
}
}
pub fn error(msg: &str) {
let head = "Error:".if_supports_color(Stream::Stderr, |t| t.red().bold().to_string());
write_stderr(&format!("\n{head} {msg}"));
}