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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! Procedural macros backing the `oopsie` error-handling crate.
//!
//! This crate provides the [`#[oopsie]`](macro@oopsie) attribute — the canonical
//! way to define an error type — and the underlying [`Oopsie`](derive@Oopsie)
//! derive. Both generate context selectors plus `Display` and `Error` impls; the
//! attribute additionally derives `Debug` and can inject diagnostic fields such
//! as backtraces, span traces, timestamps, and caller locations.
//!
//! Depend on the `oopsie` facade rather than this crate directly; the macros are
//! re-exported from there alongside the runtime they expand against.
pub
pub
pub
pub
/// Derive macro that generates context selectors, `Display`, and `Error` impls
/// for a struct or enum.
///
/// This is the engine the [`#[oopsie]`](macro@oopsie) attribute drives, and the
/// attribute is the canonical entry point. On top of this derive the attribute
/// also derives `Debug` for you and, with `traced`, injects the backtrace,
/// span-trace, and caller-location fields. Reach for the derive directly only
/// when you want to supply those pieces yourself; otherwise prefer the attribute.
///
/// # What gets generated
///
/// For each variant or struct, the derive produces a **context selector** — a struct
/// holding all fields except the source error and `#[oopsie(capture)]` fields.
///
/// - **Leaf** selectors (no source field) expose `.build()` and `.fail()`
/// (shorthand for `Err(self.build())`).
/// - **Source** selectors instead expose `.build_error(source)` via the
/// `Contextual` trait — they have no `.build()`.
///
/// All fields accept `Into<T>`, so `"str"` is accepted for `String` fields.
///
/// # Usage
///
/// ```ignore
/// use oopsie::ResultExt as _;
///
/// #[derive(Debug, oopsie::Oopsie)]
/// #[oopsie(module(false))]
/// pub enum MyError {
/// #[oopsie("Connection to {host} failed")]
/// Connect { host: String, source: std::io::Error },
/// }
///
/// # fn main() {
/// let result: Result<(), std::io::Error> = Err(std::io::Error::other("refused"));
/// let err = result.context(Connect { host: "db.example.com" }).unwrap_err();
/// assert_eq!(err.to_string(), "Connection to db.example.com failed");
/// # }
/// ```
///
/// See the [`oopsie`](https://docs.rs/oopsie) crate docs for the full attribute reference.
/// Attribute macro — the primary way to define an `oopsie` error type.
///
/// Generates context selectors, `Display`, `Error`, and `Debug` impls in one
/// attribute. No need for `#[derive(Debug, Oopsie)]`.
///
/// # Usage
///
/// ```ignore
/// use oopsie::ResultExt as _;
///
/// #[oopsie::oopsie]
/// pub enum MyError {
/// #[oopsie("Connection to {host} failed")]
/// Connect { host: String, source: std::io::Error },
/// }
///
/// # fn main() {
/// let result: Result<(), std::io::Error> = Err(std::io::Error::other("refused"));
/// let err = result.context(my_oopsies::Connect { host: "db.example.com" }).unwrap_err();
/// assert_eq!(err.to_string(), "Connection to db.example.com failed");
/// # }
/// ```
///
/// ## Diagnostics
///
/// Pass `traced` to automatically inject a backtrace field (and a span-trace when
/// the `tracing` feature is enabled):
///
/// ```ignore
/// #[oopsie::oopsie(traced)]
/// pub enum MyError {
/// #[oopsie("Connection failed")]
/// Connect,
/// }
/// # fn main() {}
/// ```
///
/// ## Parameters
///
/// The bare `#[oopsie]` adds no diagnostics; it is equivalent to
/// `#[derive(Debug, Oopsie)]`. The arguments below tune what gets generated;
/// each has its own subsection further down.
///
/// | Parameter | Effect |
/// |-----------|--------|
/// | `traced` | Inject a backtrace field (and a span-trace under the `tracing` feature), plus an auto error code |
/// | `path` | Path to the `oopsie` crate in generated impls |
/// | `debug` | Skip the automatic `Debug` derive |
///
///
/// ## `traced(...)` options
///
/// These keys are spelled nested inside `traced(...)`. `backtrace`/`spantrace`
/// take an optional settings block (`r#type`, `boxed`, `enabled`); `timestamp`
/// takes `chrono`/`provide`; `packed`/`boxed` are pair-level layout flags.
///
/// | Option | Effect |
/// |--------|--------|
/// | `backtrace` | Enable/tune the captured backtrace (default on) |
/// | `spantrace` | Enable/tune the captured span trace (default on; captures nothing without the `tracing` feature) |
/// | `timestamp` | Inject an auto-captured timestamp field (default off) |
/// | `location` | Inject an auto-captured call-site `Location` field (default on) |
/// | `packed` | Store both traces as one `(Backtrace, SpanTrace)` field |
/// | `boxed` | Box the injected trace field(s) |
/// | `code` | Tune (or disable) the auto error code |
/// | `chrono` | Use `chrono::DateTime<Local>` timestamps |
/// | `provide` | Expose the timestamp via the provider API |
/// | `r#type` | Override the injected type for this part |
/// | `enabled` | Explicit on/off inside a settings block |
///
///
/// With `traced`, every variant (or the struct itself) also gets an automatic
/// error code unless it is `transparent` or carries an explicit
/// `#[oopsie(code = "...")]`. The code is `module_path::Type` for structs and
/// `module_path::Type::Variant` for enum variants; `Report` renders it as
/// `Error[...]:` in the report header.
///
/// Container-level `#[oopsie(...)]` attributes (`module`, `vis`, `size`, etc.)
/// are placed on the type itself, not in the attribute macro's argument list.