tx5_core/
error.rs

1/// Tx5 core error type.
2#[derive(Clone)]
3pub struct Error {
4    /// Error identifier.
5    pub id: String,
6
7    /// Additional error information.
8    pub info: String,
9}
10
11impl From<String> for Error {
12    #[inline]
13    fn from(id: String) -> Self {
14        Self {
15            id,
16            info: String::default(),
17        }
18    }
19}
20
21impl From<&str> for Error {
22    #[inline]
23    fn from(id: &str) -> Self {
24        id.to_string().into()
25    }
26}
27
28impl From<Error> for std::io::Error {
29    #[inline]
30    fn from(e: Error) -> Self {
31        std::io::Error::other(e)
32    }
33}
34
35impl From<std::io::Error> for Error {
36    #[inline]
37    fn from(e: std::io::Error) -> Self {
38        let info = e.to_string();
39        if let Some(e) = e.into_inner() {
40            if let Ok(e) = e.downcast::<Error>() {
41                return *e;
42            }
43        }
44        Self {
45            id: "Error".into(),
46            info,
47        }
48    }
49}
50
51impl From<&std::io::Error> for Error {
52    #[inline]
53    fn from(e: &std::io::Error) -> Self {
54        if let Some(r) = e.get_ref() {
55            if let Some(r) = r.downcast_ref::<Error>() {
56                return r.clone();
57            }
58        }
59        Self {
60            id: "Error".into(),
61            info: e.to_string(),
62        }
63    }
64}
65
66impl Error {
67    /// Construct a new Tx5 core error instance with input as an identifier.
68    pub fn id<T>(t: T) -> std::io::Error
69    where
70        T: Into<String>,
71    {
72        Self {
73            id: t.into(),
74            info: String::default(),
75        }
76        .into()
77    }
78
79    /// Construct a new Tx5 core error instance with input as additional info.
80    pub fn err<E>(e: E) -> std::io::Error
81    where
82        E: Into<Box<dyn std::error::Error + Send + Sync>>,
83    {
84        Self {
85            id: "Error".into(),
86            info: e.into().to_string(),
87        }
88        .into()
89    }
90
91    /// Construct a new Tx5 core error instance with input as additional info.
92    pub fn str<S>(s: S) -> std::io::Error
93    where
94        S: Into<String>,
95    {
96        Self {
97            id: "Error".into(),
98            info: s.into(),
99        }
100        .into()
101    }
102}
103
104impl std::fmt::Display for Error {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        f.write_str(&self.id)?;
107        if !self.info.is_empty() {
108            f.write_str(": ")?;
109            f.write_str(&self.info)?;
110        }
111        Ok(())
112    }
113}
114
115impl std::fmt::Debug for Error {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        std::fmt::Display::fmt(self, f)
118    }
119}
120
121impl std::error::Error for Error {}
122
123/// Extension trait to extract a name from a Tx5 core error type.
124pub trait ErrorExt {
125    /// Get the identifier of this error type,
126    /// or the string representation.
127    fn id(&self) -> std::borrow::Cow<'_, str>;
128
129    /// Clone the error maintaining any meta info is available
130    /// if we are a tx5 error type.
131    fn err_clone(&self) -> std::io::Error;
132}
133
134impl ErrorExt for Error {
135    #[inline]
136    fn id(&self) -> std::borrow::Cow<'_, str> {
137        (&self.id).into()
138    }
139
140    #[inline]
141    fn err_clone(&self) -> std::io::Error {
142        self.clone().into()
143    }
144}
145
146impl ErrorExt for std::io::Error {
147    #[inline]
148    fn id(&self) -> std::borrow::Cow<'_, str> {
149        match self.get_ref() {
150            Some(r) => match r.downcast_ref::<Error>() {
151                Some(r) => (&r.id).into(),
152                None => r.to_string().into(),
153            },
154            None => self.to_string().into(),
155        }
156    }
157
158    #[inline]
159    fn err_clone(&self) -> std::io::Error {
160        Error::from(self).into()
161    }
162}
163
164#[doc(inline)]
165pub use std::io::Result;