1#[cfg(feature = "async")]
2mod fut;
3#[cfg(feature = "async")]
4pub use fut::FutResultChain;
5mod sync;
6use std::{borrow::Cow, fmt::Display};
7pub use sync::ResultChain;
8
9#[derive(Debug)]
10pub struct ErrorChain<I> {
11 pub source: I,
12 context: Vec<Cow<'static, str>>,
13}
14
15impl<I> ErrorChain<I> {
16 pub fn new(source: impl Into<I>) -> Self {
17 Self {
18 source: source.into(),
19 context: Vec::new(),
20 }
21 }
22}
23
24impl<I: Display> Display for ErrorChain<I> {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, "source: {}", self.source)?;
27 for c in &self.context {
28 write!(f, "\n {}", c)?;
29 }
30 Ok(())
31 }
32}
33
34#[macro_export]
35macro_rules! define_error {
36 ($error:ty, $source:ty$(, $t:ty)*) => {
37 impl From<$source> for ErrorChain {
38 fn from(value: $source) -> Self {
39 ErrorChain(resplus::ErrorChain::new(value))
40 }
41 }
42 define_error!($error$(, $t)*);
43 };
44 ($error:ty) => {
45 impl From<$error> for ErrorChain {
46 fn from(value: $error) -> Self {
47 ErrorChain(resplus::ErrorChain::new(value))
48 }
49 }
50
51 impl From<resplus::ErrorChain<$error>> for ErrorChain {
52 fn from(value: resplus::ErrorChain<$error>) -> Self {
53 ErrorChain(value)
54 }
55 }
56
57 #[derive(Debug)]
58 pub struct ErrorChain(resplus::ErrorChain<$error>);
59
60 impl std::fmt::Display for ErrorChain {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(f, "{}", self.0)
63 }
64 }
65
66 impl std::error::Error for ErrorChain {}
67 };
68}
69
70#[cfg(test)]
71mod tests {
72 macro_rules! about {
73 ($e:expr) => {
74 ($e).about("source")
75 };
76 }
77 pub(crate) use about;
78 macro_rules! about_else {
79 ($e:expr) => {
80 ($e).about_else(|| "source")
81 };
82 }
83 pub(crate) use about_else;
84}