rstsr_common/
error.rs

1#[cfg(feature = "std")]
2extern crate std;
3
4extern crate alloc;
5
6use crate::prelude_dev::*;
7use alloc::collections::TryReserveError;
8use core::alloc::LayoutError;
9use core::convert::Infallible;
10use core::num::TryFromIntError;
11use derive_builder::UninitializedFieldError;
12
13#[non_exhaustive]
14#[derive(Debug)]
15pub enum RSTSRError {
16    ValueOutOfRange(String),
17    InvalidValue(String),
18    InvalidLayout(String),
19    RuntimeError(String),
20    DeviceMismatch(String),
21    UnImplemented(String),
22    MemoryError(String),
23
24    TryFromIntError(String),
25    Infallible,
26
27    BuilderError(UninitializedFieldError),
28    DeviceError(String),
29    RayonError(String),
30
31    ErrorCode(i32, String),
32    FaerError(String),
33
34    Miscellaneous(String),
35}
36
37#[cfg(feature = "backtrace")]
38#[derive(Debug)]
39pub struct RSTSRBacktrace(pub std::backtrace::Backtrace);
40#[cfg(not(feature = "backtrace"))]
41#[derive(Debug)]
42pub struct RSTSRBacktrace;
43
44#[cfg(feature = "backtrace")]
45impl core::fmt::Display for RSTSRBacktrace {
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        write!(f, "{:}", self.0)
48    }
49}
50
51#[cfg(not(feature = "backtrace"))]
52impl core::fmt::Display for RSTSRBacktrace {
53    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54        write!(f, "Backtrace feature in RSTSR is disabled.")
55    }
56}
57
58#[derive(Debug)]
59pub struct Error {
60    pub inner: RSTSRError,
61    pub backtrace: Option<RSTSRBacktrace>,
62}
63
64pub fn rstsr_backtrace() -> Option<RSTSRBacktrace> {
65    #[cfg(feature = "backtrace")]
66    {
67        extern crate std;
68        let bt = std::backtrace::Backtrace::capture();
69        Some(RSTSRBacktrace(bt))
70    }
71    #[cfg(not(feature = "backtrace"))]
72    {
73        None
74    }
75}
76
77impl core::fmt::Display for Error {
78    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
79        Debug::fmt(self, f)
80    }
81}
82
83#[cfg(feature = "std")]
84impl std::error::Error for Error {}
85
86pub type Result<T> = core::result::Result<T, Error>;
87
88pub trait RSTSRResultAPI<T> {
89    fn rstsr_unwrap(self) -> T;
90}
91
92impl<T> RSTSRResultAPI<T> for Result<T> {
93    #[allow(unused_variables)]
94    fn rstsr_unwrap(self) -> T {
95        match self {
96            Ok(v) => v,
97            Err(e) => {
98                let Error { inner, backtrace } = &e;
99                #[cfg(feature = "backtrace")]
100                {
101                    extern crate std;
102                    if let Some(backtrace) = backtrace {
103                        std::eprintln!("\n====== RSTSR Backtrace ======\n{:}", backtrace);
104                    }
105                    panic!("RSTSR Error: {:?}", inner)
106                }
107                #[cfg(not(feature = "backtrace"))]
108                {
109                    panic!("RSTSR Error (backtrace disabled): {:?}", inner)
110                }
111            },
112        }
113    }
114}
115
116impl From<TryFromIntError> for Error {
117    fn from(e: TryFromIntError) -> Self {
118        Error { inner: RSTSRError::TryFromIntError(format!("{e:?}")), backtrace: rstsr_backtrace() }
119    }
120}
121
122impl From<Infallible> for Error {
123    fn from(_: Infallible) -> Self {
124        Error { inner: RSTSRError::Infallible, backtrace: rstsr_backtrace() }
125    }
126}
127
128#[cfg(feature = "rayon")]
129impl From<rayon::ThreadPoolBuildError> for Error {
130    fn from(e: rayon::ThreadPoolBuildError) -> Self {
131        Error { inner: RSTSRError::RayonError(format!("{e:?}")), backtrace: rstsr_backtrace() }
132    }
133}
134
135impl From<UninitializedFieldError> for Error {
136    fn from(e: UninitializedFieldError) -> Self {
137        Error { inner: RSTSRError::BuilderError(e), backtrace: rstsr_backtrace() }
138    }
139}
140
141impl From<TryReserveError> for Error {
142    fn from(e: TryReserveError) -> Self {
143        Error { inner: RSTSRError::MemoryError(format!("{e:?}")), backtrace: rstsr_backtrace() }
144    }
145}
146
147impl From<LayoutError> for Error {
148    fn from(e: LayoutError) -> Self {
149        Error { inner: RSTSRError::MemoryError(format!("{e:?}")), backtrace: rstsr_backtrace() }
150    }
151}
152
153#[macro_export]
154macro_rules! backtrace {
155    () => {{
156        #[cfg(feature = "backtrace")]
157        {
158            extern crate std;
159            let bt = std::backtrace::Backtrace::capture();
160            format!("\nBacktrace:\n{:}", bt)
161        }
162        #[cfg(not(feature = "backtrace"))]
163        {
164            String::new()
165        }
166    }};
167}
168
169#[macro_export]
170macro_rules! rstsr_assert {
171    ($cond:expr, $errtype:ident) => {
172        if $cond {
173            Ok(())
174        } else {
175            use $crate::prelude_dev::*;
176            let mut s = String::new();
177            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
178            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
179            write!(s, " : {:}", stringify!($cond)).unwrap();
180            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
181        }
182    };
183    ($cond:expr, $errtype:ident, $($arg:tt)*) => {{
184        if $cond {
185            Ok(())
186        } else {
187            use $crate::prelude_dev::*;
188            let mut s = String::new();
189            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
190            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
191            write!(s, " : ").unwrap();
192            write!(s, $($arg)*).unwrap();
193            write!(s, " : {:}", stringify!($cond)).unwrap();
194            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
195        }
196    }};
197}
198
199#[macro_export]
200macro_rules! rstsr_assert_eq {
201    ($lhs:expr, $rhs:expr, $errtype:ident) => {
202        if $lhs == $rhs {
203            Ok(())
204        } else {
205            use $crate::prelude_dev::*;
206            let mut s = String::new();
207            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
208            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
209            write!(
210                s,
211                " : {:} = {:?} not equal to {:} = {:?}",
212                stringify!($lhs),
213                $lhs,
214                stringify!($rhs),
215                $rhs
216            )
217            .unwrap();
218            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
219        }
220    };
221    ($lhs:expr, $rhs:expr, $errtype:ident, $($arg:tt)*) => {
222        if $lhs == $rhs {
223            Ok(())
224        } else {
225            use $crate::prelude_dev::*;
226            let mut s = String::new();
227            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
228            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
229            write!(s, " : ").unwrap();
230            write!(s, $($arg)*).unwrap();
231            write!(
232                s,
233                " : {:} = {:?} not equal to {:} = {:?}",
234                stringify!($lhs),
235                $lhs,
236                stringify!($rhs),
237                $rhs
238            )
239            .unwrap();
240            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
241        }
242    };
243}
244
245#[macro_export]
246macro_rules! rstsr_invalid {
247    ($word:expr) => {{
248        use core::fmt::Write;
249        let mut s = String::new();
250        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
251        write!(s, "Error::InvalidValue").unwrap();
252        write!(s, " : {:?} = {:?}", stringify!($word), $word).unwrap();
253        Err(Error{ inner: RSTSRError::InvalidValue(s), backtrace: rstsr_backtrace() })
254    }};
255    ($word:expr, $($arg:tt)*) => {{
256        use core::fmt::Write;
257        let mut s = String::new();
258        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
259        write!(s, "Error::InvalidValue").unwrap();
260        write!(s, " : {:?} = {:?}", stringify!($word), $word).unwrap();
261        write!(s, " : ").unwrap();
262        write!(s, $($arg)*).unwrap();
263        Err(Error{ inner: RSTSRError::InvalidValue(s), backtrace: rstsr_backtrace() })
264    }};
265}
266
267#[macro_export]
268macro_rules! rstsr_errcode {
269    ($word:expr) => {{
270        use core::fmt::Write;
271        let mut s = String::new();
272        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
273        write!(s, "Error::ErrorCode").unwrap();
274        write!(s, " : {:?}", $word).unwrap();
275        Err(Error{ inner: RSTSRError::ErrorCode($word, s), backtrace: rstsr_backtrace() })
276    }};
277    ($word:expr, $($arg:tt)*) => {{
278        use core::fmt::Write;
279        let mut s = String::new();
280        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
281        write!(s, "Error::ErrorCode").unwrap();
282        write!(s, " : {:?}", $word).unwrap();
283        write!(s, " : ").unwrap();
284        write!(s, $($arg)*).unwrap();
285        Err(Error{ inner: RSTSRError::ErrorCode($word, s), backtrace: rstsr_backtrace() })
286    }};
287}
288
289#[macro_export]
290macro_rules! rstsr_error {
291    ($errtype:ident) => {{
292        use $crate::prelude_dev::*;
293        let mut s = String::new();
294        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
295        write!(s, concat!("Error::", stringify!($errtype))).unwrap();
296        Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() }
297    }};
298    ($errtype:ident, $($arg:tt)*) => {{
299        use $crate::prelude_dev::*;
300        let mut s = String::new();
301        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
302        write!(s, concat!("Error::", stringify!($errtype))).unwrap();
303        write!(s, " : ").unwrap();
304        write!(s, $($arg)*).unwrap();
305        Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() }
306    }};
307}
308
309#[macro_export]
310macro_rules! rstsr_raise {
311    ($errtype:ident) => {{
312        use $crate::prelude_dev::*;
313        let mut s = String::new();
314        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
315        write!(s, concat!("Error::", stringify!($errtype))).unwrap();
316        Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
317    }};
318    ($errtype:ident, $($arg:tt)*) => {{
319        use $crate::prelude_dev::*;
320        let mut s = String::new();
321        write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
322        write!(s, concat!("Error::", stringify!($errtype))).unwrap();
323        write!(s, " : ").unwrap();
324        write!(s, $($arg)*).unwrap();
325        Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
326    }};
327}
328
329#[macro_export]
330macro_rules! rstsr_pattern {
331    ($value:expr, $pattern:expr, $errtype:ident) => {
332        if ($pattern).contains(&($value)) {
333            Ok(())
334        } else {
335            use $crate::prelude_dev::*;
336            let mut s = String::new();
337            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
338            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
339            write!(
340                s,
341                " : {:?} = {:?} not match to pattern {:} = {:?}",
342                stringify!($value),
343                $value,
344                stringify!($pattern),
345                $pattern
346            )
347            .unwrap();
348            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
349        }
350    };
351    ($value:expr, $pattern:expr, $errtype:ident, $($arg:tt)*) => {
352        if ($pattern).contains(&($value)) {
353            Ok(())
354        } else {
355            use $crate::prelude_dev::*;
356            let mut s = String::new();
357            write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
358            write!(s, concat!("Error::", stringify!($errtype))).unwrap();
359            write!(s, " : ").unwrap();
360            write!(s, $($arg)*).unwrap();
361            write!(
362                s,
363                " : {:?} = {:?} not match to pattern {:} = {:?}",
364                stringify!($value),
365                $value,
366                stringify!($pattern),
367                $pattern
368            )
369            .unwrap();
370            Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
371        }
372    };
373}