1use std::{fmt, fmt::Write, sync::Arc};
2
3use ntex_bytes::{ByteString, BytesMut};
4
5use crate::{Backtrace, Error, ErrorDiagnostic, ErrorKind, ErrorRepr, ErrorType};
6
7trait ErrorInfo: fmt::Debug + 'static {
8 fn error_type(&self) -> ErrorType;
9
10 fn error_signature(&self) -> ByteString;
11
12 fn service(&self) -> Option<&'static str>;
13
14 fn signature(&self) -> &'static str;
15
16 fn backtrace(&self) -> Option<&Backtrace>;
17}
18
19impl<E, K> ErrorInfo for ErrorRepr<E, K>
20where
21 E: ErrorDiagnostic,
22 K: ErrorKind + From<E::Kind>,
23{
24 fn error_type(&self) -> ErrorType {
25 self.kind().error_type()
26 }
27
28 fn error_signature(&self) -> ByteString {
29 let mut buf = BytesMut::new();
30 let _ = write!(&mut buf, "{}", self.kind());
31 ByteString::try_from(buf).unwrap()
32 }
33
34 fn service(&self) -> Option<&'static str> {
35 ErrorDiagnostic::service(self)
36 }
37
38 fn signature(&self) -> &'static str {
39 ErrorDiagnostic::signature(self)
40 }
41
42 fn backtrace(&self) -> Option<&Backtrace> {
43 ErrorDiagnostic::backtrace(self)
44 }
45}
46
47#[derive(Debug, Clone)]
48pub struct ErrorInformation {
49 inner: Arc<dyn ErrorInfo>,
50}
51
52impl ErrorInformation {
53 pub fn error_type(&self) -> ErrorType {
54 self.inner.error_type()
55 }
56
57 pub fn error_signature(&self) -> ByteString {
58 self.inner.error_signature()
59 }
60
61 pub fn service(&self) -> Option<&'static str> {
62 self.inner.service()
63 }
64
65 pub fn signature(&self) -> &'static str {
66 self.inner.signature()
67 }
68
69 pub fn backtrace(&self) -> Option<&Backtrace> {
70 self.inner.backtrace()
71 }
72}
73
74impl<E> From<Error<E>> for ErrorInformation
75where
76 E: ErrorDiagnostic,
77{
78 fn from(err: Error<E>) -> Self {
79 Self { inner: err.inner }
80 }
81}