Skip to main content

camel_dsl/
yaml_ast.rs

1use serde::Deserialize;
2
3#[derive(Deserialize)]
4pub struct YamlRoutes {
5    pub routes: Vec<YamlRoute>,
6}
7
8#[derive(Deserialize)]
9pub struct YamlRoute {
10    pub id: String,
11    pub from: String,
12    #[serde(default)]
13    pub steps: Vec<YamlStep>,
14    #[serde(default = "default_true")]
15    pub auto_startup: bool,
16    #[serde(default = "default_startup_order")]
17    pub startup_order: i32,
18    #[serde(default)]
19    pub sequential: bool,
20    #[serde(default)]
21    pub concurrent: Option<usize>,
22    #[serde(default)]
23    pub error_handler: Option<YamlErrorHandler>,
24    #[serde(default)]
25    pub circuit_breaker: Option<YamlCircuitBreaker>,
26    #[serde(default)]
27    pub on_complete: Option<String>,
28    #[serde(default)]
29    pub on_failure: Option<String>,
30}
31
32#[derive(Deserialize)]
33pub struct YamlErrorHandler {
34    #[serde(default)]
35    pub dead_letter_channel: Option<String>,
36    #[serde(default)]
37    pub retry: Option<YamlRedeliveryPolicy>,
38    #[serde(default)]
39    pub on_exceptions: Option<Vec<YamlOnException>>,
40}
41
42#[derive(Deserialize)]
43pub struct YamlOnException {
44    #[serde(default)]
45    pub kind: Option<String>,
46    #[serde(default)]
47    pub message_contains: Option<String>,
48    #[serde(default)]
49    pub retry: Option<YamlRedeliveryPolicy>,
50}
51
52#[derive(Deserialize)]
53pub struct YamlRedeliveryPolicy {
54    pub max_attempts: u32,
55    #[serde(default = "default_initial_delay_ms")]
56    pub initial_delay_ms: u64,
57    #[serde(default = "default_multiplier")]
58    pub multiplier: f64,
59    #[serde(default = "default_max_delay_ms")]
60    pub max_delay_ms: u64,
61    #[serde(default = "default_jitter_factor")]
62    pub jitter_factor: f64,
63    #[serde(default)]
64    pub handled_by: Option<String>,
65}
66
67#[derive(Deserialize)]
68pub struct YamlCircuitBreaker {
69    #[serde(default = "default_failure_threshold")]
70    pub failure_threshold: u32,
71    #[serde(default = "default_open_duration_ms")]
72    pub open_duration_ms: u64,
73}
74
75fn default_true() -> bool {
76    true
77}
78
79fn default_startup_order() -> i32 {
80    1000
81}
82
83fn default_initial_delay_ms() -> u64 {
84    100
85}
86
87fn default_multiplier() -> f64 {
88    2.0
89}
90
91fn default_max_delay_ms() -> u64 {
92    10_000
93}
94
95fn default_jitter_factor() -> f64 {
96    0.0
97}
98
99fn default_failure_threshold() -> u32 {
100    5
101}
102
103fn default_open_duration_ms() -> u64 {
104    30_000
105}
106
107#[derive(Deserialize, Debug)]
108pub struct DelayStep {
109    pub delay: DelayBody,
110}
111
112#[derive(Deserialize, Debug)]
113#[serde(untagged)]
114pub enum DelayBody {
115    Short(u64),
116    Full(DelayFullConfig),
117}
118
119#[derive(Deserialize, Debug)]
120#[serde(deny_unknown_fields)]
121pub struct DelayFullConfig {
122    pub delay_ms: u64,
123    #[serde(default)]
124    pub dynamic_header: Option<String>,
125}
126
127#[derive(Deserialize, Debug)]
128pub struct LoopStep {
129    #[serde(rename = "loop")]
130    pub loop_data: LoopData,
131}
132
133#[derive(Deserialize, Debug)]
134#[serde(untagged)]
135pub enum LoopData {
136    /// Shorthand: `loop: 3`
137    Count(usize),
138    /// Full form with config block.
139    Full(LoopFullConfig),
140}
141
142#[derive(Deserialize, Debug)]
143#[serde(deny_unknown_fields)]
144pub struct LoopFullConfig {
145    /// Fixed iteration count. Mutually exclusive with `while`.
146    pub count: Option<usize>,
147    /// While condition — expression-only (no nested steps).
148    #[serde(rename = "while")]
149    pub while_expr: Option<LoopWhileExpr>,
150    #[serde(default)]
151    pub steps: Vec<YamlStep>,
152}
153
154/// Expression-only predicate for loop while condition.
155#[derive(Deserialize, Debug)]
156#[serde(deny_unknown_fields)]
157pub struct LoopWhileExpr {
158    #[serde(default)]
159    pub language: Option<String>,
160    #[serde(default)]
161    pub source: Option<String>,
162    #[serde(default)]
163    pub simple: Option<String>,
164    #[serde(default)]
165    pub rhai: Option<String>,
166    #[serde(default)]
167    pub jsonpath: Option<String>,
168    #[serde(default)]
169    pub xpath: Option<String>,
170}
171
172#[derive(Deserialize, Debug)]
173#[serde(untagged)]
174pub enum YamlStep {
175    To(ToStep),
176    SetHeader(SetHeaderStep),
177    SetBody(SetBodyStep),
178    Bean(BeanStep),
179    Choice(ChoiceStep),
180    DynamicRouter(DynamicRouterStep),
181    Filter(FilterStep),
182    LoadBalance(LoadBalanceStep),
183    Log(LogStep),
184    Split(SplitStep),
185    Aggregate(AggregateStep),
186    WireTap(WireTapStep),
187    Multicast(MulticastStep),
188    RoutingSlip(RoutingSlipStep),
189    RecipientList(RecipientListStep),
190    Stop(StopStep),
191    StreamCache(StreamCacheStep),
192    Throttle(ThrottleStep),
193    Transform(TransformStep),
194    Script(ScriptStep),
195    ConvertBodyTo(ConvertBodyToStep),
196    Marshal(MarshalStep),
197    Unmarshal(UnmarshalStep),
198    Delay(DelayStep),
199    Loop(LoopStep),
200    Validate(ValidateStep),
201}
202
203#[derive(Deserialize, Debug)]
204pub struct ToStep {
205    pub to: String,
206}
207
208#[derive(Deserialize, Debug)]
209pub struct SetHeaderStep {
210    pub set_header: SetHeaderData,
211}
212
213#[derive(Deserialize, Debug)]
214#[serde(deny_unknown_fields)]
215pub struct SetHeaderData {
216    pub key: String,
217    #[serde(default)]
218    pub value: Option<serde_json::Value>,
219    #[serde(default)]
220    pub language: Option<String>,
221    #[serde(default)]
222    pub source: Option<String>,
223    #[serde(default)]
224    pub simple: Option<String>,
225    #[serde(default)]
226    pub rhai: Option<String>,
227    #[serde(default)]
228    pub jsonpath: Option<String>,
229    #[serde(default)]
230    pub xpath: Option<String>,
231}
232
233#[derive(Deserialize, Debug)]
234pub struct SetBodyStep {
235    pub set_body: SetBodyData,
236}
237
238/// `transform:` step — alias for `set_body:`, reuses all SetBodyData types.
239#[derive(Deserialize, Debug)]
240pub struct TransformStep {
241    pub transform: SetBodyData,
242}
243
244#[derive(Deserialize, Debug)]
245#[serde(untagged)]
246pub enum SetBodyData {
247    // Config must be tried BEFORE Literal: serde_json::Value matches any YAML value (including
248    // objects), so it would greedily swallow `{ simple: "..." }` as a Literal JSON object
249    // instead of a SetBodyConfig. By placing Config first, structured forms like
250    // `set_body: { simple: "..." }` deserialize correctly.
251    Config(SetBodyConfig),
252    Literal(serde_json::Value),
253}
254
255#[derive(Deserialize, Debug)]
256#[serde(deny_unknown_fields)]
257pub struct SetBodyConfig {
258    #[serde(default)]
259    pub value: Option<serde_json::Value>,
260    #[serde(default)]
261    pub language: Option<String>,
262    #[serde(default)]
263    pub source: Option<String>,
264    #[serde(default)]
265    pub simple: Option<String>,
266    #[serde(default)]
267    pub rhai: Option<String>,
268    #[serde(default)]
269    pub jsonpath: Option<String>,
270    #[serde(default)]
271    pub xpath: Option<String>,
272}
273
274#[derive(Deserialize, Debug)]
275#[serde(untagged)]
276pub enum LogBody {
277    Message(String),
278    Config(LogConfig),
279}
280
281#[derive(Deserialize, Debug)]
282#[serde(deny_unknown_fields)]
283pub struct LogConfig {
284    /// The log message. Can be a plain string literal or a nested expression object.
285    pub message: LogMessageData,
286    #[serde(default)]
287    pub level: Option<String>,
288}
289
290/// The `message` field inside a `log: { message: ... }` config block.
291/// Either a bare string literal or a value-source expression (simple, rhai, language+source).
292#[derive(Deserialize, Debug)]
293#[serde(untagged)]
294pub enum LogMessageData {
295    Literal(String),
296    Expr(LogMessageExpr),
297}
298
299#[derive(Deserialize, Debug)]
300#[serde(deny_unknown_fields)]
301pub struct LogMessageExpr {
302    #[serde(default)]
303    pub value: Option<String>,
304    #[serde(default)]
305    pub language: Option<String>,
306    #[serde(default)]
307    pub source: Option<String>,
308    #[serde(default)]
309    pub simple: Option<String>,
310    #[serde(default)]
311    pub rhai: Option<String>,
312    #[serde(default)]
313    pub jsonpath: Option<String>,
314    #[serde(default)]
315    pub xpath: Option<String>,
316}
317
318#[derive(Deserialize, Debug)]
319pub struct LogStep {
320    pub log: LogBody,
321}
322
323#[derive(Deserialize, Debug)]
324pub struct FilterStep {
325    pub filter: PredicateBlock,
326}
327
328#[derive(Deserialize, Debug)]
329#[serde(deny_unknown_fields)]
330pub struct PredicateBlock {
331    #[serde(default)]
332    pub language: Option<String>,
333    #[serde(default)]
334    pub source: Option<String>,
335    #[serde(default)]
336    pub simple: Option<String>,
337    #[serde(default)]
338    pub rhai: Option<String>,
339    #[serde(default)]
340    pub jsonpath: Option<String>,
341    #[serde(default)]
342    pub xpath: Option<String>,
343    #[serde(default)]
344    pub steps: Vec<YamlStep>,
345}
346
347#[derive(Deserialize, Debug)]
348pub struct ChoiceStep {
349    pub choice: ChoiceData,
350}
351
352#[derive(Deserialize, Debug)]
353#[serde(deny_unknown_fields)]
354pub struct ChoiceData {
355    #[serde(default)]
356    pub when: Vec<PredicateBlock>,
357    #[serde(default)]
358    pub otherwise: Option<Vec<YamlStep>>,
359}
360
361#[derive(Deserialize, Debug)]
362pub struct SplitStep {
363    pub split: SplitData,
364}
365
366#[derive(Deserialize, Debug)]
367#[serde(deny_unknown_fields)]
368pub struct SplitData {
369    #[serde(default)]
370    pub expression: Option<SplitExpressionYaml>,
371    #[serde(default = "default_split_aggregation")]
372    pub aggregation: String,
373    #[serde(default)]
374    pub parallel: bool,
375    #[serde(default)]
376    pub parallel_limit: Option<usize>,
377    #[serde(default = "default_true")]
378    pub stop_on_exception: bool,
379    #[serde(default)]
380    pub steps: Vec<YamlStep>,
381}
382
383#[derive(Deserialize, Debug, Clone)]
384#[serde(untagged)]
385pub enum SplitExpressionYaml {
386    Simple(String),
387    Config(SplitExpressionConfig),
388}
389
390#[derive(Deserialize, Debug, Clone)]
391#[serde(deny_unknown_fields)]
392pub struct SplitExpressionConfig {
393    #[serde(default)]
394    pub language: Option<String>,
395    #[serde(default)]
396    pub source: Option<String>,
397    #[serde(default)]
398    pub simple: Option<String>,
399    #[serde(default)]
400    pub rhai: Option<String>,
401    #[serde(default)]
402    pub jsonpath: Option<String>,
403    #[serde(default)]
404    pub xpath: Option<String>,
405}
406
407fn default_split_aggregation() -> String {
408    "last_wins".to_string()
409}
410
411#[derive(Deserialize, Debug)]
412pub struct AggregateStep {
413    pub aggregate: AggregateData,
414}
415
416#[derive(Deserialize, Debug)]
417#[serde(deny_unknown_fields)]
418pub struct AggregateData {
419    pub header: String,
420    #[serde(default)]
421    pub correlation_key: Option<String>,
422    #[serde(default)]
423    pub completion_size: Option<usize>,
424    #[serde(default)]
425    pub completion_timeout_ms: Option<u64>,
426    #[serde(default)]
427    pub completion_predicate: Option<PredicateBlock>,
428    #[serde(default = "default_aggregate_strategy")]
429    pub strategy: String,
430    #[serde(default)]
431    pub max_buckets: Option<usize>,
432    #[serde(default)]
433    pub bucket_ttl_ms: Option<u64>,
434    #[serde(default)]
435    pub force_completion_on_stop: Option<bool>,
436    #[serde(default)]
437    pub discard_on_timeout: Option<bool>,
438}
439
440fn default_aggregate_strategy() -> String {
441    "collect_all".to_string()
442}
443
444#[derive(Deserialize, Debug)]
445pub struct WireTapStep {
446    pub wire_tap: String,
447}
448
449#[derive(Deserialize, Debug)]
450pub struct MulticastStep {
451    pub multicast: MulticastData,
452}
453
454#[derive(Deserialize, Debug)]
455#[serde(deny_unknown_fields)]
456pub struct MulticastData {
457    #[serde(default)]
458    pub parallel: bool,
459    #[serde(default)]
460    pub parallel_limit: Option<usize>,
461    #[serde(default)]
462    pub stop_on_exception: bool,
463    #[serde(default)]
464    pub timeout_ms: Option<u64>,
465    #[serde(default = "default_multicast_aggregation")]
466    pub aggregation: String,
467    #[serde(default)]
468    pub steps: Vec<YamlStep>,
469}
470
471fn default_multicast_aggregation() -> String {
472    "last_wins".to_string()
473}
474
475#[derive(Deserialize, Debug)]
476pub struct StopStep {
477    pub stop: bool,
478}
479
480#[derive(Deserialize, Debug)]
481pub struct StreamCacheStep {
482    pub stream_cache: StreamCacheBody,
483}
484
485#[derive(Deserialize, Debug)]
486#[serde(untagged)]
487pub enum StreamCacheBody {
488    Enabled(bool),
489    Config(StreamCacheConfig),
490}
491
492#[derive(Deserialize, Debug)]
493#[serde(deny_unknown_fields)]
494pub struct StreamCacheConfig {
495    #[serde(default)]
496    pub threshold: Option<usize>,
497}
498
499#[derive(Deserialize, Debug)]
500pub struct ScriptStep {
501    pub script: ScriptData,
502}
503
504#[derive(Deserialize, Debug)]
505pub struct ConvertBodyToStep {
506    pub convert_body_to: String,
507}
508
509#[derive(Deserialize, Debug)]
510pub struct MarshalStep {
511    pub marshal: String,
512}
513
514#[derive(Deserialize, Debug)]
515pub struct UnmarshalStep {
516    pub unmarshal: String,
517}
518
519#[derive(Deserialize, Debug)]
520pub struct ValidateStep {
521    pub validate: String,
522}
523
524#[derive(Deserialize, Debug)]
525#[serde(deny_unknown_fields)]
526pub struct ScriptData {
527    pub language: String,
528    pub source: String,
529}
530
531#[derive(Deserialize, Debug)]
532#[serde(deny_unknown_fields)]
533pub struct ThrottleStep {
534    pub throttle: ThrottleData,
535}
536
537#[derive(Deserialize, Debug)]
538#[serde(deny_unknown_fields)]
539pub struct ThrottleData {
540    pub max_requests: usize,
541    #[serde(default = "default_throttle_period_secs")]
542    pub period_secs: u64,
543    #[serde(default)]
544    pub strategy: Option<String>,
545    #[serde(default)]
546    pub steps: Vec<YamlStep>,
547}
548
549fn default_throttle_period_secs() -> u64 {
550    1
551}
552
553#[derive(Deserialize, Debug)]
554#[serde(deny_unknown_fields)]
555pub struct LoadBalanceStep {
556    pub load_balance: LoadBalanceData,
557}
558
559#[derive(Deserialize, Debug)]
560#[serde(deny_unknown_fields)]
561pub struct LoadBalanceData {
562    #[serde(default = "default_lb_strategy")]
563    pub strategy: String,
564    #[serde(default)]
565    pub distribution_ratio: Option<String>,
566    #[serde(default)]
567    pub parallel: bool,
568    #[serde(default)]
569    pub steps: Vec<YamlStep>,
570}
571
572fn default_lb_strategy() -> String {
573    "round_robin".to_string()
574}
575
576#[derive(Deserialize, Debug)]
577#[serde(deny_unknown_fields)]
578pub struct DynamicRouterStep {
579    pub dynamic_router: DynamicRouterData,
580}
581
582#[derive(Deserialize, Debug)]
583#[serde(deny_unknown_fields)]
584pub struct DynamicRouterData {
585    #[serde(default)]
586    pub simple: Option<String>,
587    #[serde(default)]
588    pub rhai: Option<String>,
589    #[serde(default)]
590    pub language: Option<String>,
591    #[serde(default)]
592    pub source: Option<String>,
593    #[serde(default = "default_uri_delimiter")]
594    pub uri_delimiter: String,
595    #[serde(default = "default_cache_size")]
596    pub cache_size: i32,
597    #[serde(default)]
598    pub ignore_invalid_endpoints: bool,
599    #[serde(default = "default_max_iterations")]
600    pub max_iterations: usize,
601}
602
603fn default_uri_delimiter() -> String {
604    ",".to_string()
605}
606
607fn default_cache_size() -> i32 {
608    1000
609}
610
611fn default_max_iterations() -> usize {
612    1000
613}
614
615#[derive(Deserialize, Debug)]
616#[serde(deny_unknown_fields)]
617pub struct RoutingSlipStep {
618    pub routing_slip: RoutingSlipData,
619}
620
621#[derive(Deserialize, Debug)]
622#[serde(deny_unknown_fields)]
623pub struct RoutingSlipData {
624    #[serde(default)]
625    pub simple: Option<String>,
626    #[serde(default)]
627    pub rhai: Option<String>,
628    #[serde(default)]
629    pub language: Option<String>,
630    #[serde(default)]
631    pub source: Option<String>,
632    #[serde(default = "default_uri_delimiter")]
633    pub uri_delimiter: String,
634    #[serde(default = "default_cache_size")]
635    pub cache_size: i32,
636    #[serde(default)]
637    pub ignore_invalid_endpoints: bool,
638}
639
640#[derive(Deserialize, Debug)]
641#[serde(deny_unknown_fields)]
642pub struct RecipientListStep {
643    pub recipient_list: RecipientListData,
644}
645
646#[derive(Deserialize, Debug)]
647#[serde(deny_unknown_fields)]
648pub struct RecipientListData {
649    #[serde(default)]
650    pub simple: Option<String>,
651    #[serde(default)]
652    pub rhai: Option<String>,
653    #[serde(default)]
654    pub language: Option<String>,
655    #[serde(default)]
656    pub source: Option<String>,
657    #[serde(default = "default_uri_delimiter")]
658    pub delimiter: String,
659    #[serde(default)]
660    pub parallel: bool,
661    #[serde(default)]
662    pub parallel_limit: Option<usize>,
663    #[serde(default)]
664    pub stop_on_exception: bool,
665    #[serde(default)]
666    pub strategy: Option<String>,
667}
668
669#[derive(Deserialize, Debug)]
670#[serde(deny_unknown_fields)]
671pub struct BeanStep {
672    pub bean: BeanStepData,
673}
674
675#[derive(Deserialize, Debug)]
676#[serde(deny_unknown_fields)]
677pub struct BeanStepData {
678    pub name: String,
679    pub method: String,
680}