use crate::{Condition, Signature};
use serde::{Deserialize, Serialize};
pub struct NamedOutput {
pub name: String,
pub value: serde_json::Value,
pub source: Option<String>,
}
impl NamedOutput {
pub fn new(name: impl Into<String>, value: serde_json::Value) -> Self {
Self {
name: name.into(),
value,
source: None,
}
}
pub fn with_source(mut self, source: impl Into<String>) -> Self {
self.source = Some(source.into());
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ResultTransform {
Extract { field: String },
Map { task: Box<Signature> },
Filter { condition: Condition },
Aggregate { strategy: AggregationStrategy },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AggregationStrategy {
Sum,
Average,
Concat,
Merge,
Coalesce,
Custom { task: Box<Signature> },
}
impl std::fmt::Display for ResultTransform {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Extract { field } => write!(f, "Extract[{}]", field),
Self::Map { task } => write!(f, "Map[{}]", task.task),
Self::Filter { condition } => write!(f, "Filter[{}]", condition),
Self::Aggregate { strategy } => write!(f, "Aggregate[{:?}]", strategy),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResultCache {
pub key: String,
pub policy: CachePolicy,
pub ttl: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CachePolicy {
Always,
OnSuccess,
Conditional { condition: Condition },
Never,
}
impl ResultCache {
pub fn new(key: impl Into<String>) -> Self {
Self {
key: key.into(),
policy: CachePolicy::OnSuccess,
ttl: None,
}
}
pub fn with_policy(mut self, policy: CachePolicy) -> Self {
self.policy = policy;
self
}
pub fn with_ttl(mut self, ttl: u64) -> Self {
self.ttl = Some(ttl);
self
}
}
impl std::fmt::Display for ResultCache {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Cache[key={}]", self.key)?;
if let Some(ttl) = self.ttl {
write!(f, " ttl={}s", ttl)?;
}
Ok(())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WorkflowErrorHandler {
pub handler: Signature,
pub error_types: Vec<String>,
pub suppress: bool,
}
impl WorkflowErrorHandler {
pub fn new(handler: Signature) -> Self {
Self {
handler,
error_types: Vec::new(),
suppress: false,
}
}
pub fn for_errors(mut self, error_types: Vec<String>) -> Self {
self.error_types = error_types;
self
}
pub fn suppress_error(mut self) -> Self {
self.suppress = true;
self
}
}
impl std::fmt::Display for WorkflowErrorHandler {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ErrorHandler[{}]", self.handler.task)?;
if self.suppress {
write!(f, " (suppress)")?;
}
Ok(())
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompensationWorkflow {
pub forward: Vec<Signature>,
pub compensations: Vec<Signature>,
}
impl CompensationWorkflow {
pub fn new() -> Self {
Self {
forward: Vec::new(),
compensations: Vec::new(),
}
}
pub fn step(mut self, forward: Signature, compensation: Signature) -> Self {
self.forward.push(forward);
self.compensations.push(compensation);
self
}
pub fn is_empty(&self) -> bool {
self.forward.is_empty()
}
pub fn len(&self) -> usize {
self.forward.len()
}
}
impl Default for CompensationWorkflow {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for CompensationWorkflow {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Compensation[{} steps, {} compensations]",
self.forward.len(),
self.compensations.len()
)
}
}