Expand description
More robust and versatile implementation of derive(Debug)
and derive(Display)
. Unlike the version of
derive(Debug)
in the standard library, these macros will always successfully generate an implementation - even if
a member does not implement Debug
/Display
. In that case, the generated implementation will print a replacement
string of the form <TypeName>
.
§More Robust
These derive macros always work, even when derive(std::fmt::Debug)
fails.
// a type that implements neither `Debug` nor `Display`
struct Unprintable;
#[derive(fmt_derive::Debug, fmt_derive::Display)]
struct Printable(Unprintable);
fn main() {
// error[E0277]: `Unprintable` doesn't implement `Debug`
// println!("{:?}", Unprintable);
assert_eq!(format!("{:?}", Printable(Unprintable)), "Printable(<Unprintable>)");
// deriving display is often more useful with a custom format expression, but will silently fall back to the same
// behavior as `Debug`
assert_eq!(format!("{}", Printable(Unprintable)), "Printable(<Unprintable>)");
}
§Drop in Usage
Anything that derives [std::fmt::Debug
] or core::fmt::Debug
can derive fmt_derive::Debug
instead
without any changes required.
However, both cannot be use
d at the same time, as their names clash:
// error[E0252]: the name `Debug` is defined multiple times
use fmt_derive::Debug;
use core::fmt::Debug;
The same problem exists for Display
:
// error[E0252]: the name `Display` is defined multiple times
use fmt_derive::Display;
use core::fmt::Display;
If you encounter this problem, there is a simple solution: use fmt_derive::Debug;
also pulls in the
[std::fmt::Debug
]/core::fmt::Debug
trait, there is no need to use
the standard library Debug
.
use fmt_derive::Debug; // replace `use std::fmt::Debug;` and `use core::fmt::Debug;`
struct Unprintable;
#[derive(Debug)]
struct Printable(Unprintable);
fn main() {
// error[E0277]: `Unprintable` doesn't implement `Debug`
// println!("{:?}", Unprintable);
assert_eq!(format!("{:?}", &Printable(Unprintable) as &dyn Debug), "Printable(<Unprintable>)");
}
§More Versatile
The derived implementation can be easily customized using additional attributes.
§Custom Format Expressions
A custom representation can be quickly derived using a format expression for the whole structure, enumeration, or
untagged unions. This is the expected case when deriving Display
or when a member needs to be formatted in a
special manner:
use fmt_derive::{Debug, Display};
#[derive(Display, Debug)]
#[debug("T<0x{:X}>", self.0)]
#[display("A thing that sits on the number {}", self.0)]
struct Thing(u32);
fn main() {
assert_eq!(format!("{:?}", Thing(0xF7A)), "T<0xF7A>");
assert_eq!(format!("{}", Thing(42)), "A thing that sits on the number 42");
}
§Custom Format Expressions for Enumeration Variants
For enumerations, variants can also be customized:
use fmt_derive::Debug;
#[derive(Debug)]
enum Thing{
// tuple members are exposed as `_0`, `_1`, and so forth
#[debug("Thing::VariantA(0x{:X}, {})", _0, _1)]
VariantA(u32, u32),
// struct members are exposed under their name
#[debug("Thing::VariantB({})", x)]
VariantB{
x: u32,
unused: u32,
}
}
fn main() {
assert_eq!(format!("{:?}", Thing::VariantA(0xF7A, 42)), "Thing::VariantA(0xF7A, 42)");
assert_eq!(format!("{:?}", Thing::VariantB{x: 42, unused: 0}), "Thing::VariantB(42)");
}
§Custom Format Expressions for Individual Fields
Or by customizing an individual field:
use fmt_derive::Debug;
#[derive(Debug)]
struct Thing(#[debug("0x{:X}", self.0)] u32);
fn main() {
assert_eq!(format!("{:?}", Thing(0xF7A)), "Thing(0xF7A)");
}
§Ignoring a Field
Although it is possible to derive a debug message for any field, it is sometimes preferable to not print a field at all:
use fmt_derive::Debug;
#[derive(Debug)]
struct Function(#[debug(ignore)] fn());
fn main() {
assert_eq!(format!("{:?}", Function(main)), "Function");
}
Traits§
- Debug
- The trait and macro from the standard library. Only the trait is actually exposed by this crate.
?
formatting. - Display
- The trait and macro from the standard library. Only the trait is actually exposed by this crate.
Format trait for an empty format,
{}
.
Derive Macros§
- Debug
- Derive implementations of
Debug
for arbitrarystruct
s andenum
s (union
s are supported only with a top-level format directive).use
ingfmt_derive::Debug
, will also pull in thecore::fmt::Debug
/[std::fmt::Debug
] trait (but the macro of the same name will be replaced with this one). - Debug
- The trait and macro from the standard library. Only the trait is actually exposed by this crate.
Derive macro generating an impl of the trait
Debug
. - Display
- Derive implementations of
Display
for arbitrarystruct
s andenum
s (union
s are supported only with a top-level format directive)..use
ingfmt_derive::Display
, will also pull in thecore::fmt::Display
/[std::fmt::Display
] trait (but the macro of the same name will be replaced with this one).