chj_util/dt.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
//! Debug trace
// Sadly there's no __func__ or __FUNCTION__ equivalent in Rust.
use std::cell::Cell;
thread_local! {
// Cell not working here in 1.63.0, thus go with RefCell anyway
static LEVEL: Cell<u32> = Cell::new(0);
}
const INDENT: &str = " ";
fn indent(n: u32) -> &'static str {
&INDENT[0..(n as usize)]
}
pub struct DtGuard {
pub string: String
}
impl Drop for DtGuard {
fn drop(&mut self) {
// leave
let l: u32 = LEVEL.with(|c: &Cell<u32>| {
let new = c.get() - 1;
c.set(new);
new
});
eprintln!("{}{}[90m<- ({}){}[30m",
// ^ 37 is too bright; 30 assuming black is default
indent(l),
27 as char, // \033
self.string,
27 as char);
}
}
pub fn enter(s: &str) {
let l: u32 = LEVEL.with(|c: &std::cell::Cell<u32>| {
let old = c.get();
c.set(old + 1);
old
});
eprintln!("{}-> ({})",
indent(l),
s);
}
#[macro_export]
macro_rules! dt {
($namestr:expr $(,$arg:expr)*) => {
// let namestr = stringify!($name);
let mut guard = dt::DtGuard {
string: String::new()
};
guard.string.push_str($namestr);
$(
guard.string.push_str(&format!(" {:?}", $arg));
)*
dt::enter(&guard.string);
}
}
#[macro_export]
macro_rules! nodt {
($namestr:expr $(,$arg:expr)*) => {
}
}