wherr/lib.rs
1//! `wherr` crate provides a way to enhance Rust errors with file and line number information.
2//!
3//! The main struct `Wherr` represents an error containing additional metadata about where it originated from.
4//!
5//! The `wherr` attribute macro, defined in the `wherr_macro` crate, is re-exported here for ease of use.
6
7use std::fmt;
8
9// Re-export the procedural macro from the `wherr_macro` crate.
10pub use wherr_macro::wherr;
11
12#[cfg(feature = "anyhow")]
13use anyhow::Error as AnyhowError;
14
15#[cfg(feature = "anyhow")]
16type Wherror = AnyhowError;
17#[cfg(not(feature = "anyhow"))]
18type Wherror = Box<dyn std::error::Error>;
19
20/// Represents an error that includes file and line number metadata.
21///
22/// This error struct wraps around any error and provides a consistent interface to access the original error
23/// and the file and line where it originated from.
24pub struct Wherr {
25 pub inner: Wherror,
26 pub file: &'static str,
27 pub line: u32,
28}
29
30impl Wherr {
31 /// Create a new `Wherr` error from the given error, file, and line.
32 ///
33 /// # Parameters
34 /// * `err`: The original error to wrap.
35 /// * `file`: The file where the error occurred.
36 /// * `line`: The line number where the error occurred.
37 pub fn new(err: Wherror, file: &'static str, line: u32) -> Self {
38 Wherr {
39 inner: err,
40 file,
41 line,
42 }
43 }
44}
45
46impl fmt::Display for Wherr {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(
49 f,
50 "{}\nerror at {}:{}",
51 self.inner, self.file, self.line
52 )
53 }
54}
55
56impl fmt::Debug for Wherr {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 write!(
59 f,
60 "{:?}\nerror at {}:{}",
61 self.inner, self.file, self.line
62 )
63 }
64}
65
66impl std::error::Error for Wherr {}
67
68/// Utility function to wrap the given error into a `Wherr` struct, adding file and line number details.
69///
70/// # Parameters
71/// * `result`: The result containing the error to wrap.
72/// * `file`: The file where the error occurred.
73/// * `line`: The line number where the error occurred.
74///
75/// # Returns
76/// If the original error is already of type `Wherr`, it is returned as is.
77/// Otherwise, the original error is wrapped inside a `Wherr` and returned.
78pub fn wherrapper<T, E>(
79 result: Result<T, E>,
80 file: &'static str,
81 line: u32,
82) -> Result<T, Wherror>
83where
84 E: Into<Wherror>,
85{
86 match result {
87 Ok(val) => Ok(val),
88 Err(err) => {
89 let error: Wherror = err.into();
90 if error.is::<Wherr>() {
91 Err(error)
92 } else {
93 Err(Wherr::new(error, file, line).into())
94 }
95 }
96 }
97}