# `displaystr`
[](https://crates.io/crates/displaystr)
[](https://docs.rs/displaystr)


[](https://github.com/nik-rev/displaystr)
This crate provides a convenient attribute macro that implements [`Display`](https://doc.rust-lang.org/stable/core/fmt/trait.Display.html) for you
```toml
[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:
```rust
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:
```rust
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:
```rust
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:
```rust
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 section
```
## Multiple arguments
You can use a tuple to supply multiple arguments to the `format_args!`:
```rust
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:
```rust
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("+")
)),
}
}
}
```
## Notes
- `#[display]` cannot be applied on generic types like `Foo<T>`, because that **significantly** increases complexity of the parsing logic required, which also leads to much higher compile-times
- `#[display]` only applies to `enum`s
## 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`
```rust
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`
```rust
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`
```rust
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,
}
```