Expand description
This library provides a convenient derive macro for the standard library’s
core::fmt::Display
trait.
[dependencies]
displaydoc = "0.2"
Compiler support: requires rustc 1.56+
§Example
Demonstration alongside the Error
derive macro from thiserror
,
to propagate source locations from io::Error
with the #[source]
attribute:
use std::io;
use displaydoc::Display;
use thiserror::Error;
#[derive(Display, Error, Debug)]
pub enum DataStoreError {
/// data store disconnected
Disconnect(#[source] io::Error),
/// the data for key `{0}` is not available
Redaction(String),
/// invalid header (expected {expected:?}, found {found:?})
InvalidHeader {
expected: String,
found: String,
},
/// unknown data store error
Unknown,
}
let error = DataStoreError::Redaction("CLASSIFIED CONTENT".to_string());
assert!("the data for key `CLASSIFIED CONTENT` is not available" == &format!("{}", error));
Note that although io::Error
implements Display
, we do not add it to the
generated message for DataStoreError::Disconnect
, since it is already made available via
#[source]
. See further context on avoiding duplication in error reports at the rust blog
here.
§Details
- A
fmt::Display
impl is generated for your enum if you provide a docstring comment on each variant as shown above in the example. TheDisplay
derive macro supports a shorthand for interpolating fields from the error:/// {var}
⟶write!("{}", self.var)
/// {0}
⟶write!("{}", self.0)
/// {var:?}
⟶write!("{:?}", self.var)
/// {0:?}
⟶write!("{:?}", self.0)
- This also works with structs and generic types:
/// oh no, an error: {0}
#[derive(Display)]
pub struct Error<E>(pub E);
let error: Error<&str> = Error("muahaha i am an error");
assert!("oh no, an error: muahaha i am an error" == &format!("{}", error));
-
Two optional attributes can be added to your types next to the derive:
-
#[ignore_extra_doc_attributes]
makes the macro ignore any doc comment attributes (or///
lines) after the first. Multi-line comments using///
are otherwise treated as an error, so use this attribute or consider switching to block doc comments (/** */
). -
#[prefix_enum_doc_attributes]
combines the doc comment message on your enum itself with the messages for each variant, in the format “enum: variant”. When added to an enum, the doc comment on the enum becomes mandatory. When added to any other type, it has no effect.
-
-
In case you want to have an independent doc comment, the
#[displaydoc("...")
atrribute may be used on the variant or struct to override it.
§FAQ
-
Is this crate
no_std
compatible?- Yes! This crate implements the
core::fmt::Display
trait, not thestd::fmt::Display
trait, so it should work instd
andno_std
environments. Just adddefault-features = false
.
- Yes! This crate implements the
-
Does this crate work with
Path
andPathBuf
via theDisplay
trait?- Yuuup. This crate uses @dtolnay’s autoref specialization technique to add a special trait for types to get the display impl. It then specializes for
Path
andPathBuf
, and when either of these types are found, it callsself.display()
to get astd::path::Display<'_>
type which can be used with theDisplay
format specifier!
- Yuuup. This crate uses @dtolnay’s autoref specialization technique to add a special trait for types to get the display impl. It then specializes for
Derive Macros§
- Custom
#[derive(...)]
macro for implementingfmt::Display
via doc comment attributes.