use async_trait::async_trait;
use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::models::{
ExecutionPointer, ExecutionResult, WorkflowDefinition, WorkflowInstance, WorkflowStep,
};
pub trait WorkflowData: Serialize + DeserializeOwned + Send + Sync + Clone + 'static {}
impl<T> WorkflowData for T where T: Serialize + DeserializeOwned + Send + Sync + Clone + 'static {}
pub trait HostContext: Send + Sync {
fn start_workflow(
&self,
definition_id: &str,
version: u32,
data: serde_json::Value,
parent_root_workflow_id: Option<String>,
) -> std::pin::Pin<Box<dyn std::future::Future<Output = crate::Result<String>> + Send + '_>>;
}
pub struct StepExecutionContext<'a> {
pub item: Option<&'a serde_json::Value>,
pub execution_pointer: &'a ExecutionPointer,
pub persistence_data: Option<&'a serde_json::Value>,
pub step: &'a WorkflowStep,
pub workflow: &'a WorkflowInstance,
pub definition: Option<&'a WorkflowDefinition>,
pub cancellation_token: tokio_util::sync::CancellationToken,
pub host_context: Option<&'a dyn HostContext>,
pub log_sink: Option<&'a dyn super::LogSink>,
}
impl<'a> std::fmt::Debug for StepExecutionContext<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StepExecutionContext")
.field("item", &self.item)
.field("execution_pointer", &self.execution_pointer)
.field("persistence_data", &self.persistence_data)
.field("step", &self.step)
.field("workflow", &self.workflow)
.field("definition", &self.definition.is_some())
.field("host_context", &self.host_context.is_some())
.field("log_sink", &self.log_sink.is_some())
.finish()
}
}
#[async_trait]
pub trait StepBody: Send + Sync {
async fn run(&mut self, context: &StepExecutionContext<'_>) -> crate::Result<ExecutionResult>;
}