use std::io::{self, IsTerminal, Write};
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
static VERBOSE: AtomicBool = AtomicBool::new(false);
static STDOUT_LOCK: Mutex<()> = Mutex::new(());
pub fn set_verbose(enabled: bool) {
VERBOSE.store(enabled, Ordering::SeqCst);
}
pub fn is_verbose() -> bool {
VERBOSE.load(Ordering::SeqCst)
}
pub fn write_verbose(args: std::fmt::Arguments) {
let _guard = STDOUT_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let is_tty = io::stdout().is_terminal();
let mut stdout = io::stdout().lock();
if is_tty {
let _ = write!(stdout, "[verbose] {}\r\n", args);
} else {
let _ = writeln!(stdout, "[verbose] {}", args);
}
let _ = stdout.flush();
}
#[macro_export]
macro_rules! verbose {
($($arg:tt)*) => {
if $crate::verbose::is_verbose() {
$crate::verbose::write_verbose(format_args!($($arg)*));
}
};
}
#[macro_export]
macro_rules! info {
($($arg:tt)*) => {
eprintln!("[info] {}", format!($($arg)*));
};
}
#[macro_export]
macro_rules! warn {
($($arg:tt)*) => {
eprintln!("[warn] {}", format!($($arg)*));
};
}
#[macro_export]
macro_rules! error {
($($arg:tt)*) => {
eprintln!("[error] {}", format!($($arg)*));
};
}