use std::sync::atomic::{AtomicU8, Ordering};
static VERBOSITY: AtomicU8 = AtomicU8::new(0);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum VerbosityLevel {
Quiet = 0,
Normal = 1,
Verbose = 2,
VeryVerbose = 3,
}
impl VerbosityLevel {
pub fn current() -> Self {
match VERBOSITY.load(Ordering::Relaxed) {
0 => VerbosityLevel::Quiet,
1 => VerbosityLevel::Normal,
2 => VerbosityLevel::Verbose,
_ => VerbosityLevel::VeryVerbose,
}
}
pub fn set(level: Self) {
VERBOSITY.store(level as u8, Ordering::Relaxed);
}
pub fn should_output(&self) -> bool {
self <= &Self::current()
}
}
pub fn init_logging(verbose: bool, quiet: bool) {
let level = if quiet {
VerbosityLevel::Quiet
} else if verbose {
VerbosityLevel::Verbose
} else {
VerbosityLevel::Normal
};
VerbosityLevel::set(level);
}
pub fn log_at_level(level: VerbosityLevel, message: &str) {
if level.should_output() {
eprintln!("{}", message);
}
}
pub fn debug(message: &str) {
log_at_level(VerbosityLevel::Verbose, message);
}
pub fn info(message: &str) {
log_at_level(VerbosityLevel::Normal, message);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_verbosity_levels() {
VerbosityLevel::set(VerbosityLevel::Normal);
assert_eq!(VerbosityLevel::current(), VerbosityLevel::Normal);
VerbosityLevel::set(VerbosityLevel::Verbose);
assert_eq!(VerbosityLevel::current(), VerbosityLevel::Verbose);
}
#[test]
fn test_should_output() {
VerbosityLevel::set(VerbosityLevel::Normal);
assert!(VerbosityLevel::Normal.should_output());
assert!(!VerbosityLevel::Verbose.should_output());
assert!(VerbosityLevel::Quiet.should_output());
}
#[test]
fn test_init_logging_quiet() {
init_logging(false, true);
assert_eq!(VerbosityLevel::current(), VerbosityLevel::Quiet);
}
#[test]
fn test_init_logging_verbose() {
init_logging(true, false);
assert_eq!(VerbosityLevel::current(), VerbosityLevel::Verbose);
}
#[test]
fn test_init_logging_normal() {
init_logging(false, false);
assert_eq!(VerbosityLevel::current(), VerbosityLevel::Normal);
}
}