1use std::borrow::Cow;
2use std::ops::Deref;
3
4use thiserror::Error;
6
7#[derive(Debug)]
8pub struct ErrInfo(Cow<'static, str>);
9
10impl<T> From<T> for ErrInfo
11where
12 T: Into<Cow<'static, str>>,
13{
14 #[inline]
15 fn from(msg: T) -> Self {
16 Self(msg.into())
17 }
18}
19
20impl AsRef<str> for ErrInfo {
21 fn as_ref(&self) -> &str {
22 &self.0
23 }
24}
25
26impl Deref for ErrInfo {
27 type Target = str;
28
29 fn deref(&self) -> &Self::Target {
30 &self.0
31 }
32}
33
34impl std::fmt::Display for ErrInfo {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 write!(f, "{}", self.0)
37 }
38}
39
40#[derive(Error, Debug)]
41pub enum TError {
42 #[error("The length of both vec doesn't match, left: {left} right: {right}")]
43 LengthMismatch { left: usize, right: usize },
44 #[error("Index out of bounds: index: {idx}, length: {len}")]
45 IdxOut { idx: usize, len: usize },
46 #[error(transparent)]
47 Io(#[from] std::io::Error),
48 #[cfg(feature = "polars")]
49 #[error("Polars error: {0}")]
50 Polars(#[from] tea_deps::polars::prelude::PolarsError),
52 #[error("Parse error: {0}")]
53 ParseError(ErrInfo),
54 #[error("{0}")]
55 Str(ErrInfo),
56 #[error("unknown error")]
57 Unknown,
58}
59
60pub type TResult<T> = Result<T, TError>;
61
62#[macro_export]
63macro_rules! terr {
64 (oob($idx: expr, $len: expr)) => {
65 $crate::__private::must_use(
66 $crate::TError::IdxOut { idx: $idx, len: $len }
67 )
68 };
69 (lm, $left: expr, $right: expr) => {
70 $crate::__private::must_use(
71 $crate::TError::LengthMismatch {
72 left: $left,
73 right: $right,
74 }
75 )
76 };
77 (func=$func: ident, $fmt:literal $(, $arg:expr)* $(,)?) => {
78 $crate::__private::must_use(
79 $crate::TError::Str(
80 format!("function {}: {}", stringify!($func), format!($fmt, $($arg),*)).into()
81 )
82 )
83 };
84 ($variant:ident: $fmt:literal $(, $arg:expr)* $(,)?) => {
85 $crate::__private::must_use(
86 $crate::TError::$variant(format!($fmt, $($arg),*).into())
87 )
88 };
89 ($fmt:literal $(, $arg:expr)* $(,)?) => {
90 $crate::__private::must_use(
91 $crate::TError::Str(format!($fmt, $($arg),*).into())
92 )
93 };
94
95 ($variant: ident: $err: expr $(,)?) => {
96 $crate::__private::must_use(
97 $crate::TError::$variant($err.into())
98 )
99 };
100 ($err: expr) => {
101 $crate::terr!(Str: $err)
102 };
103 () => {
104 $crate::__private::must_use(
105 $crate::TError::Unknown
106 )
107 };
108}
109
110#[macro_export]
111macro_rules! tbail {
112 ($($tt:tt)+) => {
113 return Err($crate::terr!($($tt)+))
114 };
115}
116
117#[macro_export]
118macro_rules! tensure {
119 ($cond:expr, $($tt:tt)+) => {
120 if !$cond {
121 $crate::tbail!($($tt)+);
122 }
123 };
124}
125
126#[cfg(feature = "polars")]
127impl From<TError> for tea_deps::polars::prelude::PolarsError {
128 fn from(e: TError) -> Self {
129 tea_deps::polars::prelude::PolarsError::ComputeError(format!("{}", e).into())
130 }
131}
132
133#[doc(hidden)]
135pub mod __private {
136 #[doc(hidden)]
137 #[inline]
138 #[cold]
139 #[must_use]
140 pub fn must_use(error: crate::TError) -> crate::TError {
141 error
142 }
143}