displaystr

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.
Example
Apply #[display]
on enum
s:
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"))
}
}
}
}
IDE Support
rustfmt
formats it flawlessly
rust-analyzer
supports hover and goto definition on the actual strings
Auto-generated doc comments
Use #[display(doc)]
to automatically generate ///
comments. The above example's expansion enum
would generate this:
use displaystr::display;
pub enum DataStoreError {
Disconnect(std::io::Error),
Redaction(String),
InvalidHeader {
expected: String,
found: String,
},
Unknown,
}
Multiple arguments
You 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("+")
)),
}
}
}
Comparison between displaystr
, thiserror
and displaydoc
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)
displaystr
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",
}
thiserror
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,
}
displaydoc
use thiserror::Error;
use displaydoc::Display;
#[derive(Display, Error, Debug)]
pub enum DataStoreError {
Disconnect(#[source] io::Error),
Redaction(String),
InvalidHeader {
expected: String,
found: String,
},
Unknown,
}