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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Declarative error derivation with `no_std` support and zero allocation in
//! generated runtime code.
//!
//! `fack` generates `Display`, `Error`, and optional `From` implementations
//! from `#[error(...)]` declarations.
//!
//! # Quick start
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error("file not found {path}")]
//! struct FileError {
//! path: String,
//! }
//! ```
//!
//! # Formatting
//!
//! Named and tuple fields can be captured directly. Explicit Rust format
//! arguments are also supported.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error("invalid input {input:?}")]
//! struct InputError {
//! input: String,
//! }
//!
//! #[derive(Error, Debug)]
//! #[error("invalid value {0}")]
//! struct ValueError(i32);
//! ```
//!
//! A custom formatter can be selected when a format string is not the right
//! abstraction.
//!
//! ```rust
//! # use fack::prelude::*;
//! fn render(error: &RenderedError, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
//! let RenderedError { code } = error;
//! write!(f, "rendered {code}")
//! }
//!
//! #[derive(Error, Debug)]
//! #[error(display(render))]
//! struct RenderedError {
//! code: u8,
//! }
//! ```
//!
//! # Sources
//!
//! `#[error(source(field))]` exposes the selected field as the ordinary source.
//! Direct, boxed, optional, and optional boxed source fields are supported.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error("request failed")]
//! #[error(source(io))]
//! struct RequestError {
//! io: std::io::Error,
//! url: String,
//! }
//! ```
//!
//! `#[error(transparent(field))]` requires exactly one non-optional field.
//! Display forwards to that field and source chaining forwards through the
//! field's own `Error::source` implementation.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error(transparent(0))]
//! struct Wrapper(std::io::Error);
//! ```
//!
//! # Conversion
//!
//! `#[error(from)]` requires exactly one field. It generates `From<T>` and
//! makes that field the ordinary error source.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! enum AppError {
//! #[error("io error")]
//! #[error(from)]
//! Io(std::io::Error),
//!
//! #[error("parse error")]
//! #[error(from)]
//! Parse(std::num::ParseIntError),
//! }
//! ```
//!
//! # Generation options
//!
//! Without an inline declaration, generated methods receive no explicit inline
//! attribute. `#[error(inline)]` and `#[error(inline(neutral))]` emit ordinary
//! `#[inline]`. The `always` and `never` strategies emit their corresponding
//! Rust attributes.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error(inline(never))]
//! #[error("rare error")]
//! struct RareError;
//! ```
//!
//! Generated paths use `::core` by default. `#[error(import(path))]` selects a
//! different root.
//!
//! ```rust
//! # use fack::prelude::*;
//! #[derive(Error, Debug)]
//! #[error(import(::std))]
//! #[error("standard error")]
//! struct StdError;
//! ```
//!
//! Enum-wide generation options belong on the enum. Display, source,
//! transparency, and conversion declarations belong on variants.
//!
//! # Generated code guarantees
//!
//! Generated implementations contain no unsafe code and allocate nothing at
//! runtime. Formatting and source bounds are added only where the generated
//! implementation requires them.