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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
//! Bidirectional integration with the [`error-stack`] 0.6.x error handling
//! library.
//!
//! This module specifically supports `error-stack` version 0.6.x. To enable
//! this integration, add the `compat-error-stack06` feature flag to your
//! `Cargo.toml`.
//!
//! # Overview
//!
//! This module provides seamless interoperability between rootcause [`Report`]s
//! and [`error_stack::Report`], supporting conversions in both directions.
//! This is useful when:
//! - Migrating from error-stack to rootcause incrementally
//! - Working with libraries that use error-stack for error handling
//! - Integrating rootcause into an existing error-stack-based codebase
//! - Calling error-stack-based APIs from rootcause code (and vice versa)
//!
//! Conversions preserve error information and formatting, allowing you to mix
//! both error handling approaches seamlessly.
//!
//! # Converting from error-stack to Rootcause
//!
//! Use the [`IntoRootcause`] trait to convert error-stack
//! reports into rootcause reports:
//!
//! ```
//! use std::io;
//!
//! use rootcause::prelude::*;
//!
//! fn error_stack_function() -> Result<String, error_stack::Report<io::Error>> {
//! Err(error_stack::report!(io::Error::from(
//! io::ErrorKind::NotFound
//! )))
//! }
//!
//! fn rootcause_function() -> Result<String, Report> {
//! // Convert error_stack result to rootcause result
//! let value = error_stack_function().into_rootcause()?;
//! Ok(value)
//! }
//! ```
//!
//! You can also convert individual [`error_stack::Report`] values:
//!
//! ```
//! use rootcause::prelude::*;
//!
//! let es_report = error_stack::report!(std::io::Error::from(std::io::ErrorKind::NotFound));
//! let report: Report<_> = es_report.into_rootcause();
//!
//! // The report preserves error-stack's formatting
//! println!("{}", report);
//! ```
//!
//! # Converting from Rootcause to error-stack
//!
//! Use the [`IntoErrorStack`] trait to convert rootcause reports into
//! error-stack reports:
//!
//! ```
//! use rootcause::{compat::error_stack06::IntoErrorStack, prelude::*};
//!
//! fn rootcause_function() -> Result<String, Report> {
//! Err(report!("database connection failed"))
//! }
//!
//! // The ? operator automatically converts Result<T, Report> to Result<T, error_stack::Report>
//! fn error_stack_function()
//! -> Result<String, error_stack::Report<rootcause::compat::ReportAsError>> {
//! rootcause_function().into_error_stack()?;
//! Ok("success".to_string())
//! }
//! ```
//!
//! You can also convert individual [`Report`] values:
//!
//! ```
//! use rootcause::{compat::error_stack06::IntoErrorStack, prelude::*};
//!
//! let report = report!("operation failed").attach("debug info");
//! let es_report: error_stack::Report<_> = report.into_error_stack();
//!
//! // The error-stack report preserves the report's formatting
//! println!("{}", es_report);
//! ```
//!
//! Or using the `From` trait directly:
//!
//! ```
//! use rootcause::prelude::*;
//!
//! let report: Report = report!("operation failed");
//! let es_report: error_stack::Report<_> = report.into();
//!
//! // The error-stack report preserves the report's formatting
//! println!("{}", es_report);
//! ```
//!
//! The `From` trait also works with the `?` operator for automatic conversion:
//!
//! ```
//! use rootcause::prelude::*;
//!
//! fn rootcause_function() -> Result<String, Report> {
//! Err(report!("something failed"))
//! }
//!
//! fn error_stack_function()
//! -> Result<String, error_stack::Report<rootcause::compat::ReportAsError>> {
//! // The ? operator automatically converts Report to error_stack::Report
//! rootcause_function()?;
//! Ok("success".to_string())
//! }
//! ```
//!
//! # Handler Behavior
//!
//! The [`ErrorStackHandler`] delegates to error-stack's own formatting
//! implementation, ensuring that converted reports display exactly as they
//! would in pure error-stack code. This includes:
//! - Display formatting via [`error_stack::Report`]'s `Display` implementation
//! - Debug formatting via [`error_stack::Report`]'s `Debug` implementation
//! - Source chain navigation via the context's `source` method
//!
//! When converting from rootcause to error-stack, the entire [`Report`]
//! structure (including all contexts and attachments) is preserved and
//! formatted according to rootcause's formatting rules.
//!
//! [`error-stack`]: error_stack
use PhantomData;
use ContextHandler;
use crate::;
/// A custom handler for [`error_stack::Report`] that delegates to
/// error-stack's own formatting.
///
/// This handler ensures that [`error_stack::Report`] objects display
/// identically whether they're used directly or wrapped in a rootcause
/// [`Report`]. You typically don't need to use this handler directly - it's
/// used automatically by the [`IntoRootcause`] trait.
///
/// # Implementation Details
///
/// - **Display**: Uses [`error_stack::Report`]'s `Display` implementation
/// - **Debug**: Uses [`error_stack::Report`]'s `Debug` implementation
/// - **Source**: Uses the current context's `source` method to traverse the
/// error chain
/// - **Formatting style**: Matches the report's formatting function (Display or
/// Debug)
///
/// # Examples
///
/// ```
/// use rootcause::{Report, compat::error_stack06::ErrorStackHandler};
///
/// let es_report = error_stack::Report::new(std::io::Error::from(std::io::ErrorKind::NotFound));
/// let report: Report<_> = Report::new_custom::<ErrorStackHandler<_>>(es_report);
/// ```
///
/// # Type Parameters
///
/// - `C`: The context type of the error-stack report, which must implement
/// `Error + Send + Sync + 'static`
;
/// A trait for converting rootcause [`Report`]s into [`error_stack::Report`].
///
/// This trait provides the `.into_error_stack()` method for converting
/// rootcause reports into error-stack reports. It's implemented for both
/// [`Report`] and [`Result<T, Report>`], making it easy to call
/// error-stack-based APIs from rootcause code.
///
/// The conversion wraps the entire report structure inside an
/// [`error_stack::Report`], preserving all contexts, attachments, and
/// formatting behavior.
///
/// # Examples
///
/// ## Converting a Result
///
/// ```
/// use rootcause::{compat::error_stack06::IntoErrorStack, prelude::*};
///
/// fn uses_rootcause() -> Result<i32, Report> {
/// Err(report!("failed"))
/// }
///
/// fn uses_error_stack() -> Result<i32, error_stack::Report<rootcause::compat::ReportAsError>> {
/// let value = uses_rootcause().into_error_stack()?;
/// Ok(value)
/// }
/// ```
///
/// ## Converting a Report
///
/// ```
/// use rootcause::{compat::error_stack06::IntoErrorStack, prelude::*};
///
/// let report = report!("operation failed").attach("debug info");
/// let es_report: error_stack::Report<_> = report.into_error_stack();
///
/// // The error-stack report displays the full rootcause structure
/// println!("{}", es_report);
/// ```
///
/// ## Using `From` Instead
///
/// You can also use the `From` trait for explicit conversions:
///
/// ```
/// use rootcause::prelude::*;
///
/// let report: Report = report!("error");
/// let es_report: error_stack::Report<_> = report.into();
/// ```
///
/// # Type Parameters
///
/// - `C`: The context type parameter of the rootcause report. When converting,
/// the report will be wrapped as an
/// [`error_stack::Report<ReportAsError<C>>`].