1#[macro_use]
2extern crate log;
3
4use std::sync::{Arc, Mutex};
5use log::{Level, LevelFilter, Log, Record, Metadata};
6
7#[cfg(feature = "std")]
8use log::set_boxed_logger;
9#[cfg(not(feature = "std"))]
10fn set_boxed_logger(logger: Box<Log>) -> Result<(), log::SetLoggerError> {
11    log::set_logger(Box::leak(logger))
12}
13
14struct State {
15    last_log: Mutex<Option<Level>>,
16}
17
18struct Logger(Arc<State>);
19
20impl Log for Logger {
21    fn enabled(&self, _: &Metadata) -> bool {
22        true
23    }
24
25    fn log(&self, record: &Record) {
26        *self.0.last_log.lock().unwrap() = Some(record.level());
27    }
28
29    fn flush(&self) {}
30}
31
32fn main() {
33    let me = Arc::new(State { last_log: Mutex::new(None) });
34    let a = me.clone();
35    set_boxed_logger(Box::new(Logger(me))).unwrap();
36
37    test(&a, LevelFilter::Off);
38    test(&a, LevelFilter::Error);
39    test(&a, LevelFilter::Warn);
40    test(&a, LevelFilter::Info);
41    test(&a, LevelFilter::Debug);
42    test(&a, LevelFilter::Trace);
43}
44
45fn test(a: &State, filter: LevelFilter) {
46    log::set_max_level(filter);
47    error!("");
48    last(&a, t(Level::Error, filter));
49    warn!("");
50    last(&a, t(Level::Warn, filter));
51    info!("");
52    last(&a, t(Level::Info, filter));
53
54    debug!("");
55    if cfg!(debug_assertions) {
56        last(&a, t(Level::Debug, filter));
57    } else {
58        last(&a, None);
59    }
60
61    trace!("");
62    last(&a, None);
63
64    fn t(lvl: Level, filter: LevelFilter) -> Option<Level> {
65        if lvl <= filter {Some(lvl)} else {None}
66    }
67}
68
69fn last(state: &State, expected: Option<Level>) {
70    let mut lvl = state.last_log.lock().unwrap();
71    assert_eq!(*lvl, expected);
72    *lvl = None;
73}
74