near_workspaces/error/
impls.rs

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    /// Construct a workspaces [`Error`] with the full details of an error which includes
47    /// the internal error it references, the custom error message with further context
48    /// and the [`ErrorKind`] that represents the category of error.
49    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    /// Construct a workspaces [`Error`] with the details of an error which includes
64    /// the internal error it references and the [`ErrorKind`] that represents the
65    /// category of error.
66    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    /// Construct a workspaces [`Error`] with the details of an error which includes
79    /// the custom error message with further context and the [`ErrorKind`] that
80    /// represents the category of error.
81    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    /// Construct a workspaces [`Error`] with the details of an error which only
94    /// includes the [`ErrorKind`] that represents the category of error.
95    pub fn simple(kind: ErrorKind) -> Self {
96        Self {
97            repr: ErrorRepr::Simple(kind),
98        }
99    }
100
101    /// Returns the corresponding [`ErrorKind`] for this error.
102    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    /// Consumes the `Error`, returning its inner error (if any).
113    ///
114    /// If this [`Error`] was constructed via a Custom or Full variant, then
115    /// this function will return [`Ok`], otherwise it will return [`Err`].
116    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}