1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3use std::collections::HashMap;
4
5use super::constants::{ContainerCleanupPolicy, ProcessReturnType};
6use super::TaskDefinitionFields;
7use crate::models::resource::ExternalResourceDefinition;
8
9fn default_await() -> Option<bool> {
10 Some(true)
11}
12
13fn default_return_type() -> Option<String> {
14 Some(ProcessReturnType::STDOUT.to_string())
15}
16
17fn default_cleanup() -> String {
18 ContainerCleanupPolicy::ALWAYS.to_string()
19}
20
21#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
23pub struct RunTaskDefinition {
24 #[serde(rename = "run")]
26 pub run: ProcessTypeDefinition,
27
28 #[serde(flatten)]
30 pub common: TaskDefinitionFields,
31}
32impl RunTaskDefinition {
33 pub fn new(run: ProcessTypeDefinition) -> Self {
35 Self {
36 run,
37 common: TaskDefinitionFields::new(),
38 }
39 }
40}
41
42#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
44pub struct ProcessTypeDefinition {
45 #[serde(rename = "container", skip_serializing_if = "Option::is_none")]
47 pub container: Option<ContainerProcessDefinition>,
48
49 #[serde(rename = "script", skip_serializing_if = "Option::is_none")]
51 pub script: Option<ScriptProcessDefinition>,
52
53 #[serde(rename = "shell", skip_serializing_if = "Option::is_none")]
55 pub shell: Option<ShellProcessDefinition>,
56
57 #[serde(rename = "workflow", skip_serializing_if = "Option::is_none")]
59 pub workflow: Option<WorkflowProcessDefinition>,
60
61 #[serde(
63 rename = "await",
64 default = "default_await",
65 skip_serializing_if = "Option::is_none"
66 )]
67 pub await_: Option<bool>,
68
69 #[serde(
72 rename = "return",
73 default = "default_return_type",
74 skip_serializing_if = "Option::is_none"
75 )]
76 pub return_: Option<String>,
77}
78impl ProcessTypeDefinition {
79 pub fn using_container(container: ContainerProcessDefinition, await_: Option<bool>) -> Self {
81 Self {
82 container: Some(container),
83 await_,
84 ..Self::default()
85 }
86 }
87
88 pub fn using_script(script: ScriptProcessDefinition, await_: Option<bool>) -> Self {
90 Self {
91 script: Some(script),
92 await_,
93 ..Self::default()
94 }
95 }
96
97 pub fn using_shell(shell: ShellProcessDefinition, await_: Option<bool>) -> Self {
99 Self {
100 shell: Some(shell),
101 await_,
102 ..Self::default()
103 }
104 }
105
106 pub fn using_workflow(workflow: WorkflowProcessDefinition, await_: Option<bool>) -> Self {
108 Self {
109 workflow: Some(workflow),
110 await_,
111 ..Self::default()
112 }
113 }
114
115 pub fn get_process_type(&self) -> Option<&str> {
117 if self.container.is_some() {
118 Some(super::constants::ProcessType::CONTAINER)
119 } else if self.script.is_some() {
120 Some(super::constants::ProcessType::SCRIPT)
121 } else if self.shell.is_some() {
122 Some(super::constants::ProcessType::SHELL)
123 } else if self.workflow.is_some() {
124 Some(super::constants::ProcessType::WORKFLOW)
125 } else {
126 None
127 }
128 }
129}
130
131#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
133pub struct ContainerLifetimeDefinition {
134 #[serde(rename = "cleanup", default = "default_cleanup")]
136 pub cleanup: String,
137
138 #[serde(rename = "after", skip_serializing_if = "Option::is_none")]
140 pub after: Option<crate::models::duration::OneOfDurationOrIso8601Expression>,
141}
142
143#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
145pub struct ContainerProcessDefinition {
146 #[serde(rename = "image")]
148 pub image: String,
149
150 #[serde(rename = "name", skip_serializing_if = "Option::is_none")]
152 pub name: Option<String>,
153
154 #[serde(rename = "command", skip_serializing_if = "Option::is_none")]
156 pub command: Option<String>,
157
158 #[serde(rename = "ports", skip_serializing_if = "Option::is_none")]
161 pub ports: Option<HashMap<String, Value>>,
162
163 #[serde(rename = "volumes", skip_serializing_if = "Option::is_none")]
166 pub volumes: Option<HashMap<String, Value>>,
167
168 #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
170 pub environment: Option<HashMap<String, String>>,
171
172 #[serde(rename = "stdin", skip_serializing_if = "Option::is_none")]
174 pub stdin: Option<String>,
175
176 #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
178 pub arguments: Option<Vec<String>>,
179
180 #[serde(rename = "pullPolicy", skip_serializing_if = "Option::is_none")]
182 pub pull_policy: Option<String>,
183
184 #[serde(rename = "lifetime", skip_serializing_if = "Option::is_none")]
186 pub lifetime: Option<ContainerLifetimeDefinition>,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
192#[serde(untagged)]
193pub enum OneOfRunArguments {
194 Array(Vec<String>),
196 Map(HashMap<String, Value>),
198}
199
200impl Default for OneOfRunArguments {
201 fn default() -> Self {
202 OneOfRunArguments::Array(Vec::new())
203 }
204}
205
206impl OneOfRunArguments {
207 pub fn as_array(&self) -> Option<&[String]> {
209 match self {
210 OneOfRunArguments::Array(arr) => Some(arr),
211 _ => None,
212 }
213 }
214
215 pub fn as_map(&self) -> Option<&HashMap<String, Value>> {
217 match self {
218 OneOfRunArguments::Map(map) => Some(map),
219 _ => None,
220 }
221 }
222
223 pub fn is_array(&self) -> bool {
225 matches!(self, OneOfRunArguments::Array(_))
226 }
227
228 pub fn is_map(&self) -> bool {
230 matches!(self, OneOfRunArguments::Map(_))
231 }
232}
233
234#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
236pub struct ScriptProcessDefinition {
237 #[serde(rename = "language")]
239 pub language: String,
240
241 #[serde(rename = "code", skip_serializing_if = "Option::is_none")]
243 pub code: Option<String>,
244
245 #[serde(rename = "source", skip_serializing_if = "Option::is_none")]
247 pub source: Option<ExternalResourceDefinition>,
248
249 #[serde(rename = "stdin", skip_serializing_if = "Option::is_none")]
251 pub stdin: Option<String>,
252
253 #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
255 pub arguments: Option<OneOfRunArguments>,
256
257 #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
259 pub environment: Option<HashMap<String, String>>,
260}
261impl ScriptProcessDefinition {
262 pub fn from_code(
264 language: &str,
265 code: String,
266 stdin: Option<String>,
267 arguments: Option<OneOfRunArguments>,
268 environment: Option<HashMap<String, String>>,
269 ) -> Self {
270 Self {
271 language: language.to_string(),
272 code: Some(code),
273 source: None,
274 stdin,
275 arguments,
276 environment,
277 }
278 }
279
280 pub fn from_source(
282 language: &str,
283 source: ExternalResourceDefinition,
284 stdin: Option<String>,
285 arguments: Option<OneOfRunArguments>,
286 environment: Option<HashMap<String, String>>,
287 ) -> Self {
288 Self {
289 language: language.to_string(),
290 code: None,
291 source: Some(source),
292 stdin,
293 arguments,
294 environment,
295 }
296 }
297}
298
299#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
301pub struct ShellProcessDefinition {
302 #[serde(rename = "command")]
304 pub command: String,
305
306 #[serde(rename = "stdin", skip_serializing_if = "Option::is_none")]
308 pub stdin: Option<String>,
309
310 #[serde(rename = "arguments", skip_serializing_if = "Option::is_none")]
312 pub arguments: Option<OneOfRunArguments>,
313
314 #[serde(rename = "environment", skip_serializing_if = "Option::is_none")]
316 pub environment: Option<HashMap<String, String>>,
317}
318impl ShellProcessDefinition {
319 pub fn new(
320 command: &str,
321 stdin: Option<String>,
322 arguments: Option<OneOfRunArguments>,
323 environment: Option<HashMap<String, String>>,
324 ) -> Self {
325 Self {
326 command: command.to_string(),
327 stdin,
328 arguments,
329 environment,
330 }
331 }
332}
333
334fn default_workflow_version() -> String {
335 "latest".to_string()
336}
337
338#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
340pub struct WorkflowProcessDefinition {
341 #[serde(rename = "namespace")]
343 pub namespace: String,
344
345 #[serde(rename = "name")]
347 pub name: String,
348
349 #[serde(rename = "version", default = "default_workflow_version")]
351 pub version: String,
352
353 #[serde(rename = "input", skip_serializing_if = "Option::is_none")]
355 pub input: Option<Value>,
356}
357impl WorkflowProcessDefinition {
358 pub fn new(namespace: &str, name: &str, version: &str, input: Option<Value>) -> Self {
359 let version = if version.is_empty() {
360 default_workflow_version()
361 } else {
362 version.to_string()
363 };
364 Self {
365 namespace: namespace.to_string(),
366 name: name.to_string(),
367 version,
368 input,
369 }
370 }
371}