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