use std::fmt;
use serde::{Deserialize, Serialize};
use super::attempt_executor_error::AttemptExecutorError;
use super::attempt_panic::AttemptPanic;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound(
serialize = "E: serde::Serialize",
deserialize = "E: serde::de::DeserializeOwned"
))]
pub enum AttemptFailure<E> {
Error(E),
Timeout,
Panic(AttemptPanic),
Executor(AttemptExecutorError),
}
impl<E> AttemptFailure<E> {
#[inline]
pub fn as_error(&self) -> Option<&E> {
match self {
Self::Error(error) => Some(error),
Self::Timeout | Self::Panic(_) | Self::Executor(_) => None,
}
}
#[inline]
pub fn into_error(self) -> Option<E> {
match self {
Self::Error(error) => Some(error),
Self::Timeout | Self::Panic(_) | Self::Executor(_) => None,
}
}
#[inline]
pub fn as_panic(&self) -> Option<&AttemptPanic> {
match self {
Self::Panic(panic) => Some(panic),
Self::Error(_) | Self::Timeout | Self::Executor(_) => None,
}
}
#[inline]
pub fn as_executor_error(&self) -> Option<&AttemptExecutorError> {
match self {
Self::Executor(error) => Some(error),
Self::Error(_) | Self::Timeout | Self::Panic(_) => None,
}
}
}
impl<E: fmt::Display> fmt::Display for AttemptFailure<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Error(error) => write!(f, "{error}"),
Self::Timeout => write!(f, "attempt timed out"),
Self::Panic(panic) => write!(f, "attempt panicked: {panic}"),
Self::Executor(error) => write!(f, "attempt executor failed: {error}"),
}
}
}