1use std::fmt;
2use std::{borrow::Cow, sync::PoisonError};
3
4use crate::result::ExecutionFailure;
5
6use super::{Error, ErrorKind, ErrorRepr, RpcErrorCode, SandboxErrorCode};
7
8impl ErrorKind {
9 pub(crate) fn custom<E>(self, error: E) -> Error
10 where
11 E: Into<Box<dyn std::error::Error + Send + Sync>>,
12 {
13 Error::custom(self, error)
14 }
15
16 pub(crate) fn message<T>(self, msg: T) -> Error
17 where
18 T: Into<Cow<'static, str>>,
19 {
20 Error::message(self, msg)
21 }
22
23 pub(crate) fn full<T, E>(self, msg: T, error: E) -> Error
24 where
25 T: Into<Cow<'static, str>>,
26 E: Into<Box<dyn std::error::Error + Send + Sync>>,
27 {
28 Error::full(self, msg, error)
29 }
30
31 pub(crate) fn detailed(self, error: ExecutionFailure) -> Error {
32 Error::detailed(self, error)
33 }
34}
35
36impl Error {
37 pub(crate) fn detailed(kind: ErrorKind, error: ExecutionFailure) -> Self {
38 Self {
39 repr: ErrorRepr::Detailed {
40 kind,
41 error: Box::new(error),
42 },
43 }
44 }
45
46 pub(crate) fn full<T, E>(kind: ErrorKind, msg: T, error: E) -> Self
50 where
51 T: Into<Cow<'static, str>>,
52 E: Into<Box<dyn std::error::Error + Send + Sync>>,
53 {
54 Self {
55 repr: ErrorRepr::Full {
56 kind,
57 message: msg.into(),
58 error: error.into(),
59 },
60 }
61 }
62
63 pub fn custom<E>(kind: ErrorKind, error: E) -> Self
67 where
68 E: Into<Box<dyn std::error::Error + Send + Sync>>,
69 {
70 Self {
71 repr: ErrorRepr::Custom {
72 kind,
73 error: error.into(),
74 },
75 }
76 }
77
78 pub fn message<T>(kind: ErrorKind, msg: T) -> Self
82 where
83 T: Into<Cow<'static, str>>,
84 {
85 Self {
86 repr: ErrorRepr::Message {
87 kind,
88 message: msg.into(),
89 },
90 }
91 }
92
93 pub fn simple(kind: ErrorKind) -> Self {
96 Self {
97 repr: ErrorRepr::Simple(kind),
98 }
99 }
100
101 pub fn kind(&self) -> &ErrorKind {
103 match &self.repr {
104 ErrorRepr::Simple(kind) => kind,
105 ErrorRepr::Message { kind, .. } => kind,
106 ErrorRepr::Custom { kind, .. } => kind,
107 ErrorRepr::Full { kind, .. } => kind,
108 ErrorRepr::Detailed { kind, .. } => kind,
109 }
110 }
111
112 pub fn into_inner(self) -> Result<Box<dyn std::error::Error + Send + Sync>, Self> {
117 match self.repr {
118 ErrorRepr::Custom { error, .. } => Ok(error),
119 ErrorRepr::Full { error, .. } => Ok(error),
120 ErrorRepr::Detailed { error, .. } => Ok(error),
121 _ => Err(self),
122 }
123 }
124}
125
126impl fmt::Display for Error {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(f, "{}", self.repr)
129 }
130}
131
132impl std::error::Error for Error {
133 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
134 self.repr.source()
135 }
136}
137
138impl<T> From<PoisonError<T>> for Error {
139 fn from(value: PoisonError<T>) -> Self {
140 Self::custom(ErrorKind::Other, value.to_string())
141 }
142}
143
144impl SandboxErrorCode {
145 pub(crate) fn message<T>(self, msg: T) -> Error
146 where
147 T: Into<Cow<'static, str>>,
148 {
149 Error::message(ErrorKind::Sandbox(self), msg)
150 }
151
152 pub(crate) fn custom<E>(self, error: E) -> Error
153 where
154 E: Into<Box<dyn std::error::Error + Send + Sync>>,
155 {
156 Error::custom(ErrorKind::Sandbox(self), error)
157 }
158
159 pub(crate) fn full<T, E>(self, msg: T, error: E) -> Error
160 where
161 T: Into<Cow<'static, str>>,
162 E: Into<Box<dyn std::error::Error + Send + Sync>>,
163 {
164 Error::full(ErrorKind::Sandbox(self), msg, error)
165 }
166}
167
168impl From<SandboxErrorCode> for Error {
169 fn from(code: SandboxErrorCode) -> Self {
170 Self::simple(ErrorKind::Sandbox(code))
171 }
172}
173
174impl RpcErrorCode {
175 pub(crate) fn message<T>(self, msg: T) -> Error
176 where
177 T: Into<Cow<'static, str>>,
178 {
179 Error::message(ErrorKind::Rpc(self), msg)
180 }
181
182 pub(crate) fn custom<E>(self, error: E) -> Error
183 where
184 E: Into<Box<dyn std::error::Error + Send + Sync>>,
185 {
186 Error::custom(ErrorKind::Rpc(self), error)
187 }
188}
189
190impl From<RpcErrorCode> for Error {
191 fn from(code: RpcErrorCode) -> Self {
192 Self::simple(ErrorKind::Rpc(code))
193 }
194}