1pub use anyhow::{Context, Error as AnyError, Result as AnyResult, anyhow}; use std::{
10 error::Error as StdError,
11 fmt::{Debug, Display, Formatter, Result as FmtResult},
12 result::Result as StdResult,
13};
14pub use std::{ffi::OsStr, path::Path};
15
16#[derive(Debug)]
20pub struct Error(pub anyhow::Error);
21pub type Result<T, E = Error> = StdResult<T, E>;
22
23impl<E> From<E> for Error
25where
26 E: Into<AnyError>,
27{
28 #[track_caller]
29 fn from(e: E) -> Self {
30 let caller = std::panic::Location::caller();
31 let fullname = OsStr::new(caller.file());
32 let name = Path::new(fullname).file_name().unwrap_or(fullname);
33 Error(e.into().context(anyhow!("({}:{})", name.display(), caller.line())))
34 }
35}
36
37impl Display for Error {
67 fn fmt(&self, f: &mut Formatter) -> FmtResult {
68 Display::fmt(&self.0.chain().map(|e| e.to_string() + " ").collect::<String>(), f)
69 }
70}
71
72impl Error {
74 #[inline(always)]
75 pub fn is<E>(&self) -> bool
76 where
77 E: Display + Debug + Send + Sync + 'static,
78 {
79 self.0.is::<E>()
80 }
81}
82
83pub mod cauz2 {
85 #[inline(always)]
86 #[allow(non_snake_case)]
87 pub fn Ok<T>(value: T) -> super::Result<T> {
88 super::Result::<T>::Ok(value)
89 }
90}
91
92#[macro_export]
114macro_rules! err {
115 () => {{
116 let fullname = OsStr::new(file!());
117 let name = Path::new(fullname).file_name().unwrap_or(fullname);
118 Error(anyhow!("({}:{})", name.display(), line!()))
119
120 }};
121
122 ($msg:literal) => {{
123 let fullname = OsStr::new(file!());
124 let name = Path::new(fullname).file_name().unwrap_or(fullname);
125 Error(anyhow!("({}:{}) {}", name.display(), line!(), $msg))
126 }};
127
128 ($err:ident) => {{
129 let fullname = OsStr::new(file!());
130 let name = Path::new(fullname).file_name().unwrap_or(fullname);
131 Error(anyhow!($err).context(anyhow!("({}:{}) ", name.display(), line!())))
132 }};
133
134 ($fmt:literal, $($args:tt)*) => {{
135 let fullname = OsStr::new(file!());
136 let name = Path::new(fullname).file_name().unwrap_or(fullname);
137 Error(anyhow!("({}:{}) {}", name.display(), line!(), format!($fmt, $($args)*)))
138 }};
139
140 ($err:ident, $($args:tt)*) => {{
141 let fullname = OsStr::new(file!());
142 let name = Path::new(fullname).file_name().unwrap_or(fullname);
143 Error(anyhow!($err).context(anyhow!("({}:{}) {}", name.display(), line!(), format!($($args)*))))
144 }};
145
146 ($err:expr) => {{
151 let fullname = OsStr::new(file!());
152 let name = Path::new(fullname).file_name().unwrap_or(fullname);
153 Error(anyhow!("({}:{}) {:?}", name.display(), line!(), $err))
154 }};
155}
156#[macro_export]
169macro_rules! err2 {
170 ($fmt:literal, $($args:tt)*) => {
171 |x: AnyError| {
172 let fullname = OsStr::new(file!());
173 let name = Path::new(fullname).file_name().unwrap_or(fullname);
174 Error(x.context(anyhow!("({}:{}) {}", name.display(), line!(), format!($fmt, $($args)*))))
175 }
176 };
177
178 ($err:ident, $($args:tt)*) => {
179 |x: AnyError| {
180 let fullname = OsStr::new(file!());
181 let name = Path::new(fullname).file_name().unwrap_or(fullname);
182 Error(x.context($err).context(anyhow!("({}:{}) {}", name.display(), line!(), format!($($args)*))))
183 }
184 };
185}
186
187pub trait Cauz<T> {
192 fn cauz(self) -> AnyResult<T>; }
194
195impl<T> Cauz<T> for Result<T> {
198 #[inline(always)]
199 fn cauz(self) -> AnyResult<T> {
200 self.map_err(|e| e.0)
201 }
202}
203
204impl<T> Cauz<T> for StdResult<T, Box<dyn StdError + Send + Sync>> {
217 #[inline(always)]
218 fn cauz(self) -> AnyResult<T> {
219 self.map_err(|e| anyhow!(e))
220 }
221}
222
223impl<T> Cauz<T> for Option<T> {
225 #[inline(always)]
226 fn cauz(self) -> AnyResult<T> {
227 self.ok_or(anyhow!(""))
228 }
229}
230
231impl Cauz<()> for bool {
233 #[inline(always)]
234 fn cauz(self) -> AnyResult<()> {
235 self.then_some(()).ok_or(anyhow!("")) }
237}
238
239pub trait Cauz2<C, T> {
246 fn cauz2(self, cause: C) -> AnyResult<T>; }
248
249impl<C, T> Cauz2<C, T> for Result<T>
251where
252 C: Display + Send + Sync + 'static,
253{
254 #[inline(always)]
255 fn cauz2(self, cause: C) -> AnyResult<T> {
256 self.map_err(|e| e.0.context(cause))
257 }
258}
259
260impl<C, T, E> Cauz2<C, T> for StdResult<T, E>
262where
263 C: Display + Send + Sync + 'static,
264 E: Into<AnyError>,
265{
266 #[inline(always)]
267 fn cauz2(self, cause: C) -> AnyResult<T> {
268 self.map_err(|e| anyhow!(e).context(cause))
269 }
270}
271
272impl<C, T> Cauz2<C, T> for Option<T>
286where
287 C: Display + Send + Sync + 'static,
288{
289 #[inline(always)]
290 fn cauz2(self, cause: C) -> AnyResult<T> {
291 self.ok_or(anyhow!("{}", cause))
292 }
293}
294
295impl<C> Cauz2<C, ()> for bool
297where
298 C: Display + Send + Sync + 'static,
299{
300 #[inline(always)]
301 fn cauz2(self, cause: C) -> AnyResult<()> {
302 self.then_some(()).ok_or(anyhow!("{}", cause)) }
304}
305
306pub trait Cauz3<T, E> {
313 fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E>;
314}
315
316impl<T, E> Cauz3<T, E> for Result<T> {
318 #[inline(always)]
319 fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
320 self.map_err(|e| cause(e.0))
321 }
322}
323
324impl<T, E0, E> Cauz3<T, E> for StdResult<T, E0>
327where
328 E0: Into<AnyError>,
329{
330 #[inline(always)]
331 fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
332 self.map_err(|e| cause(e.into()))
333 }
334}
335
336impl<T, E> Cauz3<T, E> for Option<T> {
338 #[inline(always)]
339 fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<T, E> {
340 self.ok_or_else(|| cause(anyhow!("")))
341 }
342}
343
344impl<E> Cauz3<(), E> for bool {
346 #[inline(always)]
347 fn cauz3(self, cause: impl FnOnce(AnyError) -> E) -> StdResult<(), E> {
348 self.then_some(()).ok_or_else(|| cause(anyhow!(""))) }
350}