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}")]`&ensp;⟶&ensp;`write!("{}", self.var)`
//!     - `#[display("{0}")]`&ensp;⟶&ensp;`write!("{}", self.0)`
//!     - `#[display("{var:?}")]`&ensp;⟶&ensp;`write!("{:?}", self.var)`
//!     - `#[display("{0:?}")]`&ensp;⟶&ensp;`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};
}