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