use tao_log::*;
use std::sync::{Arc, Mutex};
use log::{Level, LevelFilter, Log, Record, Metadata};
#[cfg(feature = "std")]
use log::set_boxed_logger;
#[cfg(not(feature = "std"))]
fn set_boxed_logger(logger: Box<Log>) -> Result<(), log::SetLoggerError> {
log::set_logger(Box::leak(logger))
}
struct State {
last_log: Mutex<Option<String>>,
}
fn last(state: &State) -> Option<String> {
state.last_log.lock().unwrap().take()
}
struct Logger(Arc<State>);
impl Log for Logger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
let msg = format!("{}", record.args());
*self.0.last_log.lock().unwrap() = Some(msg);
assert_eq!(record.file(), Some(file!()));
assert!(record.line().is_some());
let t = record.target().to_owned();
assert!(t == "log_v" || t == "special", t);
println!("{:5} {}", record.level(), record.args());
}
fn flush(&self) {}
}
fn main() {
let me = Arc::new(State { last_log: Mutex::new(None) });
let a = me.clone();
set_boxed_logger(Box::new(Logger(me))).unwrap();
log::set_max_level(LevelFilter::Debug);
info!("Start of test (test output follows)");
let i = 32;
assert_eq!(debugv!(i), 32);
assert_eq!(last(&a), Some("i → 32".to_owned()));
assert_eq!(debugv!(i+1), 33);
assert_eq!(last(&a), Some("i + 1 → 33".to_owned()));
assert_eq!(errorv!(target: "special", i), 32);
assert_eq!(last(&a), Some("i → 32".to_owned()));
assert_eq!(warnv!("index", "{:#x}", i), 32);
assert_eq!(last(&a), Some("index i → 0x20".to_owned()));
assert_eq!(errorv!(target: "special", "custom:", "{:05}", i), 32);
assert_eq!(last(&a), Some("custom: i → 00032".to_owned()));
let j = 19;
let (q, r) = debugv!((j/4, j%4));
assert_eq!(q, 4);
assert_eq!(r, 3);
assert_eq!(last(&a), Some("(j / 4, j % 4) → (4, 3)".to_owned()));
assert_eq!(debugv!("fifth", (j/5, j%5)), (3, 4));
assert_eq!(last(&a), Some("fifth (j / 5, j % 5) → (3, 4)".to_owned()));
assert_eq!(debugv!((j,)), (19,));
#[allow(unused_parens)] {
assert_eq!(debugv!((j)), 19);
}
let vt = "foo";
assert_eq!(infov!(&vt), &"foo");
assert_eq!(last(&a), Some("&vt → \"foo\"".to_owned()));
assert_eq!(infov!(vt), "foo");
assert_eq!(last(&a), Some("vt → \"foo\"".to_owned()));
let i = 2;
assert_eq!(tracev!(i*4), 8);
assert_eq!(last(&a), None);
let mut o = Some(33);
assert_eq!(debugv!(o.take()), Some(33));
assert_eq!(last(&a), Some("o.take() → Some(33)".to_owned()));
assert_eq!(debugv!(o.take()), None);
assert_eq!(last(&a), Some("o.take() → None".to_owned()));
let i = 3;
assert_eq!(logv!(target: "special", Level::Info, i), 3);
assert_eq!(last(&a), Some("i → 3".to_owned()));
assert_eq!(logv!(Level::Warn, (i+1, i+2)).1, 5);
assert_eq!(last(&a), Some("(i + 1, i + 2) → (4, 5)".to_owned()));
fn fvoid() {}
debugv!(fvoid());
assert_eq!(last(&a), Some("fvoid() → ()".to_owned()));
fn fstr() -> String { "returned".to_owned() }
let s = debugv!(fstr());
assert_eq!(s, "returned");
assert_eq!(last(&a), Some("fstr() → \"returned\"".to_owned()));
let mut m = 0;
assert_eq!(m, 0);
infov!(m = 1);
assert_eq!(m, 1);
infov! { m = 2 };
assert_eq!(m, 2);
assert_eq!(last(&a), Some("m = 2 → ()".to_owned()));
let i = infov!(4,);
infov!("trailing comma", i,);
logv!(target: "special", Level::Info, i,);
debugv!("", 22);
assert_eq!(last(&a), Some(" 22 → 22".to_owned()));
warnv!(666, 1);
assert_eq!(last(&a), Some("666 1 → 1".to_owned()));
let i = 4;
debugv!("prefix with {:?}", "without", i);
assert_eq!(last(&a), Some("prefix with \"i\" 4 → without".to_owned()));
#[cfg(not(tao_log_trailing_comma))] {
let i = infov!(5,,);
infov!("trailing comma", i,,);
logv!(target: "special", Level::Info, i,,);
}
info!("End of test (passed)");
}