use crate::Actor;
use std::fmt::Debug;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FailurePhase {
OnStart,
OnIdle,
OnStop,
OnIdleThenOnStop,
}
impl std::fmt::Display for FailurePhase {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FailurePhase::OnStart => write!(f, "OnStart"),
FailurePhase::OnIdle => write!(f, "OnIdle"),
FailurePhase::OnStop => write!(f, "OnStop"),
FailurePhase::OnIdleThenOnStop => write!(f, "OnIdleThenOnStop"),
}
}
}
#[derive(Debug)]
pub enum ActorResult<T: Actor> {
Completed {
actor: T,
killed: bool,
},
Failed {
actor: Option<T>,
error: T::Error,
secondary_error: Option<T::Error>,
phase: FailurePhase,
killed: bool,
},
}
impl<T: Actor> From<ActorResult<T>> for (Option<T>, Option<T::Error>) {
fn from(result: ActorResult<T>) -> Self {
match result {
ActorResult::Completed { actor, .. } => (Some(actor), None),
ActorResult::Failed {
actor,
error: cause,
..
} => (actor, Some(cause)),
}
}
}
impl<T: Actor> ActorResult<T> {
pub fn is_completed(&self) -> bool {
matches!(self, ActorResult::Completed { .. })
}
pub fn was_killed(&self) -> bool {
matches!(
self,
ActorResult::Completed { killed: true, .. } | ActorResult::Failed { killed: true, .. }
)
}
pub fn stopped_normally(&self) -> bool {
matches!(self, ActorResult::Completed { killed: false, .. })
}
pub fn is_startup_failed(&self) -> bool {
matches!(
self,
ActorResult::Failed {
phase: FailurePhase::OnStart,
..
}
)
}
pub fn is_runtime_failed(&self) -> bool {
matches!(
self,
ActorResult::Failed {
phase: FailurePhase::OnIdle | FailurePhase::OnIdleThenOnStop,
..
}
)
}
pub fn is_cleanup_failed(&self) -> bool {
matches!(
self,
ActorResult::Failed {
phase: FailurePhase::OnIdleThenOnStop,
..
}
)
}
pub fn is_stop_failed(&self) -> bool {
matches!(
self,
ActorResult::Failed {
phase: FailurePhase::OnStop,
..
}
)
}
pub fn actor(&self) -> Option<&T> {
match self {
ActorResult::Completed { actor, .. } => Some(actor),
ActorResult::Failed { actor, .. } => actor.as_ref(),
}
}
pub fn into_actor(self) -> Option<T> {
match self {
ActorResult::Completed { actor, .. } => Some(actor),
ActorResult::Failed { actor, .. } => actor,
}
}
pub fn error(&self) -> Option<&T::Error> {
match self {
ActorResult::Completed { .. } => None,
ActorResult::Failed { error: cause, .. } => Some(cause),
}
}
pub fn into_error(self) -> Option<T::Error> {
match self {
ActorResult::Completed { .. } => None,
ActorResult::Failed { error: cause, .. } => Some(cause),
}
}
pub fn secondary_error(&self) -> Option<&T::Error> {
match self {
ActorResult::Failed {
secondary_error, ..
} => secondary_error.as_ref(),
ActorResult::Completed { .. } => None,
}
}
pub fn into_secondary_error(self) -> Option<T::Error> {
match self {
ActorResult::Failed {
secondary_error, ..
} => secondary_error,
ActorResult::Completed { .. } => None,
}
}
pub fn is_failed(&self) -> bool {
!self.is_completed()
}
pub fn has_actor(&self) -> bool {
self.actor().is_some()
}
pub fn to_result(self) -> std::result::Result<T, T::Error> {
match self {
ActorResult::Completed { actor, .. } => Ok(actor),
ActorResult::Failed { error: cause, .. } => Err(cause),
}
}
}