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
20 AxisError {
24 axis: isize,
25 ndim: usize,
26 },
27
28 IndexError(String),
31
32 RuntimeError(String),
33 DeviceMismatch(String),
34 UnImplemented(String),
35 MemoryError(String),
36
37 TryFromIntError(String),
38 Infallible,
39
40 BuilderError(UninitializedFieldError),
41 DeviceError(String),
42 RayonError(String),
43
44 ErrorCode(i32, String),
45 FaerError(String),
46
47 Miscellaneous(String),
48}
49
50#[cfg(feature = "backtrace")]
51#[derive(Debug)]
52pub struct RSTSRBacktrace(pub std::backtrace::Backtrace);
53#[cfg(not(feature = "backtrace"))]
54#[derive(Debug)]
55pub struct RSTSRBacktrace;
56
57#[cfg(feature = "backtrace")]
58impl core::fmt::Display for RSTSRBacktrace {
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 write!(f, "{:}", self.0)
61 }
62}
63
64#[cfg(not(feature = "backtrace"))]
65impl core::fmt::Display for RSTSRBacktrace {
66 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67 write!(f, "Backtrace feature in RSTSR is disabled.")
68 }
69}
70
71#[derive(Debug)]
72pub struct Error {
73 pub inner: RSTSRError,
74 pub backtrace: Option<RSTSRBacktrace>,
75}
76
77pub fn rstsr_backtrace() -> Option<RSTSRBacktrace> {
78 #[cfg(feature = "backtrace")]
79 {
80 extern crate std;
81 let bt = std::backtrace::Backtrace::capture();
82 Some(RSTSRBacktrace(bt))
83 }
84 #[cfg(not(feature = "backtrace"))]
85 {
86 None
87 }
88}
89
90impl core::fmt::Display for Error {
91 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
92 Debug::fmt(self, f)
93 }
94}
95
96#[cfg(feature = "std")]
97impl std::error::Error for Error {}
98
99pub type Result<T> = core::result::Result<T, Error>;
100
101pub trait RSTSRResultAPI<T> {
102 fn rstsr_unwrap(self) -> T;
103}
104
105impl<T> RSTSRResultAPI<T> for Result<T> {
106 #[allow(unused_variables)]
107 fn rstsr_unwrap(self) -> T {
108 match self {
109 Ok(v) => v,
110 Err(e) => {
111 let Error { inner, backtrace } = &e;
112 #[cfg(feature = "backtrace")]
113 {
114 extern crate std;
115 if let Some(backtrace) = backtrace {
116 std::eprintln!("\n====== RSTSR Backtrace ======\n{:}", backtrace);
117 }
118 panic!("RSTSR Error: {:?}", inner)
119 }
120 #[cfg(not(feature = "backtrace"))]
121 {
122 panic!("RSTSR Error (backtrace disabled): {:?}", inner)
123 }
124 },
125 }
126 }
127}
128
129impl From<TryFromIntError> for Error {
130 fn from(e: TryFromIntError) -> Self {
131 Error { inner: RSTSRError::TryFromIntError(format!("{e:?}")), backtrace: rstsr_backtrace() }
132 }
133}
134
135impl From<Infallible> for Error {
136 fn from(_: Infallible) -> Self {
137 Error { inner: RSTSRError::Infallible, backtrace: rstsr_backtrace() }
138 }
139}
140
141#[cfg(feature = "rayon")]
142impl From<rayon::ThreadPoolBuildError> for Error {
143 fn from(e: rayon::ThreadPoolBuildError) -> Self {
144 Error { inner: RSTSRError::RayonError(format!("{e:?}")), backtrace: rstsr_backtrace() }
145 }
146}
147
148impl From<UninitializedFieldError> for Error {
149 fn from(e: UninitializedFieldError) -> Self {
150 Error { inner: RSTSRError::BuilderError(e), backtrace: rstsr_backtrace() }
151 }
152}
153
154impl From<TryReserveError> for Error {
155 fn from(e: TryReserveError) -> Self {
156 Error { inner: RSTSRError::MemoryError(format!("{e:?}")), backtrace: rstsr_backtrace() }
157 }
158}
159
160impl From<LayoutError> for Error {
161 fn from(e: LayoutError) -> Self {
162 Error { inner: RSTSRError::MemoryError(format!("{e:?}")), backtrace: rstsr_backtrace() }
163 }
164}
165
166#[macro_export]
167macro_rules! backtrace {
168 () => {{
169 #[cfg(feature = "backtrace")]
170 {
171 extern crate std;
172 let bt = std::backtrace::Backtrace::capture();
173 format!("\nBacktrace:\n{:}", bt)
174 }
175 #[cfg(not(feature = "backtrace"))]
176 {
177 String::new()
178 }
179 }};
180}
181
182#[macro_export]
183macro_rules! rstsr_assert {
184 ($cond:expr, $errtype:ident) => {
185 if $cond {
186 Ok(())
187 } else {
188 use $crate::prelude_dev::*;
189 let mut s = String::new();
190 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
191 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
192 write!(s, " : {:}", stringify!($cond)).unwrap();
193 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
194 }
195 };
196 ($cond:expr, $errtype:ident, $($arg:tt)*) => {{
197 if $cond {
198 Ok(())
199 } else {
200 use $crate::prelude_dev::*;
201 let mut s = String::new();
202 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
203 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
204 write!(s, " : ").unwrap();
205 write!(s, $($arg)*).unwrap();
206 write!(s, " : {:}", stringify!($cond)).unwrap();
207 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
208 }
209 }};
210}
211
212#[macro_export]
213macro_rules! rstsr_assert_eq {
214 ($lhs:expr, $rhs:expr, $errtype:ident) => {
215 if $lhs == $rhs {
216 Ok(())
217 } else {
218 use $crate::prelude_dev::*;
219 let mut s = String::new();
220 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
221 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
222 write!(
223 s,
224 " : {:} = {:?} not equal to {:} = {:?}",
225 stringify!($lhs),
226 $lhs,
227 stringify!($rhs),
228 $rhs
229 )
230 .unwrap();
231 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
232 }
233 };
234 ($lhs:expr, $rhs:expr, $errtype:ident, $($arg:tt)*) => {
235 if $lhs == $rhs {
236 Ok(())
237 } else {
238 use $crate::prelude_dev::*;
239 let mut s = String::new();
240 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
241 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
242 write!(s, " : ").unwrap();
243 write!(s, $($arg)*).unwrap();
244 write!(
245 s,
246 " : {:} = {:?} not equal to {:} = {:?}",
247 stringify!($lhs),
248 $lhs,
249 stringify!($rhs),
250 $rhs
251 )
252 .unwrap();
253 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
254 }
255 };
256}
257
258#[macro_export]
259macro_rules! rstsr_invalid {
260 ($word:expr) => {{
261 use core::fmt::Write;
262 let mut s = String::new();
263 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
264 write!(s, "Error::InvalidValue").unwrap();
265 write!(s, " : {:?} = {:?}", stringify!($word), $word).unwrap();
266 Err(Error{ inner: RSTSRError::InvalidValue(s), backtrace: rstsr_backtrace() })
267 }};
268 ($word:expr, $($arg:tt)*) => {{
269 use core::fmt::Write;
270 let mut s = String::new();
271 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
272 write!(s, "Error::InvalidValue").unwrap();
273 write!(s, " : {:?} = {:?}", stringify!($word), $word).unwrap();
274 write!(s, " : ").unwrap();
275 write!(s, $($arg)*).unwrap();
276 Err(Error{ inner: RSTSRError::InvalidValue(s), backtrace: rstsr_backtrace() })
277 }};
278}
279
280#[macro_export]
281macro_rules! rstsr_errcode {
282 ($word:expr) => {{
283 use core::fmt::Write;
284 let mut s = String::new();
285 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
286 write!(s, "Error::ErrorCode").unwrap();
287 write!(s, " : {:?}", $word).unwrap();
288 Err(Error{ inner: RSTSRError::ErrorCode($word, s), backtrace: rstsr_backtrace() })
289 }};
290 ($word:expr, $($arg:tt)*) => {{
291 use core::fmt::Write;
292 let mut s = String::new();
293 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
294 write!(s, "Error::ErrorCode").unwrap();
295 write!(s, " : {:?}", $word).unwrap();
296 write!(s, " : ").unwrap();
297 write!(s, $($arg)*).unwrap();
298 Err(Error{ inner: RSTSRError::ErrorCode($word, s), backtrace: rstsr_backtrace() })
299 }};
300}
301
302#[macro_export]
303macro_rules! rstsr_error {
304 ($errtype:ident) => {{
305 use $crate::prelude_dev::*;
306 let mut s = String::new();
307 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
308 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
309 Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() }
310 }};
311 ($errtype:ident, $($arg:tt)*) => {{
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 write!(s, " : ").unwrap();
317 write!(s, $($arg)*).unwrap();
318 Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() }
319 }};
320}
321
322#[macro_export]
323macro_rules! rstsr_raise {
324 ($errtype:ident) => {{
325 use $crate::prelude_dev::*;
326 let mut s = String::new();
327 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
328 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
329 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
330 }};
331 ($errtype:ident, $($arg:tt)*) => {{
332 use $crate::prelude_dev::*;
333 let mut s = String::new();
334 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
335 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
336 write!(s, " : ").unwrap();
337 write!(s, $($arg)*).unwrap();
338 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
339 }};
340}
341
342#[macro_export]
351macro_rules! rstsr_check_axis {
352 ($axis:expr, $ndim:expr) => {{
353 let axis: isize = $axis;
354 let ndim: usize = $ndim;
355 let norm = if axis < 0 { (ndim as isize) + axis } else { axis };
356 if norm >= 0 && (norm as usize) < ndim {
357 core::result::Result::Ok(norm as usize)
358 } else {
359 core::result::Result::Err($crate::error::Error {
360 inner: $crate::error::RSTSRError::AxisError { axis, ndim },
361 backtrace: $crate::error::rstsr_backtrace(),
362 })
363 }
364 }};
365}
366
367#[macro_export]
372macro_rules! rstsr_check_axis_insert {
373 ($axis:expr, $ndim:expr) => {{
374 let axis: isize = $axis;
375 let ndim: usize = $ndim;
376 let norm = if axis < 0 { (ndim as isize) + axis + 1 } else { axis };
378 if norm >= 0 && (norm as usize) <= ndim {
379 core::result::Result::Ok(norm as usize)
380 } else {
381 core::result::Result::Err($crate::error::Error {
382 inner: $crate::error::RSTSRError::AxisError { axis, ndim },
383 backtrace: $crate::error::rstsr_backtrace(),
384 })
385 }
386 }};
387}
388
389#[macro_export]
393macro_rules! rstsr_axis_error {
394 ($axis:expr, $ndim:expr) => {{
395 $crate::error::Error {
396 inner: $crate::error::RSTSRError::AxisError { axis: $axis, ndim: $ndim },
397 backtrace: $crate::error::rstsr_backtrace(),
398 }
399 }};
400}
401
402#[macro_export]
403macro_rules! rstsr_pattern {
404 ($value:expr, $pattern:expr, $errtype:ident) => {
405 if ($pattern).contains(&($value)) {
406 Ok(())
407 } else {
408 use $crate::prelude_dev::*;
409 let mut s = String::new();
410 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
411 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
412 write!(
413 s,
414 " : {:?} = {:?} not match to pattern {:} = {:?}",
415 stringify!($value),
416 $value,
417 stringify!($pattern),
418 $pattern
419 )
420 .unwrap();
421 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
422 }
423 };
424 ($value:expr, $pattern:expr, $errtype:ident, $($arg:tt)*) => {
425 if ($pattern).contains(&($value)) {
426 Ok(())
427 } else {
428 use $crate::prelude_dev::*;
429 let mut s = String::new();
430 write!(s, concat!(file!(), ":", line!(), ": ")).unwrap();
431 write!(s, concat!("Error::", stringify!($errtype))).unwrap();
432 write!(s, " : ").unwrap();
433 write!(s, $($arg)*).unwrap();
434 write!(
435 s,
436 " : {:?} = {:?} not match to pattern {:} = {:?}",
437 stringify!($value),
438 $value,
439 stringify!($pattern),
440 $pattern
441 )
442 .unwrap();
443 Err(Error{ inner: RSTSRError::$errtype(s), backtrace: rstsr_backtrace() })
444 }
445 };
446}