1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
//! This library provides a convenient derive macro for the standard library's //! [`std::fmt::Display`] trait. displaythis is a fork of //! [thiserror](https://crates.io/crates/thiserror), modified for types that are //! not errors. //! //! [`std::fmt::Display`]: https://doc.rust-lang.org/std/fmt/trait.Display.html //! //! <br> //! //! # Example //! //! ```rust //! # use std::io; //! use displaythis::Display; //! //! #[derive(Display, Debug)] //! pub enum DataStoreError { //! #[display("data store disconnected")] //! Disconnect(io::Error), //! #[display("the data for key `{0}` is not available")] //! Redaction(String), //! #[display("invalid header (expected {expected:?}, found {found:?})")] //! InvalidHeader { //! expected: String, //! found: String, //! }, //! #[display("unknown data store error")] //! Unknown, //! } //! ``` //! //! <br> //! //! # Details //! //! - displaythis deliberately does not appear in your public API. You get the //! same thing as if you had written an implementation of `std::fmt::Display` //! by hand, and switching from handwritten impls to displaythis or vice versa //! is not a breaking change. //! //! - Types may be enums, structs with named fields, tuple structs, or unit //! structs. //! //! - You should provide //! `#[display("...")]` messages on the struct or each variant of your enum, as //! shown above in the example. //! //! The messages support a shorthand for interpolating fields from the error. //! //! - `#[display("{var}")]` ⟶ `write!("{}", self.var)` //! - `#[display("{0}")]` ⟶ `write!("{}", self.0)` //! - `#[display("{var:?}")]` ⟶ `write!("{:?}", self.var)` //! - `#[display("{0:?}")]` ⟶ `write!("{:?}", self.0)` //! //! These shorthands can be used together with any additional format args, //! which may be arbitrary expressions. For example: //! //! ```rust //! # use std::i32; //! # use displaythis::Display; //! # //! #[derive(Display, Debug)] //! pub enum Error { //! #[display("invalid rdo_lookahead_frames {0} (expected < {})", i32::MAX)] //! InvalidLookahead(u32), //! } //! ``` //! //! If one of the additional expression arguments needs to refer to a field of //! the struct or enum, then refer to named fields as `.var` and tuple fields //! as `.0`. //! //! ```rust //! # use displaythis::Display; //! # //! # fn first_char(s: &String) -> char { //! # s.chars().next().unwrap() //! # } //! # //! # #[derive(Debug)] //! # struct Limits { //! # lo: usize, //! # hi: usize, //! # } //! # //! #[derive(Display, Debug)] //! pub enum Error { //! #[display("first letter must be lowercase but was {:?}", first_char(.0))] //! WrongCase(String), //! #[display("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)] //! OutOfBounds { idx: usize, limits: Limits }, //! } //! ``` mod display; pub use displaythis_impl::*; // Not public API. #[doc(hidden)] pub mod private { pub use crate::display::{DisplayAsDisplay, PathAsDisplay}; }