Skip to main content

swf_builders/services/task/
task_builder.rs

1use super::*;
2
3// ============== TaskDefinitionBuilder ==============
4/// Primary entry point for building workflow task definitions.
5///
6/// Supports all task types: call, do, emit, for, fork, listen, raise, run, set, switch, try, and wait.
7#[derive(Default)]
8pub struct TaskDefinitionBuilder {
9    builder: Option<TaskBuilderVariant>,
10}
11
12impl TaskDefinitionBuilder {
13    pub fn new() -> Self {
14        Self::default()
15    }
16
17    task_variant_method!(call, Call, CallFunctionTaskDefinitionBuilder, function: &str);
18    task_variant_method!(do_, Do, DoTaskDefinitionBuilder);
19    task_variant_method!(for_, For, ForTaskDefinitionBuilder);
20    task_variant_method!(fork, Fork, ForkTaskDefinitionBuilder);
21    task_variant_method!(listen, Listen, ListenTaskDefinitionBuilder);
22    task_variant_method!(raise, Raise, RaiseTaskDefinitionBuilder);
23    task_variant_method!(run, Run, RunTaskDefinitionBuilder);
24    task_variant_method!(set, Set, SetTaskDefinitionBuilder);
25    task_variant_method!(switch, Switch, SwitchTaskDefinitionBuilder);
26    task_variant_method!(try_, Try, TryTaskDefinitionBuilder);
27    task_variant_method!(wait, Wait, WaitTaskDefinitionBuilder, duration: OneOfDurationOrIso8601Expression);
28
29    /// Creates an emit task that produces a workflow event.
30    pub fn emit<F>(&mut self, setup: F) -> &mut EmitTaskDefinitionBuilder
31    where
32        F: FnOnce(&mut EventDefinitionBuilder),
33    {
34        let mut event_builder = EventDefinitionBuilder::new();
35        setup(&mut event_builder);
36        let event = event_builder.build();
37        let builder = EmitTaskDefinitionBuilder::new(event);
38        self.builder = Some(TaskBuilderVariant::Emit(Box::new(builder)));
39        match &mut self.builder {
40            Some(TaskBuilderVariant::Emit(ref mut builder)) => builder,
41            _ => unreachable!("Builder should always be set to Emit"),
42        }
43    }
44
45    /// Builds the final `TaskDefinition`, panicking if no task type was configured.
46    pub fn build(self) -> TaskDefinition {
47        if let Some(builder) = self.builder {
48            match builder {
49                TaskBuilderVariant::Call(builder) => builder.build(),
50                TaskBuilderVariant::Do(builder) => builder.build(),
51                TaskBuilderVariant::Emit(builder) => builder.build(),
52                TaskBuilderVariant::For(builder) => builder.build(),
53                TaskBuilderVariant::Fork(builder) => builder.build(),
54                TaskBuilderVariant::Listen(builder) => builder.build(),
55                TaskBuilderVariant::Raise(builder) => builder.build(),
56                TaskBuilderVariant::Run(builder) => builder.build(),
57                TaskBuilderVariant::Set(builder) => builder.build(),
58                TaskBuilderVariant::Switch(builder) => builder.build(),
59                TaskBuilderVariant::Try(builder) => builder.build(),
60                TaskBuilderVariant::Wait(builder) => builder.build(),
61            }
62        } else {
63            panic!("The task must be configured");
64        }
65    }
66}
67
68/// Internal enum tracking which task type variant is being built.
69pub(crate) enum TaskBuilderVariant {
70    /// Call function task builder.
71    Call(Box<CallFunctionTaskDefinitionBuilder>),
72    /// Do (sequential) task builder.
73    Do(Box<DoTaskDefinitionBuilder>),
74    /// Emit event task builder.
75    Emit(Box<EmitTaskDefinitionBuilder>),
76    /// For loop task builder.
77    For(Box<ForTaskDefinitionBuilder>),
78    /// Fork (parallel) task builder.
79    Fork(Box<ForkTaskDefinitionBuilder>),
80    /// Listen event task builder.
81    Listen(Box<ListenTaskDefinitionBuilder>),
82    /// Raise error task builder.
83    Raise(Box<RaiseTaskDefinitionBuilder>),
84    /// Run process task builder.
85    Run(Box<RunTaskDefinitionBuilder>),
86    /// Set variables task builder.
87    Set(Box<SetTaskDefinitionBuilder>),
88    /// Switch conditional task builder.
89    Switch(Box<SwitchTaskDefinitionBuilder>),
90    /// Try-catch task builder.
91    Try(Box<TryTaskDefinitionBuilder>),
92    /// Wait delay task builder.
93    Wait(Box<WaitTaskDefinitionBuilder>),
94}
95
96/// Common trait shared by all task definition builders, providing
97/// conditional execution, timeout, input/output, export, and flow control methods.
98#[allow(dead_code)]
99pub(crate) trait TaskDefinitionBuilderBase {
100    /// Sets a runtime condition that must be true for the task to execute.
101    fn if_(&mut self, condition: &str) -> &mut Self;
102    /// References a named timeout definition by name.
103    fn with_timeout_reference(&mut self, reference: &str) -> &mut Self;
104    /// Configures an inline timeout definition using a builder callback.
105    fn with_timeout<F>(&mut self, setup: F) -> &mut Self
106    where
107        F: FnOnce(&mut TimeoutDefinitionBuilder);
108    /// Configures input data transformation using a builder callback.
109    fn with_input<F>(&mut self, setup: F) -> &mut Self
110    where
111        F: FnOnce(&mut InputDataModelDefinitionBuilder);
112    /// Configures output data transformation using a builder callback.
113    fn with_output<F>(&mut self, setup: F) -> &mut Self
114    where
115        F: FnOnce(&mut OutputDataModelDefinitionBuilder);
116    /// Configures exported output data using a builder callback.
117    fn with_export<F>(&mut self, setup: F) -> &mut Self
118    where
119        F: FnOnce(&mut OutputDataModelDefinitionBuilder);
120    /// Sets a flow directive to execute after this task completes (e.g., "continue", "end").
121    fn then(&mut self, directive: &str) -> &mut Self;
122    /// Builds the final `TaskDefinition`.
123    fn build(self) -> TaskDefinition;
124}