1use std::sync::atomic::{AtomicU8, Ordering};
5
6static VERBOSITY: AtomicU8 = AtomicU8::new(0);
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
11pub enum VerbosityLevel {
12 Quiet = 0,
14 Normal = 1,
16 Verbose = 2,
18 VeryVerbose = 3,
20}
21
22impl VerbosityLevel {
23 pub fn current() -> Self {
25 match VERBOSITY.load(Ordering::Relaxed) {
26 0 => VerbosityLevel::Quiet,
27 1 => VerbosityLevel::Normal,
28 2 => VerbosityLevel::Verbose,
29 _ => VerbosityLevel::VeryVerbose,
30 }
31 }
32
33 pub fn set(level: Self) {
35 VERBOSITY.store(level as u8, Ordering::Relaxed);
36 }
37
38 pub fn should_output(&self) -> bool {
40 self <= &Self::current()
41 }
42}
43
44pub fn init_logging(verbose: bool, quiet: bool) {
46 let level = if quiet {
47 VerbosityLevel::Quiet
48 } else if verbose {
49 VerbosityLevel::Verbose
50 } else {
51 VerbosityLevel::Normal
52 };
53
54 VerbosityLevel::set(level);
55}
56
57pub fn log_at_level(level: VerbosityLevel, message: &str) {
59 if level.should_output() {
60 eprintln!("{}", message);
61 }
62}
63
64pub fn debug(message: &str) {
66 log_at_level(VerbosityLevel::Verbose, message);
67}
68
69pub fn info(message: &str) {
71 log_at_level(VerbosityLevel::Normal, message);
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_verbosity_levels() {
80 VerbosityLevel::set(VerbosityLevel::Normal);
81 assert_eq!(VerbosityLevel::current(), VerbosityLevel::Normal);
82
83 VerbosityLevel::set(VerbosityLevel::Verbose);
84 assert_eq!(VerbosityLevel::current(), VerbosityLevel::Verbose);
85 }
86
87 #[test]
88 fn test_should_output() {
89 VerbosityLevel::set(VerbosityLevel::Normal);
90 assert!(VerbosityLevel::Normal.should_output());
91 assert!(!VerbosityLevel::Verbose.should_output());
92 assert!(VerbosityLevel::Quiet.should_output());
93 }
94
95 #[test]
96 fn test_init_logging_quiet() {
97 init_logging(false, true);
98 assert_eq!(VerbosityLevel::current(), VerbosityLevel::Quiet);
99 }
100
101 #[test]
102 fn test_init_logging_verbose() {
103 init_logging(true, false);
104 assert_eq!(VerbosityLevel::current(), VerbosityLevel::Verbose);
105 }
106
107 #[test]
108 fn test_init_logging_normal() {
109 init_logging(false, false);
110 assert_eq!(VerbosityLevel::current(), VerbosityLevel::Normal);
111 }
112}