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}