Skip to main content

logging_options/
verbosity.rs

1use clap::Args;
2use log::LevelFilter;
3
4use crate::backend::LoggingOptions;
5
6/// A mutually exclusive set of arguments to specify log verbosity
7#[derive(Copy, Clone, Debug, Default, Args)]
8#[group(multiple = false)]
9pub struct Verbosity {
10    /// Do not log any messages
11    #[clap(short, long, help_heading = "Log Verbosity")]
12    silent: bool,
13
14    /// Log only errors
15    #[clap(short, long, help_heading = "Log Verbosity")]
16    quiet: bool,
17
18    /// Log verbose info messages
19    #[clap(short, long, help_heading = "Log Verbosity")]
20    verbose: bool,
21
22    /// Log debug messages
23    #[clap(short, long, help_heading = "Log Verbosity")]
24    debug: bool,
25
26    /// Log highly verbose trace messages
27    #[clap(short, long, help_heading = "Log Verbosity")]
28    trace: bool,
29}
30
31impl LoggingOptions<env_logger::Logger> for Verbosity {
32    fn configure(&self, mut builder: env_logger::Builder) -> env_logger::Builder {
33        builder.filter_level((*self).into());
34        builder
35    }
36}
37
38impl From<Verbosity> for LevelFilter {
39    fn from(verbosity: Verbosity) -> Self {
40        use LevelFilter::*;
41
42        let Verbosity {
43            silent,
44            quiet,
45            verbose,
46            debug,
47            trace,
48        } = verbosity;
49
50        match (silent, quiet, verbose, debug, trace) {
51            (true, false, false, false, false) => Off,
52            (false, true, false, false, false) => Error,
53            (false, false, false, false, false) => Warn,
54            (false, false, true, false, false) => Info,
55            (false, false, false, true, false) => Debug,
56            (false, false, false, false, true) => Trace,
57            _ => panic!(
58                "`LogVerbosity` should not be instantiated with more than one true field: {verbosity:#?}"
59            ),
60        }
61    }
62}
63
64impl From<LevelFilter> for Verbosity {
65    fn from(level: LevelFilter) -> Self {
66        use LevelFilter::*;
67
68        let mut lv = Verbosity::default();
69        let mut dummy_warn = false;
70
71        let fieldptr = match level {
72            Trace => &mut lv.trace,
73            Debug => &mut lv.debug,
74            Info => &mut lv.verbose,
75            Warn => &mut dummy_warn,
76            Error => &mut lv.quiet,
77            Off => &mut lv.silent,
78        };
79
80        // Set only a single field (maybe the dummy):
81        *fieldptr = true;
82
83        lv
84    }
85}