use aion_core::{ActivityError, Payload, WorkflowError};
use serde::de::DeserializeOwned;
use super::id::{WorkflowConversationId, WorkflowRunId, WorkflowStepId};
#[derive(Debug)]
pub enum WorkflowItem {
Progress(WorkflowProgress),
Terminal(WorkflowTerminal),
}
#[derive(Debug)]
pub struct WorkflowProgress {
pub seq: u64,
pub kind: WorkflowProgressKind,
}
#[derive(Debug)]
pub enum WorkflowProgressKind {
Opened {
workflow_kind: String,
run: WorkflowRunId,
continued_from: Option<WorkflowRunId>,
},
Reopened {
run: WorkflowRunId,
redispatched_steps: Vec<WorkflowStepId>,
},
Paused {
reason: Option<String>,
},
Resumed,
AttributesNoted {
attributes: Vec<String>,
},
StepScheduled {
step: WorkflowStepId,
step_kind: String,
input: WorkflowPayload,
},
StepStarted {
step: WorkflowStepId,
attempt: u32,
},
StepCompleted {
step: WorkflowStepId,
attempt: u32,
result: WorkflowPayload,
},
StepFailed {
step: WorkflowStepId,
attempt: u32,
failure: WorkflowStepFailure,
},
StepCancelled {
step: WorkflowStepId,
attempt: u32,
},
TimerArmed {
timer: String,
},
TimerFired {
timer: String,
},
TimerRetired {
timer: String,
permanent: bool,
},
TimeoutSettled {
timer: String,
timed_out: bool,
result: Option<WorkflowPayload>,
},
ContributionReceived {
name: String,
payload: WorkflowPayload,
},
ContributionForwarded {
target: WorkflowConversationId,
name: String,
},
ChildOpened {
child: WorkflowConversationId,
workflow_kind: String,
},
ChildCompleted {
child: WorkflowConversationId,
result: WorkflowPayload,
},
ChildFailed {
child: WorkflowConversationId,
failure: WorkflowFailure,
},
ChildCancelled {
child: WorkflowConversationId,
},
ScheduleNoted {
schedule: String,
note: ScheduleNote,
},
}
#[derive(Debug)]
pub enum ScheduleNote {
Created,
Updated,
Paused,
Resumed,
Deleted,
Triggered {
conversation: WorkflowConversationId,
run: WorkflowRunId,
},
}
#[derive(Debug)]
pub enum WorkflowTerminal {
Completed {
seq: u64,
result: WorkflowPayload,
},
Failed {
seq: u64,
failure: WorkflowFailure,
},
Cancelled {
seq: u64,
reason: String,
},
TimedOut {
seq: u64,
timeout: String,
},
ContinuedAsNew {
seq: u64,
continued_run: WorkflowRunId,
next_input: WorkflowPayload,
next_kind: Option<String>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct WorkflowPayload(Payload);
impl WorkflowPayload {
pub fn decode<T: DeserializeOwned>(&self) -> Result<T, super::WorkflowCallError> {
let value =
self.0
.to_json()
.map_err(|error| super::WorkflowCallError::InvalidArgument {
message: format!("payload is not JSON: {error}"),
})?;
serde_json::from_value(value).map_err(|error| super::WorkflowCallError::InvalidArgument {
message: format!("payload does not match the requested type: {error}"),
})
}
#[must_use]
pub fn bytes(&self) -> &[u8] {
self.0.bytes()
}
pub(crate) fn from_core(payload: Payload) -> Self {
Self(payload)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct WorkflowFailure(WorkflowError);
impl WorkflowFailure {
#[must_use]
pub fn message(&self) -> &str {
&self.0.message
}
#[must_use]
pub fn details(&self) -> Option<WorkflowPayload> {
self.0.details.clone().map(WorkflowPayload::from_core)
}
pub(crate) fn from_core(error: WorkflowError) -> Self {
Self(error)
}
}
impl std::fmt::Display for WorkflowFailure {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(formatter)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct WorkflowStepFailure(ActivityError);
impl WorkflowStepFailure {
#[must_use]
pub fn message(&self) -> &str {
&self.0.message
}
#[must_use]
pub fn is_retryable(&self) -> bool {
self.0.is_retryable()
}
pub(crate) fn from_core(error: ActivityError) -> Self {
Self(error)
}
}
impl std::fmt::Display for WorkflowStepFailure {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(formatter)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum WorkflowPhase {
Running,
Completed,
Failed,
Cancelled,
TimedOut,
ContinuedAsNew,
Paused,
}
impl WorkflowPhase {
#[must_use]
pub const fn is_terminal(self) -> bool {
!matches!(self, Self::Running | Self::Paused)
}
}
#[derive(Debug)]
pub struct ReopenedRun {
pub run: WorkflowRunId,
pub phase: WorkflowPhase,
}
#[derive(Debug)]
pub struct WorkflowInspection {
pub phase: WorkflowPhase,
pub recorded_events: u64,
}