1use std::{error::Error as StdError, fmt};
2
3pub struct BX(Box<dyn StdError>);
9
10pub type Result<T, E = BX> = std::result::Result<T, E>;
12
13impl BX {
14 pub fn from_err(e: impl StdError + 'static) -> Self {
16 Self(e.into())
17 }
18
19 pub fn from_boxed(e: Box<dyn StdError + 'static>) -> Self {
21 Self(e)
22 }
23
24 pub fn from_string(s: String) -> Self {
26 Self(Box::new(StringError(s)))
27 }
28}
29
30pub fn box_error(e: impl StdError + 'static) -> BX {
31 BX::from_err(e)
32}
33
34pub trait BxForErrors {
36 fn bx(self) -> BX;
37}
38
39impl<E: StdError + 'static> BxForErrors for E {
40 fn bx(self) -> BX {
41 BX::from_err(self)
42 }
43}
44
45pub trait BxForResults<T> {
47 fn bx(self) -> Result<T, BX>;
48}
49
50impl<T, E: StdError + 'static> BxForResults<T> for Result<T, E> {
51 fn bx(self) -> Result<T, BX> {
52 self.map_err(BX::from_err)
53 }
54}
55
56impl fmt::Debug for BX {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 self.0.fmt(f)
59 }
60}
61
62impl fmt::Display for BX {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 self.0.fmt(f)
65 }
66}
67
68impl StdError for BX {
69 fn source(&self) -> Option<&(dyn StdError + 'static)> {
70 self.0.source()
71 }
72}
73
74#[macro_export]
76macro_rules! make_bxable {
77 ($ty:ty) => {
78 impl From<$ty> for $crate::BX {
79 fn from(e: $ty) -> Self {
80 $crate::BX::from_err(e)
81 }
82 }
83 };
84}
85
86make_bxable!(std::io::Error);
87make_bxable!(std::fmt::Error);
88make_bxable!(std::str::Utf8Error);
89make_bxable!(std::string::FromUtf8Error);
90make_bxable!(std::string::FromUtf16Error);
91make_bxable!(std::num::ParseIntError);
92make_bxable!(std::num::ParseFloatError);
93make_bxable!(std::num::TryFromIntError);
94make_bxable!(std::array::TryFromSliceError);
95make_bxable!(std::char::ParseCharError);
96make_bxable!(std::net::AddrParseError);
97make_bxable!(std::time::SystemTimeError);
98make_bxable!(std::env::VarError);
99make_bxable!(std::sync::mpsc::RecvError);
100make_bxable!(std::sync::mpsc::TryRecvError);
101make_bxable!(std::sync::mpsc::SendError<Box<dyn StdError + Send + Sync>>);
102make_bxable!(std::sync::PoisonError<Box<dyn StdError + Send + Sync>>);
103
104#[macro_export]
105macro_rules! bail {
106 ($err:expr) => {
107 return Err($crate::BX::from_err($err));
108 };
109 ($fmt:expr, $($arg:tt)*) => {
110 return Err($crate::BX::from_string(format!($fmt, $($arg)*)));
111 };
112}
113
114pub struct BS(Box<dyn StdError + Send + Sync>);
119
120#[derive(Debug)]
121struct StringError(String);
122
123impl fmt::Display for StringError {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 self.0.fmt(f)
126 }
127}
128
129impl StdError for StringError {
130 fn source(&self) -> Option<&(dyn StdError + 'static)> {
131 None
132 }
133}
134
135impl BS {
136 pub fn from_err(e: impl StdError + Send + Sync + 'static) -> Self {
138 Self(Box::new(e))
139 }
140
141 pub fn from_boxed(e: Box<dyn StdError + Send + Sync + 'static>) -> Self {
143 Self(e)
144 }
145
146 pub fn from_string(s: String) -> Self {
148 Self(Box::new(StringError(s)))
149 }
150}
151
152pub fn box_send_error(e: impl StdError + Send + Sync + 'static) -> BS {
153 BS::from_err(e)
154}
155
156pub trait BsForErrors {
158 fn bs(self) -> BS;
159}
160
161impl<E: StdError + Send + Sync + 'static> BsForErrors for E {
162 fn bs(self) -> BS {
163 BS::from_err(self)
164 }
165}
166
167pub trait BsForResults<T> {
169 fn bs(self) -> Result<T, BS>;
170}
171
172impl<T, E: StdError + Send + Sync + 'static> BsForResults<T> for Result<T, E> {
173 fn bs(self) -> Result<T, BS> {
174 self.map_err(BS::from_err)
175 }
176}
177
178impl fmt::Debug for BS {
179 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180 self.0.fmt(f)
181 }
182}
183
184impl fmt::Display for BS {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 self.0.fmt(f)
187 }
188}
189
190impl StdError for BS {
191 fn source(&self) -> Option<&(dyn StdError + 'static)> {
192 self.0.source()
193 }
194}
195
196#[macro_export]
197macro_rules! make_bsable {
198 ($ty:ty) => {
199 impl From<$ty> for $crate::BS {
200 fn from(e: $ty) -> Self {
201 $crate::BS::from_err(e)
202 }
203 }
204 };
205}
206
207make_bsable!(std::io::Error);
208make_bsable!(std::fmt::Error);
209make_bsable!(std::str::Utf8Error);
210make_bsable!(std::string::FromUtf8Error);
211make_bsable!(std::string::FromUtf16Error);
212make_bsable!(std::num::ParseIntError);
213make_bsable!(std::num::ParseFloatError);
214make_bsable!(std::num::TryFromIntError);
215make_bsable!(std::array::TryFromSliceError);
216make_bsable!(std::char::ParseCharError);
217make_bsable!(std::net::AddrParseError);
218make_bsable!(std::time::SystemTimeError);
219make_bsable!(std::env::VarError);
220make_bsable!(std::sync::mpsc::RecvError);
221make_bsable!(std::sync::mpsc::TryRecvError);
222make_bsable!(std::sync::mpsc::SendError<Box<dyn StdError + Send + Sync>>);
223make_bsable!(std::sync::PoisonError<Box<dyn StdError + Send + Sync>>);