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}