Derive Macro displaydoc::Display

source ·
#[derive(Display)]
{
    // Attributes available to this derive:
    #[ignore_extra_doc_attributes]
    #[prefix_enum_doc_attributes]
    #[displaydoc]
}
Expand description

Custom #[derive(...)] macro for implementing fmt::Display via doc comment attributes.

Generic Type Parameters

Type parameters to an enum or struct using this macro should not need to have an explicit Display constraint at the struct or enum definition site. A Display implementation for the derived struct or enum is generated assuming each type parameter implements Display, but that should be possible without adding the constraint to the struct definition itself:

use displaydoc::Display;

/// oh no, an error: {0}
#[derive(Display)]
pub struct Error<E>(pub E);

// No need to require `E: Display`, since `displaydoc::Display` adds that implicitly.
fn generate_error<E>(e: E) -> Error<E> { Error(e) }

assert!("oh no, an error: muahaha" == &format!("{}", generate_error("muahaha")));

Using Debug Implementations with Type Parameters

However, if a type parameter must instead be constrained with the Debug trait so that some field may be printed with {:?}, that constraint must currently still also be specified redundantly at the struct or enum definition site. If a struct or enum field is being formatted with {:?} via displaydoc, and a generic type parameter must implement Debug to do that, then that struct or enum definition will need to propagate the Debug constraint to every type parameter it’s instantiated with:

use core::fmt::Debug;
use displaydoc::Display;

/// oh no, an error: {0:?}
#[derive(Display)]
pub struct Error<E: Debug>(pub E);

// `E: Debug` now has to propagate to callers.
fn generate_error<E: Debug>(e: E) -> Error<E> { Error(e) }

assert!("oh no, an error: \"cool\"" == &format!("{}", generate_error("cool")));

// Try this with a struct that doesn't impl `Display` at all, unlike `str`.
#[derive(Debug)]
pub struct Oh;
assert!("oh no, an error: Oh" == &format!("{}", generate_error(Oh)));