debug_everything/
lib.rs

1#![feature(specialization)]
2
3//! Debug-print everything!
4//!
5//! If you - like me - frequently find yourself deep in a jungle of generic traits with
6//! a sudden need to debug-print some data, this crate is for you.
7//! The constant struggle of adding `Debug` bounds everywhere only to remove
8//! all of them (or at least the ones you can still find) as soon as you're done is over:
9//!
10//! ```
11//! use debug_everything::Debuggable;
12//!
13//! fn generic<T>(t: T) {
14//!     println!("t = {:?}", t.debug());
15//! }
16//! ```
17//!
18//! # How it works
19//!
20//! Sadly, this relies on specialization and thus only works on nightly (as of May 2019).
21//! The `Debuggable` trait is implemented for **all** types but *specialized* for types implementing
22//! `Debug`:
23//!
24//! ```
25//! use debug_everything::Debuggable;
26//! struct Dummy;
27//! 
28//! assert_eq!("42", format!("{:?}", 42.debug()));
29//! assert_eq!("<no Debug impl>", format!("{:?}", Dummy.debug()));
30//! ```
31//!
32//! Simple!
33
34use std::fmt::{Debug, Formatter, Result as FmtResult};
35
36pub trait Debuggable {
37    fn debug(&self) -> &dyn Debug;
38}
39
40struct NotDebug;
41impl Debug for NotDebug {
42    fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
43        fmt.write_str("<no Debug impl>")
44    }
45}
46
47impl<T> Debuggable for T {
48    default fn debug(&self) -> &dyn Debug { &NotDebug }
49}
50
51impl<T: Debug> Debuggable for T {
52    fn debug(&self) -> &dyn Debug { self }
53}
54