Skip to main content

ntex_error/
chain.rs

1use std::{error, fmt, panic::Location, sync::Arc};
2
3use crate::{Backtrace, Error, ErrorDiagnostic, ErrorKind, ErrorRepr};
4
5#[derive(Debug, Clone)]
6pub struct ErrorChain<K: ErrorKind> {
7    error: Arc<dyn ErrorDiagnostic<Kind = K>>,
8}
9
10impl<K: ErrorKind> ErrorChain<K> {
11    #[track_caller]
12    pub fn new<E>(error: E) -> Self
13    where
14        E: ErrorDiagnostic + Sized,
15        K: ErrorKind + From<E::Kind>,
16    {
17        Self {
18            error: Arc::new(ErrorRepr::new(error, None, Location::caller())),
19        }
20    }
21}
22
23impl<E, K> From<Error<E>> for ErrorChain<K>
24where
25    E: ErrorDiagnostic<Kind = K> + Sized,
26    K: ErrorKind,
27{
28    fn from(err: Error<E>) -> Self {
29        Self { error: err.inner }
30    }
31}
32
33impl<K> error::Error for ErrorChain<K>
34where
35    K: ErrorKind,
36{
37    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
38        self.error.source()
39    }
40}
41
42impl<K> fmt::Display for ErrorChain<K>
43where
44    K: ErrorKind,
45{
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        fmt::Display::fmt(&self.error, f)
48    }
49}
50
51impl<K> ErrorDiagnostic for ErrorChain<K>
52where
53    K: ErrorKind,
54{
55    type Kind = K;
56
57    fn kind(&self) -> Self::Kind {
58        self.error.kind()
59    }
60
61    fn service(&self) -> Option<&'static str> {
62        self.error.service()
63    }
64
65    fn signature(&self) -> &'static str {
66        self.error.signature()
67    }
68
69    fn backtrace(&self) -> Option<&Backtrace> {
70        self.error.backtrace()
71    }
72}