ricecoder_cli/
logging.rs

1// Logging and verbosity control
2// Adapted from automation/src/utils/logging.rs
3
4use std::sync::atomic::{AtomicU8, Ordering};
5
6/// Global verbosity level
7static VERBOSITY: AtomicU8 = AtomicU8::new(0);
8
9/// Verbosity levels
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
11pub enum VerbosityLevel {
12    /// Quiet mode - minimal output
13    Quiet = 0,
14    /// Normal mode - standard output
15    Normal = 1,
16    /// Verbose mode - detailed output
17    Verbose = 2,
18    /// Very verbose mode - debug output
19    VeryVerbose = 3,
20}
21
22impl VerbosityLevel {
23    /// Get the current verbosity level
24    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    /// Set the verbosity level
34    pub fn set(level: Self) {
35        VERBOSITY.store(level as u8, Ordering::Relaxed);
36    }
37
38    /// Check if we should output at this level
39    pub fn should_output(&self) -> bool {
40        self <= &Self::current()
41    }
42}
43
44/// Initialize logging based on CLI flags
45pub 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
57/// Log a message at the given verbosity level
58pub fn log_at_level(level: VerbosityLevel, message: &str) {
59    if level.should_output() {
60        eprintln!("{}", message);
61    }
62}
63
64/// Log a debug message (only in verbose mode)
65pub fn debug(message: &str) {
66    log_at_level(VerbosityLevel::Verbose, message);
67}
68
69/// Log an info message (in normal and verbose modes)
70pub 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}