Skip to main content

swf_builders/services/task/
try_catch.rs

1use super::*;
2
3// ============== TryTaskDefinitionBuilder ==============
4/// Builder for constructing a try task with error catching.
5#[derive(Default)]
6pub struct TryTaskDefinitionBuilder {
7    task: TryTaskDefinition,
8}
9
10impl TryTaskDefinitionBuilder {
11    pub fn new() -> Self {
12        Self::default()
13    }
14
15    /// Adds a named sub-task to the try block.
16    pub fn do_<F>(&mut self, name: &str, setup: F) -> &mut Self
17    where
18        F: FnOnce(&mut TaskDefinitionBuilder),
19    {
20        let mut builder = TaskDefinitionBuilder::new();
21        setup(&mut builder);
22        let task = builder.build();
23        self.task.try_.add(name.to_string(), task);
24        self
25    }
26
27    /// Configures the error catcher for this try task using a builder callback.
28    pub fn catch<F>(&mut self, setup: F) -> &mut Self
29    where
30        F: FnOnce(&mut ErrorCatcherDefinitionBuilder),
31    {
32        let mut builder = ErrorCatcherDefinitionBuilder::new(&mut self.task);
33        setup(&mut builder);
34        self
35    }
36}
37
38impl_task_definition_builder_base!(TryTaskDefinitionBuilder, task, TaskDefinition::Try);
39
40/// Builder for constructing an error catcher within a try task.
41pub struct ErrorCatcherDefinitionBuilder<'a> {
42    parent: &'a mut TryTaskDefinition,
43}
44
45impl<'a> ErrorCatcherDefinitionBuilder<'a> {
46    fn new(parent: &'a mut TryTaskDefinition) -> Self {
47        parent.catch = ErrorCatcherDefinition::default();
48        Self { parent }
49    }
50
51    /// Configures the error filter for this catcher using a builder callback.
52    pub fn errors<F>(&mut self, setup: F) -> &mut Self
53    where
54        F: FnOnce(&mut ErrorFilterDefinitionBuilder),
55    {
56        let mut builder = ErrorFilterDefinitionBuilder::new();
57        setup(&mut builder);
58        self.parent.catch.errors = Some(builder.build());
59        self
60    }
61
62    /// Sets the condition expression for when the catcher applies.
63    pub fn when(&mut self, when: &str) -> &mut Self {
64        self.parent.catch.when = Some(when.to_string());
65        self
66    }
67
68    /// Configures the retry policy for this catcher using a builder callback.
69    pub fn retry<F>(&mut self, setup: F) -> &mut Self
70    where
71        F: FnOnce(&mut RetryPolicyDefinitionBuilder),
72    {
73        let mut builder = RetryPolicyDefinitionBuilder::new();
74        setup(&mut builder);
75        self.parent.catch.retry = Some(OneOfRetryPolicyDefinitionOrReference::Retry(Box::new(
76            builder.build(),
77        )));
78        self
79    }
80
81    /// Sets the variable name to store the caught error.
82    pub fn as_(&mut self, as_var: &str) -> &mut Self {
83        self.parent.catch.as_ = Some(as_var.to_string());
84        self
85    }
86
87    /// Sets the condition expression for when the catcher should not apply.
88    pub fn except_when(&mut self, except_when: &str) -> &mut Self {
89        self.parent.catch.except_when = Some(except_when.to_string());
90        self
91    }
92
93    /// Adds a named sub-task to execute when the error is caught.
94    pub fn do_<F>(&mut self, name: &str, setup: F) -> &mut Self
95    where
96        F: FnOnce(&mut TaskDefinitionBuilder),
97    {
98        let mut builder = TaskDefinitionBuilder::new();
99        setup(&mut builder);
100        let task = builder.build();
101        self.parent
102            .catch
103            .do_
104            .get_or_insert_with(swf_core::models::map::Map::default)
105            .add(name.to_string(), task);
106        self
107    }
108}
109
110/// Builder for constructing an error filter definition.
111pub struct ErrorFilterDefinitionBuilder {
112    filter: ErrorFilterDefinition,
113}
114
115impl ErrorFilterDefinitionBuilder {
116    pub fn new() -> Self {
117        Self {
118            filter: ErrorFilterDefinition::default(),
119        }
120    }
121
122    /// Sets the error type to match.
123    pub fn with_type(&mut self, type_: &str) -> &mut Self {
124        self.filter
125            .with
126            .get_or_insert_with(ErrorFilterProperties::default)
127            .type_ = Some(type_.to_string());
128        self
129    }
130
131    /// Sets the error status to match.
132    pub fn with_status(&mut self, status: Value) -> &mut Self {
133        self.filter
134            .with
135            .get_or_insert_with(ErrorFilterProperties::default)
136            .status = Some(status);
137        self
138    }
139
140    /// Sets the error instance to match.
141    pub fn with_instance(&mut self, instance: &str) -> &mut Self {
142        self.filter
143            .with
144            .get_or_insert_with(ErrorFilterProperties::default)
145            .instance = Some(instance.to_string());
146        self
147    }
148
149    /// Sets the error title to match.
150    pub fn with_title(&mut self, title: &str) -> &mut Self {
151        self.filter
152            .with
153            .get_or_insert_with(ErrorFilterProperties::default)
154            .title = Some(title.to_string());
155        self
156    }
157
158    /// Sets the error detail to match.
159    pub fn with_detail(&mut self, details: &str) -> &mut Self {
160        self.filter
161            .with
162            .get_or_insert_with(ErrorFilterProperties::default)
163            .detail = Some(details.to_string());
164        self
165    }
166
167    /// Builds the `ErrorFilterDefinition`.
168    pub fn build(self) -> ErrorFilterDefinition {
169        self.filter
170    }
171}
172
173impl Default for ErrorFilterDefinitionBuilder {
174    fn default() -> Self {
175        Self::new()
176    }
177}
178
179/// Builder for constructing a retry policy definition.
180pub struct RetryPolicyDefinitionBuilder {
181    policy: RetryPolicyDefinition,
182}
183
184impl RetryPolicyDefinitionBuilder {
185    pub fn new() -> Self {
186        Self {
187            policy: RetryPolicyDefinition::default(),
188        }
189    }
190
191    /// Sets the condition for when the retry policy should not apply.
192    pub fn except_when(&mut self, except_when: &str) -> &mut Self {
193        self.policy.except_when = Some(except_when.to_string());
194        self
195    }
196
197    /// Sets the condition for when the retry policy applies.
198    pub fn when(&mut self, when: &str) -> &mut Self {
199        self.policy.when = Some(when.to_string());
200        self
201    }
202
203    /// Configures the retry limit using a builder callback.
204    pub fn limit<F>(&mut self, setup: F) -> &mut Self
205    where
206        F: FnOnce(&mut RetryLimitDefinitionBuilder),
207    {
208        let mut builder = RetryLimitDefinitionBuilder::new();
209        setup(&mut builder);
210        self.policy.limit = Some(builder.build());
211        self
212    }
213
214    /// Sets the initial delay before the first retry.
215    pub fn delay(&mut self, delay: Duration) -> &mut Self {
216        self.policy.delay = Some(OneOfDurationOrIso8601Expression::Duration(delay));
217        self
218    }
219
220    /// Configures the backoff strategy using a builder callback.
221    pub fn backoff<F>(&mut self, setup: F) -> &mut Self
222    where
223        F: FnOnce(&mut BackoffStrategyDefinitionBuilder),
224    {
225        let mut builder = BackoffStrategyDefinitionBuilder::new();
226        setup(&mut builder);
227        self.policy.backoff = Some(builder.build());
228        self
229    }
230
231    /// Configures the jitter settings using a builder callback.
232    pub fn jitter<F>(&mut self, setup: F) -> &mut Self
233    where
234        F: FnOnce(&mut JitterDefinitionBuilder),
235    {
236        let mut builder = JitterDefinitionBuilder::new();
237        setup(&mut builder);
238        self.policy.jitter = Some(builder.build());
239        self
240    }
241
242    /// Builds the `RetryPolicyDefinition`.
243    pub fn build(self) -> RetryPolicyDefinition {
244        self.policy
245    }
246}
247
248impl Default for RetryPolicyDefinitionBuilder {
249    fn default() -> Self {
250        Self::new()
251    }
252}
253
254/// Builder for constructing a retry policy limit definition.
255pub struct RetryLimitDefinitionBuilder {
256    limit: RetryPolicyLimitDefinition,
257}
258
259impl RetryLimitDefinitionBuilder {
260    pub fn new() -> Self {
261        Self {
262            limit: RetryPolicyLimitDefinition::default(),
263        }
264    }
265
266    /// Sets the maximum number of retry attempts.
267    pub fn attempt_count(&mut self, count: u16) -> &mut Self {
268        self.limit
269            .attempt
270            .get_or_insert_with(RetryAttemptLimitDefinition::default)
271            .count = Some(count);
272        self
273    }
274
275    /// Sets the maximum duration for a single retry attempt.
276    pub fn attempt_duration(&mut self, duration: Duration) -> &mut Self {
277        self.limit
278            .attempt
279            .get_or_insert_with(RetryAttemptLimitDefinition::default)
280            .duration = Some(OneOfDurationOrIso8601Expression::Duration(duration));
281        self
282    }
283
284    /// Sets the overall maximum duration for all retries combined.
285    pub fn duration(&mut self, duration: Duration) -> &mut Self {
286        self.limit.duration = Some(OneOfDurationOrIso8601Expression::Duration(duration));
287        self
288    }
289
290    /// Builds the `RetryPolicyLimitDefinition`.
291    pub fn build(self) -> RetryPolicyLimitDefinition {
292        self.limit
293    }
294}
295
296impl Default for RetryLimitDefinitionBuilder {
297    fn default() -> Self {
298        Self::new()
299    }
300}
301
302/// Builder for constructing a backoff strategy definition.
303pub struct BackoffStrategyDefinitionBuilder {
304    strategy: BackoffStrategyDefinition,
305    linear_builder: Option<LinearBackoffDefinitionBuilder>,
306    constant_builder: Option<ConstantBackoffDefinitionBuilder>,
307    exponential_builder: Option<ExponentialBackoffDefinitionBuilder>,
308}
309
310impl BackoffStrategyDefinitionBuilder {
311    pub fn new() -> Self {
312        Self {
313            strategy: BackoffStrategyDefinition::default(),
314            linear_builder: None,
315            constant_builder: None,
316            exponential_builder: None,
317        }
318    }
319
320    /// Configures a linear backoff strategy.
321    pub fn linear(&mut self) -> &mut LinearBackoffDefinitionBuilder {
322        self.linear_builder = Some(LinearBackoffDefinitionBuilder::new());
323        self.get_linear_builder()
324    }
325
326    fn get_linear_builder(&mut self) -> &mut LinearBackoffDefinitionBuilder {
327        if let Some(ref mut builder) = self.linear_builder {
328            builder
329        } else {
330            unreachable!("Linear builder should be set")
331        }
332    }
333
334    /// Configures a constant backoff strategy.
335    pub fn constant(&mut self) -> &mut ConstantBackoffDefinitionBuilder {
336        self.constant_builder = Some(ConstantBackoffDefinitionBuilder::new());
337        self.get_constant_builder()
338    }
339
340    fn get_constant_builder(&mut self) -> &mut ConstantBackoffDefinitionBuilder {
341        if let Some(ref mut builder) = self.constant_builder {
342            builder
343        } else {
344            unreachable!("Constant builder should be set")
345        }
346    }
347
348    /// Configures an exponential backoff strategy.
349    pub fn exponential(&mut self) -> &mut ExponentialBackoffDefinitionBuilder {
350        self.exponential_builder = Some(ExponentialBackoffDefinitionBuilder::new());
351        self.get_exponential_builder()
352    }
353
354    fn get_exponential_builder(&mut self) -> &mut ExponentialBackoffDefinitionBuilder {
355        if let Some(ref mut builder) = self.exponential_builder {
356            builder
357        } else {
358            unreachable!("Exponential builder should be set")
359        }
360    }
361
362    /// Builds the `BackoffStrategyDefinition`.
363    pub fn build(mut self) -> BackoffStrategyDefinition {
364        if let Some(builder) = self.linear_builder.take() {
365            self.strategy.linear = Some(builder.build());
366        }
367        if let Some(builder) = self.constant_builder.take() {
368            self.strategy.constant = Some(builder.build());
369        }
370        if let Some(builder) = self.exponential_builder.take() {
371            self.strategy.exponential = Some(builder.build());
372        }
373        self.strategy
374    }
375}
376
377impl Default for BackoffStrategyDefinitionBuilder {
378    fn default() -> Self {
379        Self::new()
380    }
381}
382
383/// Builder for constructing a linear backoff definition.
384pub struct LinearBackoffDefinitionBuilder {
385    linear: LinearBackoffDefinition,
386}
387
388impl LinearBackoffDefinitionBuilder {
389    fn new() -> Self {
390        Self {
391            linear: LinearBackoffDefinition::default(),
392        }
393    }
394
395    /// Sets the increment duration added on each retry.
396    pub fn with_increment(&mut self, increment: Duration) -> &mut Self {
397        self.linear.increment = Some(increment);
398        self
399    }
400
401    /// Builds the `LinearBackoffDefinition`.
402    pub fn build(self) -> LinearBackoffDefinition {
403        self.linear
404    }
405}
406
407impl Default for LinearBackoffDefinitionBuilder {
408    fn default() -> Self {
409        Self::new()
410    }
411}
412
413/// Builder for constructing a constant backoff definition.
414pub struct ConstantBackoffDefinitionBuilder {
415    constant: ConstantBackoffDefinition,
416}
417
418impl ConstantBackoffDefinitionBuilder {
419    fn new() -> Self {
420        Self {
421            constant: ConstantBackoffDefinition::default(),
422        }
423    }
424
425    /// Sets the constant delay duration between retries.
426    pub fn with_delay(&mut self, delay: &str) -> &mut Self {
427        self.constant = ConstantBackoffDefinition::with_delay(delay);
428        self
429    }
430
431    /// Builds the `ConstantBackoffDefinition`.
432    pub fn build(self) -> ConstantBackoffDefinition {
433        self.constant
434    }
435}
436
437impl Default for ConstantBackoffDefinitionBuilder {
438    fn default() -> Self {
439        Self::new()
440    }
441}
442
443/// Builder for constructing an exponential backoff definition.
444pub struct ExponentialBackoffDefinitionBuilder {
445    exponential: ExponentialBackoffDefinition,
446}
447
448impl ExponentialBackoffDefinitionBuilder {
449    fn new() -> Self {
450        Self {
451            exponential: ExponentialBackoffDefinition::default(),
452        }
453    }
454
455    /// Sets the exponential growth factor.
456    pub fn with_factor(&mut self, factor: f64) -> &mut Self {
457        self.exponential = ExponentialBackoffDefinition::with_factor(factor);
458        self
459    }
460
461    /// Sets the exponential growth factor and maximum delay cap.
462    pub fn with_factor_and_max_delay(&mut self, factor: f64, max_delay: &str) -> &mut Self {
463        self.exponential =
464            ExponentialBackoffDefinition::with_factor_and_max_delay(factor, max_delay);
465        self
466    }
467
468    /// Builds the `ExponentialBackoffDefinition`.
469    pub fn build(self) -> ExponentialBackoffDefinition {
470        self.exponential
471    }
472}
473
474impl Default for ExponentialBackoffDefinitionBuilder {
475    fn default() -> Self {
476        Self::new()
477    }
478}
479
480/// Builder for constructing a jitter definition for retry delays.
481pub struct JitterDefinitionBuilder {
482    jitter: JitterDefinition,
483}
484
485impl JitterDefinitionBuilder {
486    pub fn new() -> Self {
487        Self {
488            jitter: JitterDefinition::default(),
489        }
490    }
491
492    /// Sets the minimum jitter duration.
493    pub fn from(&mut self, from: Duration) -> &mut Self {
494        self.jitter.from = from;
495        self
496    }
497
498    /// Sets the maximum jitter duration.
499    pub fn to(&mut self, to: Duration) -> &mut Self {
500        self.jitter.to = to;
501        self
502    }
503
504    /// Builds the `JitterDefinition`.
505    pub fn build(self) -> JitterDefinition {
506        self.jitter
507    }
508}
509
510impl Default for JitterDefinitionBuilder {
511    fn default() -> Self {
512        Self::new()
513    }
514}