Skip to main content

ntex_error/
chain.rs

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