This crate provides a convenient attribute macro that implements Display for you
[dependencies]
displaystr = "0.1"This crate has 0 dependencies. I think compile-times are very important, so I have put a lot of effort into optimizing them.
Apply #[display] on enums:
use displaystr::display;
#[display]
pub enum DataStoreError {
Disconnect(std::io::Error) = "data store disconnected",
Redaction(String) = "the data for key `{_0}` is not available",
InvalidHeader {
expected: String,
found: String,
} = "invalid header (expected {expected:?}, found {found:?})",
Unknown = "unknown data store error",
}The above expands to this:
use displaystr::display;
pub enum DataStoreError {
Disconnect(std::io::Error),
Redaction(String),
InvalidHeader {
expected: String,
found: String,
},
Unknown,
}
impl ::core::fmt::Display for DataStoreError {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Disconnect(_0) => {
f.write_fmt(format_args!("data store disconnected"))
}
Self::Redaction(_0) => {
f.write_fmt(format_args!("the data for key `{_0}` is not available"))
}
Self::InvalidHeader { expected, found } => {
f.write_fmt(format_args!("invalid header (expected {expected}, found {found})"))
}
Self::Unknown => {
f.write_fmt(format_args!("unknown data store error"))
}
}
}
}rustfmtformats it flawlesslyrust-analyzersupports hover and goto definition on the actual strings
Use #[display(doc)] to automatically generate /// comments:
use displaystr::display;
#[display(doc)]
pub enum DataStoreError {
Disconnect(std::io::Error) = "data store disconnected",
Redaction(String) = "the data for key `{_0}` is not available",
InvalidHeader {
expected: String,
found: String,
} = "invalid header (expected {expected:?}, found {found:?})",
Unknown = "unknown data store error",
}The above example's expands to this:
use displaystr::display;
pub enum DataStoreError {
/// data store disconnected
Disconnect(std::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,
}
// impl Display omitted since it's identical to the previous sectionYou can use a tuple to supply multiple arguments to the format_args!:
use displaystr::display;
#[display]
pub enum DataStoreError {
Redaction(String, Vec<String>) = (
"the data for key `{_0}` is not available, but we recovered: {}",
_1.join("+"),
),
}Expands to this:
use displaystr::display;
pub enum DataStoreError {
Redaction(String, Vec<String>),
}
impl ::core::fmt::Display for DataStoreError {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Self::Redaction(_0, _1) => f.write_fmt(format_args!(
"the data for key `{_0}` is not available, but we recovered: {}",
_1.join("+")
)),
}
}
}These 3 errors are identical.
displaystr expresses the same error in the most concise way while being significantly faster to compile (both "cold" compile times, and also each individual invocation)
use thiserror::Error;
use displaystr::display;
#[derive(Error, Debug)]
#[display]
pub enum DataStoreError {
Disconnect(#[from] io::Error) = "data store disconnected",
Redaction(String) = "the data for key `{_0}` is not available",
InvalidHeader {
expected: String,
found: String,
} = "invalid header (expected {expected:?}, found {found:?})",
Unknown = "unknown data store error",
}use thiserror::Error;
#[derive(Error, Debug)]
pub enum DataStoreError {
#[error("data store disconnected")]
Disconnect(#[from] io::Error),
#[error("the data for key `{0}` is not available")]
Redaction(String),
#[error("invalid header (expected {expected:?}, found {found:?})")]
InvalidHeader {
expected: String,
found: String,
},
#[error("unknown data store error")]
Unknown,
}use thiserror::Error;
use displaydoc::Display;
#[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,
}#[display]cannot be applied on generic types likeFoo<T>, because that significantly increases complexity of the parsing logic required, which also leads to much higher compile-times#[display]only applies toenums- Variants of enums marked with
#[display]cannot have discriminants