Skip to main content

swf_core/models/task/
run_task.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5use super::TaskDefinitionFields;
6use crate::models::resource::ExternalResourceDefinition;
7
8/// Represents the configuration of a task used to run a given process
9#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
10pub struct RunTaskDefinition {
11    /// Gets/sets the configuration of the process to execute
12    #[serde(rename = "run")]
13    pub run: ProcessTypeDefinition,
14
15    /// Gets/sets the task's common fields
16    #[serde(flatten)]
17    pub common: TaskDefinitionFields,
18}
19impl RunTaskDefinition {
20    /// Initializes a new RunTaskDefinition
21    pub fn new(run: ProcessTypeDefinition) -> Self {
22        Self {
23            run,
24            common: TaskDefinitionFields::new(),
25        }
26    }
27}
28
29/// Represents the configuration of a process execution
30#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
31pub struct ProcessTypeDefinition {
32    /// Gets/sets the configuration of the container to run
33    #[serde(rename = "container", skip_serializing_if = "Option::is_none")]
34    pub container: Option<ContainerProcessDefinition>,
35
36    /// Gets/sets the configuration of the script to run
37    #[serde(rename = "script", skip_serializing_if = "Option::is_none")]
38    pub script: Option<ScriptProcessDefinition>,
39
40    /// Gets/sets the configuration of the shell command to run
41    #[serde(rename = "shell", skip_serializing_if = "Option::is_none")]
42    pub shell: Option<ShellProcessDefinition>,
43
44    /// Gets/sets the configuration of the workflow to run
45    #[serde(rename = "workflow", skip_serializing_if = "Option::is_none")]
46    pub workflow: Option<WorkflowProcessDefinition>,
47
48    /// Gets/sets a boolean indicating whether or not to await the process completion before continuing. Defaults to 'true'
49    #[serde(rename = "await", skip_serializing_if = "Option::is_none")]
50    pub await_: Option<bool>,
51
52    /// Gets/sets the configuration of the process output. Defaults to 'stdout'.
53    /// Possible values: 'stdout', 'stderr', 'code', 'all', 'none'
54    #[serde(rename = "return", skip_serializing_if = "Option::is_none")]
55    pub return_: Option<String>,
56}
57impl ProcessTypeDefinition {
58    /// Creates a new container process
59    pub fn using_container(container: ContainerProcessDefinition, await_: Option<bool>) -> Self {
60        Self {
61            container: Some(container),
62            await_,
63            ..Self::default()
64        }
65    }
66
67    /// Creates a new script process
68    pub fn using_script(script: ScriptProcessDefinition, await_: Option<bool>) -> Self {
69        Self {
70            script: Some(script),
71            await_,
72            ..Self::default()
73        }
74    }
75
76    /// Creates a new shell process
77    pub fn using_shell(shell: ShellProcessDefinition, await_: Option<bool>) -> Self {
78        Self {
79            shell: Some(shell),
80            await_,
81            ..Self::default()
82        }
83    }
84
85    /// Creates a new workflow process
86    pub fn using_workflow(workflow: WorkflowProcessDefinition, await_: Option<bool>) -> Self {
87        Self {
88            workflow: Some(workflow),
89            await_,
90            ..Self::default()
91        }
92    }
93
94    /// Gets the type of the defined process, or None if no process is configured
95    pub fn get_process_type(&self) -> Option<&str> {
96        if self.container.is_some() {
97            Some(super::constants::ProcessType::CONTAINER)
98        } else if self.script.is_some() {
99            Some(super::constants::ProcessType::SCRIPT)
100        } else if self.shell.is_some() {
101            Some(super::constants::ProcessType::SHELL)
102        } else if self.workflow.is_some() {
103            Some(super::constants::ProcessType::WORKFLOW)
104        } else {
105            None
106        }
107    }
108}
109
110/// Represents the configuration of a container's lifetime
111#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
112pub struct ContainerLifetimeDefinition {
113    /// Gets/sets the container cleanup policy to use
114    #[serde(rename = "cleanup")]
115    pub cleanup: String,
116
117    /// Gets/sets the duration after which to cleanup the container, in case the cleanup policy has been set to 'eventually'
118    #[serde(rename = "after", skip_serializing_if = "Option::is_none")]
119    pub after: Option<crate::models::duration::OneOfDurationOrIso8601Expression>,
120}
121
122/// Represents the configuration of a container process
123#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
124pub struct ContainerProcessDefinition {
125    /// Gets/sets the name of the container image to run
126    #[serde(rename = "image")]
127    pub image: String,
128
129    /// Gets/sets the name of the container to run
130    #[serde(rename = "name", skip_serializing_if = "Option::is_none")]
131    pub name: Option<String>,
132
133    /// Gets/sets the command, if any, to execute on the container
134    #[serde(rename = "command", skip_serializing_if = "Option::is_none")]
135    pub command: Option<String>,
136
137    /// Gets/sets a list containing the container's port mappings, if any
138    /// Keys and values can be strings or numbers (matches Go SDK's `map[string]interface{}`)
139    #[serde(rename = "ports", skip_serializing_if = "Option::is_none")]
140    pub ports: Option<HashMap<String, Value>>,
141
142    /// Gets/sets the volume mapping for the container, if any
143    /// Matches Go SDK's `map[string]interface{}` which allows both string and object values
144    #[serde(rename = "volumes", skip_serializing_if = "Option::is_none")]
145    pub volumes: Option<HashMap<String, Value>>,
146
147    /// Gets/sets a key/value mapping of the environment variables, if any, to use when running the configured process
148    #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
149    pub environment: Option<HashMap<String, String>>,
150
151    /// Gets/sets the data to pass to the process via stdin, if any
152    #[serde(rename = "stdin", skip_serializing_if = "Option::is_none")]
153    pub stdin: Option<String>,
154
155    /// Gets/sets a list of arguments, if any, to pass to the container (argv)
156    #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
157    pub arguments: Option<Vec<String>>,
158
159    /// Gets/sets the policy that controls how the container's image should be pulled from the registry
160    #[serde(rename = "pullPolicy", skip_serializing_if = "Option::is_none")]
161    pub pull_policy: Option<String>,
162
163    /// Gets/sets the configuration of the container's lifetime
164    #[serde(rename = "lifetime", skip_serializing_if = "Option::is_none")]
165    pub lifetime: Option<ContainerLifetimeDefinition>,
166}
167
168/// Represents a value that can be either a list of arguments (array) or a key/value mapping (object).
169/// Matches Go SDK's RunArguments type which supports both forms.
170#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
171#[serde(untagged)]
172pub enum OneOfRunArguments {
173    /// A list of string arguments (e.g., ["arg1=value1", "arg2"])
174    Array(Vec<String>),
175    /// A key/value mapping of arguments (e.g., {"arg1": "value1"})
176    Map(HashMap<String, Value>),
177}
178
179impl Default for OneOfRunArguments {
180    fn default() -> Self {
181        OneOfRunArguments::Array(Vec::new())
182    }
183}
184
185impl OneOfRunArguments {
186    /// Returns the arguments as a slice if this is an Array variant
187    pub fn as_array(&self) -> Option<&[String]> {
188        match self {
189            OneOfRunArguments::Array(arr) => Some(arr),
190            _ => None,
191        }
192    }
193
194    /// Returns the arguments as a HashMap if this is a Map variant
195    pub fn as_map(&self) -> Option<&HashMap<String, Value>> {
196        match self {
197            OneOfRunArguments::Map(map) => Some(map),
198            _ => None,
199        }
200    }
201
202    /// Returns true if this is an Array variant
203    pub fn is_array(&self) -> bool {
204        matches!(self, OneOfRunArguments::Array(_))
205    }
206
207    /// Returns true if this is a Map variant
208    pub fn is_map(&self) -> bool {
209        matches!(self, OneOfRunArguments::Map(_))
210    }
211}
212
213/// Represents the definition of a script evaluation process
214#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
215pub struct ScriptProcessDefinition {
216    /// Gets/sets the language of the script to run
217    #[serde(rename = "language")]
218    pub language: String,
219
220    /// Gets/sets the script's code. Required if 'source' has not been set
221    #[serde(rename = "code", skip_serializing_if = "Option::is_none")]
222    pub code: Option<String>,
223
224    /// Gets the the script's source. Required if 'code' has not been set
225    #[serde(rename = "source", skip_serializing_if = "Option::is_none")]
226    pub source: Option<ExternalResourceDefinition>,
227
228    /// Gets/sets the data to pass to the process via stdin
229    #[serde(rename = "stdin", skip_serializing_if = "Option::is_none")]
230    pub stdin: Option<String>,
231
232    /// Gets/sets the arguments to pass to the script. Can be either a list of strings (argv) or a key/value mapping.
233    #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
234    pub arguments: Option<OneOfRunArguments>,
235
236    /// Gets/sets a key/value mapping of the environment variables, if any, to use when running the configured process
237    #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
238    pub environment: Option<HashMap<String, String>>,
239}
240impl ScriptProcessDefinition {
241    /// Initializes a new script from code
242    pub fn from_code(
243        language: &str,
244        code: String,
245        stdin: Option<String>,
246        arguments: Option<OneOfRunArguments>,
247        environment: Option<HashMap<String, String>>,
248    ) -> Self {
249        Self {
250            language: language.to_string(),
251            code: Some(code),
252            source: None,
253            stdin,
254            arguments,
255            environment,
256        }
257    }
258
259    /// Initializes a new script from an external resource
260    pub fn from_source(
261        language: &str,
262        source: ExternalResourceDefinition,
263        stdin: Option<String>,
264        arguments: Option<OneOfRunArguments>,
265        environment: Option<HashMap<String, String>>,
266    ) -> Self {
267        Self {
268            language: language.to_string(),
269            code: None,
270            source: Some(source),
271            stdin,
272            arguments,
273            environment,
274        }
275    }
276}
277
278/// Represents the definition of a shell process
279#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
280pub struct ShellProcessDefinition {
281    /// Gets/sets the shell command to run
282    #[serde(rename = "command")]
283    pub command: String,
284
285    /// Gets/sets the arguments of the shell command to run (supports both array and map forms, matches Go SDK's RunArguments)
286    #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
287    pub arguments: Option<OneOfRunArguments>,
288
289    /// Gets/sets a key/value mapping of the environment variables, if any, to use when running the configured process
290    #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
291    pub environment: Option<HashMap<String, String>>,
292}
293impl ShellProcessDefinition {
294    pub fn new(
295        command: &str,
296        arguments: Option<OneOfRunArguments>,
297        environment: Option<HashMap<String, String>>,
298    ) -> Self {
299        Self {
300            command: command.to_string(),
301            arguments,
302            environment,
303        }
304    }
305}
306
307/// Represents the definition of a (sub)workflow process
308#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
309pub struct WorkflowProcessDefinition {
310    /// Gets/sets the namespace the workflow to run belongs to
311    #[serde(rename = "namespace")]
312    pub namespace: String,
313
314    /// Gets/sets the name of the workflow to run
315    #[serde(rename = "name")]
316    pub name: String,
317
318    /// Gets/sets the version of the workflow to run
319    #[serde(rename = "version")]
320    pub version: String,
321
322    /// Gets/sets the data, if any, to pass as input to the workflow to execute. The value should be validated against the target workflow's input schema, if specified
323    #[serde(rename = "input", skip_serializing_if = "Option::is_none")]
324    pub input: Option<Value>,
325}
326impl WorkflowProcessDefinition {
327    pub fn new(namespace: &str, name: &str, version: &str, input: Option<Value>) -> Self {
328        Self {
329            namespace: namespace.to_string(),
330            name: name.to_string(),
331            version: version.to_string(),
332            input,
333        }
334    }
335}