tab_api/
log.rs

1//! A global, configurable level filters
2//! The command, daemon, and pty honor this level on startup.
3//!
4//! The main executible configures if the --log <level> option is provided
5//!
6//! get_level() returns None unless set_level has been called.
7use std::sync::atomic::{AtomicU8, Ordering};
8
9use log::LevelFilter;
10
11// info level
12static LOG_LEVEL: AtomicU8 = AtomicU8::new(0);
13
14pub fn set_level(level: LevelFilter) {
15    let byte_repr = discriminant_of(level);
16    LOG_LEVEL.store(byte_repr, Ordering::SeqCst);
17}
18
19pub fn get_level() -> Option<LevelFilter> {
20    level_of(LOG_LEVEL.load(Ordering::SeqCst))
21}
22
23pub fn get_level_str() -> Option<&'static str> {
24    let level = get_level();
25
26    if let None = level {
27        return None;
28    }
29
30    match level.unwrap() {
31        LevelFilter::Off => Some("off"),
32        LevelFilter::Error => Some("error"),
33        LevelFilter::Warn => Some("warn"),
34        LevelFilter::Info => Some("info"),
35        LevelFilter::Debug => Some("debug"),
36        LevelFilter::Trace => Some("trace"),
37    }
38}
39
40// LevelFilter has a from_usize method, but it's private
41// we have to redo the cases here, and support None as 0
42fn discriminant_of(filter: LevelFilter) -> u8 {
43    match filter {
44        LevelFilter::Trace => 1,
45        LevelFilter::Debug => 2,
46        LevelFilter::Info => 3,
47        LevelFilter::Warn => 4,
48        LevelFilter::Error => 5,
49        LevelFilter::Off => 6,
50    }
51}
52
53fn level_of(filter: u8) -> Option<LevelFilter> {
54    match filter {
55        0 => None,
56        1 => Some(LevelFilter::Trace),
57        2 => Some(LevelFilter::Debug),
58        3 => Some(LevelFilter::Info),
59        4 => Some(LevelFilter::Warn),
60        5 => Some(LevelFilter::Error),
61        6 => Some(LevelFilter::Off),
62        _ => unreachable!("unreachable level discriminant"),
63    }
64}