Bug: 312432303

Clone this repo:
  1. 6f7d8b1 Migrate 25 crates to monorepo. am: d1184ee72e by James Farrell · 3 months ago main
  2. d1184ee Migrate 25 crates to monorepo. by James Farrell · 3 months ago
  3. 201ae3b Update Android.bp by running cargo_embargo am: be4555a590 by James Farrell · 4 months ago
  4. be4555a Update Android.bp by running cargo_embargo by James Farrell · 4 months ago
  5. 13d78b8 Cleanup license metadata in external/rust/crates/displaydoc. am: 58af59da8a by Wei Li · 4 months ago

derive(Display) /// From<docs>

Latest Version Rust Documentation

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][std::error::Error] derive macro from thiserror, to propagate source locations from [io::Error][std::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][std::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. The Display 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][crate::Display#generic-type-parameters]:
/// 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

  1. Is this crate no_std compatible?

    • Yes! This crate implements the core::fmt::Display trait, not the [std::fmt::Display] trait, so it should work in std and no_std environments. Just add default-features = false.
  2. Does this crate work with Path and PathBuf via the Display 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 and PathBuf, and when either of these types are found, it calls self.display() to get a std::path::Display<'_> type which can be used with the Display format specifier!

License