cargo/
macros.rs

1use std::fmt;
2
3macro_rules! compact_debug {
4    (
5        impl fmt::Debug for $ty:ident {
6            fn fmt(&$this:ident, f: &mut fmt::Formatter) -> fmt::Result {
7                let (default, default_name) = $e:expr;
8                [debug_the_fields($($field:ident)*)]
9            }
10        }
11    ) => (
12
13        impl fmt::Debug for $ty {
14            fn fmt(&$this, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15                // Try printing a pretty version where we collapse as many fields as
16                // possible, indicating that they're equivalent to a function call
17                // that's hopefully enough to indicate what each value is without
18                // actually dumping everything so verbosely.
19                let mut s = f.debug_struct(stringify!($ty));
20                let (default, default_name) = $e;
21                let mut any_default = false;
22
23                // Exhaustively match so when fields are added we get a compile
24                // failure
25                let $ty { $($field),* } = $this;
26                $(
27                    if *$field == default.$field {
28                        any_default = true;
29                    } else {
30                        s.field(stringify!($field), $field);
31                    }
32                )*
33
34                if any_default {
35                    s.field("..", &crate::macros::DisplayAsDebug(default_name));
36                }
37                s.finish()
38            }
39        }
40    )
41}
42
43pub struct DisplayAsDebug<T>(pub T);
44
45impl<T: fmt::Display> fmt::Debug for DisplayAsDebug<T> {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        fmt::Display::fmt(&self.0, f)
48    }
49}