1use std::{
4 error::Error as StdError,
5 fmt::{Display, Formatter, Result as FmtResult},
6};
7
8#[doc(inline)]
9pub use crate::action::{
10 ActionError, ActionErrorType, ActionRunError, ActionRunErrorType, ActionValidationError,
11 ActionValidationErrorType,
12};
13
14#[derive(Debug)]
19pub struct Error {
20 source: Option<Box<dyn StdError + Send + Sync>>,
21 kind: ErrorType,
22}
23
24impl Error {
25 #[must_use = "retrieving the type has no effect if left unused"]
27 pub const fn kind(&self) -> &ErrorType {
28 &self.kind
29 }
30
31 #[must_use = "consuming the error and retrieving the source has no effect if left unused"]
33 pub fn into_source(self) -> Option<Box<dyn StdError + Send + Sync>> {
34 self.source
35 }
36
37 #[must_use = "consuming the error into it's parts has no effect if left unused"]
39 pub fn into_parts(self) -> (ErrorType, Option<Box<dyn StdError + Send + Sync>>) {
40 (self.kind, self.source)
41 }
42
43 #[must_use]
45 pub fn backend(e: Option<Box<dyn StdError + Send + Sync>>) -> Self {
46 Self {
47 source: e,
48 kind: ErrorType::Backend,
49 }
50 }
51}
52
53impl Display for Error {
54 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
55 match &self.kind {
56 ErrorType::Backend => f.write_str("an error occurred within a backend"),
57 ErrorType::ActionRun => f.write_str("an error occurred running an action"),
58 ErrorType::ActionValidation => f.write_str("an action is invalid"),
59 }
60 }
61}
62
63impl StdError for Error {
64 fn source(&self) -> Option<&(dyn StdError + 'static)> {
65 self.source
66 .as_ref()
67 .map(|source| &**source as &(dyn StdError + 'static))
68 }
69}
70
71impl From<ActionError> for Error {
72 fn from(e: ActionError) -> Self {
73 let kind = match e.kind() {
74 ActionErrorType::Run => ErrorType::ActionRun,
75 ActionErrorType::Validation => ErrorType::ActionValidation,
76 };
77 Self {
78 source: e.into_source(),
80 kind,
81 }
82 }
83}
84
85impl From<ActionValidationError> for Error {
86 fn from(e: ActionValidationError) -> Self {
87 Self {
88 source: Some(Box::new(e)),
89 kind: ErrorType::ActionValidation,
90 }
91 }
92}
93
94impl From<ActionRunError> for Error {
95 fn from(e: ActionRunError) -> Self {
96 Self {
97 source: Some(Box::new(e)),
98 kind: ErrorType::ActionRun,
99 }
100 }
101}
102
103#[derive(Debug)]
105#[allow(missing_copy_implementations)]
106#[non_exhaustive]
107pub enum ErrorType {
108 Backend,
110 ActionValidation,
112 ActionRun,
114}