resplus_impl/
lib.rs

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)]
10struct Inner<I> {
11    pub source: I,
12    pub context: Vec<Cow<'static, str>>,
13}
14
15#[derive(Debug)]
16pub struct ErrorChain<I> {
17    inner: Box<Inner<I>>,
18}
19
20impl<I> ErrorChain<I> {
21    pub fn new(source: impl Into<I>) -> Self {
22        Self {
23            inner: Box::new(Inner {
24                source: source.into(),
25                context: Vec::new(),
26            }),
27        }
28    }
29    pub fn with_context(source: impl Into<I>, context: impl Into<Cow<'static, str>>) -> Self {
30        Self {
31            inner: Box::new(Inner {
32                source: source.into(),
33                context: vec![context.into()],
34            }),
35        }
36    }
37    pub fn append(&mut self, context: impl Into<Cow<'static, str>>) {
38        self.inner.context.push(context.into());
39    }
40    pub fn source(&self) -> &I {
41        &self.inner.source
42    }
43}
44
45impl<I: Display> Display for ErrorChain<I> {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        write!(f, "source: {}", self.inner.source)?;
48        for c in self.inner.context.iter() {
49            write!(f, "\n  {}", c)?;
50        }
51        Ok(())
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    macro_rules! about {
58        ($e:expr) => {
59            ($e).about("source")
60        };
61    }
62    pub(crate) use about;
63    macro_rules! about_else {
64        ($e:expr) => {
65            ($e).about_else(|| "source")
66        };
67    }
68    pub(crate) use about_else;
69}