error_tools/error/mod.rs
1/// Define a private namespace for all its items.
2mod private
3{
4 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
5 pub use core::error::Error as ErrorTrait;
6
7 /// This trait allows adding extra context or information to an error, creating a tuple of the additional
8 /// context and the original error. This is particularly useful for error handling when you want to include
9 /// more details in the error without losing the original error value.
10 ///
11 /// The `ErrWith` trait provides methods to wrap an error with additional context, either by using a closure
12 /// that generates the context or by directly providing the context.
13 ///
14 pub trait ErrWith< ReportErr, ReportOk, E >
15 {
16 /// Takes a closure `f` that returns a value of type `ReportErr`, and uses it to wrap an error of type `(ReportErr, E)`
17 /// in the context of a `Result` of type `ReportOk`.
18 ///
19 /// This method allows you to add additional context to an error by providing a closure that generates the context.
20 ///
21 /// # Arguments
22 ///
23 /// * `f` - A closure that returns the additional context of type `ReportErr`.
24 ///
25 /// # Returns
26 ///
27 /// A `Result` of type `ReportOk` if the original result is `Ok`, or a tuple `(ReportErr, E)` containing the additional
28 /// context and the original error if the original result is `Err`.
29 ///
30 /// # Errors
31 ///
32 /// qqq: errors
33 ///
34 /// # Example
35 ///
36 /// ```rust
37 /// use error_tools::ErrWith;
38 /// let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) );
39 /// let result_with_context : Result< (), ( &str, std::io::Error ) > = result.err_with( || "additional context" );
40 /// ```
41 fn err_with< F >( self, f : F ) -> core::result::Result< ReportOk, ( ReportErr, E ) >
42 where
43 F : FnOnce() -> ReportErr;
44
45 /// Takes a reference to a `ReportErr` value and uses it to wrap an error of type `(ReportErr, E)`
46 /// in the context of a `Result` of type `ReportOk`.
47 ///
48 /// This method allows you to add additional context to an error by providing a reference to the context.
49 ///
50 /// # Arguments
51 ///
52 /// * `report` - A reference to the additional context of type `ReportErr`.
53 ///
54 /// # Returns
55 ///
56 /// A `Result` of type `ReportOk` if the original result is `Ok`, or a tuple `(ReportErr, E)` containing the additional
57 /// context and the original error if the original result is `Err`.
58 ///
59 /// # Errors
60 ///
61 /// qqq: Errors
62 ///
63 /// # Example
64 ///
65 /// ```rust
66 /// use error_tools::ErrWith;
67 /// let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) );
68 /// let report = "additional context";
69 /// let result_with_report : Result< (), ( &str, std::io::Error ) > = result.err_with_report( &report );
70 /// ```
71 fn err_with_report( self, report : &ReportErr ) -> core::result::Result< ReportOk, ( ReportErr, E ) >
72 where
73 ReportErr : Clone;
74
75 }
76
77 impl< ReportErr, ReportOk, E, IntoError > ErrWith< ReportErr, ReportOk, E >
78 for core::result::Result< ReportOk, IntoError >
79 where
80 IntoError : Into< E >,
81 {
82
83 #[ allow( clippy::implicit_return, clippy::min_ident_chars ) ]
84 #[ inline ]
85 fn err_with< F >( self, f : F ) -> core::result::Result< ReportOk, ( ReportErr, E ) >
86 where
87 F : FnOnce() -> ReportErr,
88 {
89 self.map_err( | error | ( f(), error.into() ) )
90 }
91
92 #[ inline( always ) ]
93 #[ allow( clippy::implicit_return ) ]
94 fn err_with_report( self, report : &ReportErr ) -> core::result::Result< ReportOk, ( ReportErr, E ) >
95 where
96 ReportErr : Clone,
97 Self : Sized,
98 {
99 self.map_err( | error | ( report.clone(), error.into() ) )
100 }
101
102 }
103
104 /// A type alias for a `Result` that contains an error which is a tuple of a report and an original error.
105 ///
106 /// This is useful when you want to report additional information along with an error. The `ResultWithReport` type
107 /// helps in defining such results more concisely.
108 pub type ResultWithReport< Report, Error > = Result< Report, ( Report, Error ) >;
109
110// ///
111// /// Macro to generate an error descriptor.
112// ///
113// /// ### Basic use-case.
114// /// ```rust
115// /// # use error_tools::{ BasicError, err };
116// /// fn f1() -> BasicError
117// /// {
118// /// return err!( "No attr" );
119// /// }
120// /// ```
121// ///
122//
123// #[ macro_export ]
124// macro_rules! err
125// {
126//
127// ( $msg : expr ) =>
128// {
129// $crate::BasicError::new( $msg ).into()
130// };
131// ( $msg : expr, $( $arg : expr ),+ $(,)? ) =>
132// {
133// $crate::BasicError::new( format!( $msg, $( $arg ),+ ) ).into()
134// };
135//
136// }
137//
138// ///
139// /// Macro to return an Err( error ) generating error descriptor.
140// ///
141// /// ### Basic use-case.
142// /// ```rust
143// /// # use error_tools::{ BasicError, return_err };
144// /// fn f1() -> Result< (), BasicError >
145// /// {
146// /// return_err!( "No attr" );
147// /// }
148// /// ```
149// ///
150//
151// #[ macro_export ]
152// macro_rules! return_err
153// {
154//
155// ( $msg : expr ) =>
156// {
157// return Result::Err( $crate::err!( $msg ) )
158// };
159// ( $msg : expr, $( $arg : expr ),+ $(,)? ) =>
160// {
161// return Result::Err( $crate::err!( $msg, $( $arg ),+ ) )
162// };
163//
164// }
165//
166// // zzz : review
167// // xxx : rid of
168//
169// /// baic implementation of generic BasicError
170//
171// #[ derive( core::fmt::Debug, core::clone::Clone, core::cmp::PartialEq, core::cmp::Eq ) ]
172// pub struct BasicError
173// {
174// msg : String,
175// }
176//
177// impl BasicError
178// {
179// /// Constructor expecting message with description.
180// pub fn new< Msg : Into< String > >( msg : Msg ) -> BasicError
181// {
182// BasicError { msg : msg.into() }
183// }
184// /// Message with description getter.
185// pub fn msg( &self ) -> &String
186// {
187// &self.msg
188// }
189// }
190//
191// impl core::fmt::Display for BasicError
192// {
193// fn fmt(&self, f: &mut core::fmt::Formatter< '_ >) -> core::fmt::Result
194// {
195// write!( f, "{}", self.msg )
196// }
197// }
198//
199// impl ErrorTrait for BasicError
200// {
201// fn description( &self ) -> &str
202// {
203// &self.msg
204// }
205// }
206//
207// impl< T > From< BasicError > for Result< T, BasicError >
208// {
209// /// Returns the argument unchanged.
210// #[ inline( always ) ]
211// fn from( src : BasicError ) -> Self
212// {
213// Result::Err( src )
214// }
215// }
216//
217// pub use err;
218// pub use return_err;
219
220 // qqq : write standard mod interface without using mod_interface /* aaa : Dmytro : added to each library file */
221}
222
223/// Assertions.
224#[ cfg( feature = "enabled" ) ]
225pub mod assert;
226
227#[ cfg( feature = "enabled" ) ]
228#[ cfg( feature = "error_typed" ) ]
229/// Typed exceptions handling mechanism.
230pub mod typed;
231
232#[ cfg( feature = "enabled" ) ]
233#[ cfg( feature = "error_untyped" ) ]
234/// Untyped exceptions handling mechanism.
235pub mod untyped;
236
237#[ cfg( feature = "enabled" ) ]
238#[ doc( inline ) ]
239#[ allow( unused_imports ) ]
240#[ allow( clippy::pub_use ) ]
241pub use own::*;
242
243/// Own namespace of the module.
244#[ cfg( feature = "enabled" ) ]
245#[ allow( unused_imports ) ]
246pub mod own
247{
248 #[ allow( clippy::wildcard_imports ) ]
249 use super::*;
250
251 #[ doc( inline ) ]
252 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
253 pub use orphan::*;
254
255 #[ doc( inline ) ]
256 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
257 pub use assert::orphan::*;
258
259 #[ cfg( feature = "error_untyped" ) ]
260 #[ doc( inline ) ]
261 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
262 pub use untyped::orphan::*;
263
264 #[ cfg( feature = "error_typed" ) ]
265 #[ doc( inline ) ]
266 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
267 pub use typed::orphan::*;
268
269 #[ doc( inline ) ]
270 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
271 pub use private::
272 {
273 // err,
274 // return_err,
275 ErrorTrait,
276 // BasicError,
277 };
278
279 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
280 pub use super::assert;
281 #[ cfg( feature = "error_typed" ) ]
282 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
283 pub use super::typed;
284 #[ cfg( feature = "error_untyped" ) ]
285 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
286 pub use super::untyped;
287
288}
289
290/// Shared with parent namespace of the module
291#[ cfg( feature = "enabled" ) ]
292#[ allow( unused_imports ) ]
293pub mod orphan
294{
295 #[ allow( clippy::wildcard_imports ) ]
296 use super::*;
297 #[ doc( inline ) ]
298 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
299 pub use exposed::*;
300}
301
302/// Exposed namespace of the module.
303#[ cfg( feature = "enabled" ) ]
304#[ allow( unused_imports ) ]
305pub mod exposed
306{
307 #[ allow( clippy::wildcard_imports ) ]
308 use super::*;
309
310 #[ doc( inline ) ]
311 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
312 pub use prelude::*;
313
314 // Expose itself.
315 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
316 pub use super::super::error;
317
318 #[ doc( inline ) ]
319 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
320 pub use private::
321 {
322 ErrWith,
323 ResultWithReport,
324 };
325
326 #[ doc( inline ) ]
327 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
328 pub use assert::exposed::*;
329
330 #[ cfg( feature = "error_untyped" ) ]
331 #[ doc( inline ) ]
332 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
333 pub use untyped::exposed::*;
334
335 #[ cfg( feature = "error_typed" ) ]
336 #[ doc( inline ) ]
337 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
338 pub use typed::exposed::*;
339
340}
341
342/// Prelude to use essentials: `use my_module::prelude::*`.
343#[ cfg( feature = "enabled" ) ]
344#[ allow( unused_imports ) ]
345pub mod prelude
346{
347 #[ allow( clippy::wildcard_imports ) ]
348 use super::*;
349
350 // #[ doc( inline ) ]
351 // pub use private::
352 // {
353 // // err,
354 // // return_err,
355 // ErrorTrait,
356 // // BasicError,
357 // };
358
359 #[ doc( inline ) ]
360 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
361 pub use assert::prelude::*;
362
363 #[ cfg( feature = "error_untyped" ) ]
364 #[ doc( inline ) ]
365 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
366 pub use untyped::prelude::*;
367
368 #[ cfg( feature = "error_typed" ) ]
369 #[ doc( inline ) ]
370 #[ allow( clippy::useless_attribute, clippy::pub_use ) ]
371 pub use typed::prelude::*;
372
373}