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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::time::Instant;
pub const RESET: &str = "\x1b[0m";
pub const RED: &str = "\x1b[31m";
pub const GREY: &str = "\x1b[90m";
static mut START: Option<Instant> = None;
pub fn d_prn<S: ToString>(s: S) {
let start = d_start();
let t = Instant::now() - start;
eprintln!("{} {}", internal::disp_time(&t), s.to_string());
}
pub fn d_start() -> Instant {
match unsafe { START } {
Some(t) => t,
None => {
eprintln!();
eprintln!("{} START", internal::fo(" s", " ms", " µs"));
let now = Instant::now();
unsafe { START = Some(now) };
now
}
}
}
pub fn d_end() {
d_prn("END");
eprintln!();
}
#[macro_export]
macro_rules! d {
{ @ $expr:expr => $val:ident ( $($format_args:tt)+ ) } => {
match $expr {
$val => {
let args = format!($($format_args)+);
d!(@raw args);
$val
}
}
};
{ @raw $expr:expr } => { {
let thread = format!("[{}]", std::thread::current().name().unwrap_or("???"));
let pos = format!("{}:{}", file!(), line!());
let val = $expr;
$crate::d_prn(format!("{:6} {} {}{}{}", thread, &val, $crate::GREY, pos, $crate::RESET));
val
} };
{ @ $($tt:tt)* } => {
d!(@raw format!($($tt)*))
};
{} => { d! { @() => val ("") } };
{ #? $val:expr } => { d! { @ $val => val ("{} = {:#?}", stringify!($val), val) } };
{ ? $val:expr } => { d! { @ $val => val ("{} = {:?}", stringify!($val), val) } };
{ $val:expr } => { d! { @ $val => val ("{}", val) } };
}
mod internal {
use std::time::Duration;
#[rustfmt::skip]
pub fn disp_time(t: &Duration) -> String {
let n = t.as_micros();
let s2 = String::from(" ");
let s3 = String::from(" ");
match (n / 1000_000, n / 1000 % 1000, n % 1000) {
(0, 0, 0) => fo(s2, s3, " 0"),
(0, 0, us) => fo(s2, s3, format!( "{:3}", us)),
(0, ms, us) => fo(s2, format!( "{:3}", ms), format!("{:03}", us)),
(s, ms, us) => fo(format!("{:2}", s), format!("{:03}", ms), format!("{:03}", us)),
}
}
pub fn fo(s: impl Into<String>, ms: impl Into<String>, us: impl Into<String>) -> String {
const S: &str = super::RED;
const MS: &str = super::RESET;
const US: &str = super::GREY;
const RST: &str = super::RESET;
let (s, ms, us) = (s.into(), ms.into(), us.into());
format!("{s}{}{rst}{ms}{}{rst} {us}{}{rst}", s, ms, us, s = S, ms = MS, us = US, rst = RST)
}
}