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
#![cfg_attr(use_nightly, feature(core_intrinsics, specialization))]
use std::fmt;
#[cfg(use_nightly)]
use std::intrinsics::type_name;
#[macro_export]
macro_rules! debugit {
($message:expr, $($value:expr),*) => {{
print!("{} ", $message);
$(
print!("{:?}", $crate::DebugIt(&$value));
)*
println!("");
}};
}
#[derive(Copy, Clone)]
pub struct DebugIt<T>(pub T);
#[cfg(not(use_nightly))]
impl<T> fmt::Debug for DebugIt<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<unknown>")
}
}
#[cfg(use_nightly)]
impl<T> fmt::Debug for DebugIt<T> {
default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe {
write!(f, "`{}`", type_name::<T>())
}
}
}
#[cfg(use_nightly)]
impl<T> fmt::Debug for DebugIt<T>
where T: fmt::Debug
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
#[cfg(test)]
mod tests {
use ::DebugIt;
#[test]
fn it_works() {
#[cfg(not(use_nightly))]
fn debug_no_bound<T>(x: T, _: &str) {
format!("{:?}", DebugIt(&x));
}
#[cfg(use_nightly)]
fn debug_no_bound<T>(x: T, s: &str) {
assert_eq!(&format!("{:?}", DebugIt(&x)), s);
}
debug_no_bound(1, "1");
debug_no_bound((), "()");
}
}