use crate::spec::{AsError, EngineSpec};
use derive_where::derive_where;
use std::{borrow::Cow, collections::VecDeque, error, fmt};
#[derive_where(Debug)]
pub enum NestedEngineError<S: EngineSpec> {
Creation {
error: S::Error,
},
StepFailed {
component: S::Component,
id: S::StepId,
description: Cow<'static, str>,
error: S::Error,
},
Aborted {
component: S::Component,
id: S::StepId,
description: Cow<'static, str>,
message: String,
},
}
impl<S: EngineSpec> fmt::Display for NestedEngineError<S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Creation { .. } => {
write!(f, "error while creating nested engine")
}
Self::StepFailed { description, .. } => {
write!(f, "step failed: {description}")
}
Self::Aborted { description, message, .. } => {
write!(
f,
"execution aborted while running step \
\"{description}\": {message}"
)
}
}
}
}
impl<S: EngineSpec> error::Error for NestedEngineError<S> {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Self::Creation { error } => Some(error.as_error()),
Self::StepFailed { error, .. } => Some(error.as_error()),
Self::Aborted { .. } => None,
}
}
}
#[derive(Debug)]
pub struct ConvertGenericError {
pub path: VecDeque<ConvertGenericPathElement>,
pub error: serde_json::Error,
}
impl ConvertGenericError {
pub fn new(elem: &'static str, error: serde_json::Error) -> Self {
Self {
path: VecDeque::from_iter([ConvertGenericPathElement::Path(elem)]),
error,
}
}
pub fn parent(mut self, elem: &'static str) -> Self {
self.path.push_front(ConvertGenericPathElement::Path(elem));
self
}
pub fn parent_array(mut self, elem: &'static str, index: usize) -> Self {
self.path
.push_front(ConvertGenericPathElement::ArrayIndex(elem, index));
self
}
}
impl fmt::Display for ConvertGenericError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("error converting path: ")?;
for (idx, element) in self.path.iter().enumerate() {
match element {
ConvertGenericPathElement::Path(path) => f.write_str(path)?,
ConvertGenericPathElement::ArrayIndex(path, index) => {
write!(f, "{path}[{index}]")?
}
}
if idx < self.path.len() - 1 {
f.write_str(".")?;
}
}
Ok(())
}
}
impl error::Error for ConvertGenericError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(&self.error)
}
}
#[derive(Debug, Eq, PartialEq)]
pub enum ConvertGenericPathElement {
Path(&'static str),
ArrayIndex(&'static str, usize),
}
#[derive(Clone, Debug)]
pub struct UnknownReportKey {}
impl fmt::Display for UnknownReportKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("unknown report key")
}
}
impl error::Error for UnknownReportKey {}