1use serde::Deserialize;
9
10#[derive(Debug, Deserialize)]
11pub struct Document {
12 pub routes: Vec<RouteSpec>,
13}
14
15#[derive(Debug, Deserialize)]
16pub struct RouteSpec {
17 pub id: String,
18 pub from: String,
19 #[serde(default)]
20 pub steps: Vec<Step>,
21}
22
23#[derive(Debug, Deserialize)]
24#[serde(untagged, deny_unknown_fields)]
25pub enum Step {
26 To { to: String },
27 WireTap { wire_tap: String },
28 Filter { filter: PredicateSpec },
29 Transform { transform: TransformSpec },
30 Delay { delay: DelaySpec },
31 Throttle { throttle: ThrottleSpec },
32 Multicast { multicast: Vec<String> },
33 Split { split: SplitSpec },
34 Choice { choice: ChoiceSpec },
35 RecipientList { recipient_list: RecipientListSpec },
36 LoadBalance { load_balance: LoadBalanceSpec },
37 Idempotent { idempotent: IdempotentSpec },
38 OnException { on_exception: OnExceptionSpec },
39}
40
41#[derive(Debug, Deserialize)]
42#[serde(untagged, deny_unknown_fields)]
43pub enum PredicateSpec {
44 BodyContains { body_contains: String },
45 BodyStartsWith { body_starts_with: String },
46 HeaderEquals { header_equals: HeaderEq },
47 HeaderPresent { header_present: String },
48}
49
50#[derive(Debug, Deserialize)]
51pub struct HeaderEq {
52 pub name: String,
53 pub value: String,
54}
55
56#[derive(Debug, Deserialize)]
57#[serde(untagged, deny_unknown_fields)]
58pub enum TransformSpec {
59 Upper { upper: bool },
60 Lower { lower: bool },
61 Prepend { prepend: String },
62 Append { append: String },
63}
64
65#[derive(Debug, Deserialize)]
66pub struct DelaySpec {
67 pub millis: u64,
68}
69
70#[derive(Debug, Deserialize)]
71pub struct ThrottleSpec {
72 pub max: u32,
73 pub period_millis: u64,
74}
75
76#[derive(Debug, Deserialize)]
77pub struct SplitSpec {
78 #[serde(default = "default_split_on")]
79 pub on: char,
80 #[serde(default)]
81 pub then: Vec<Step>,
82}
83
84fn default_split_on() -> char {
85 ','
86}
87
88#[derive(Debug, Deserialize)]
89pub struct ChoiceSpec {
90 #[serde(default)]
91 pub when: Vec<WhenSpec>,
92 #[serde(default)]
93 pub otherwise: Vec<Step>,
94}
95
96#[derive(Debug, Deserialize)]
97pub struct WhenSpec {
98 pub predicate: PredicateSpec,
99 #[serde(default)]
100 pub then: Vec<Step>,
101}
102
103#[derive(Debug, Deserialize)]
104pub struct RecipientListSpec {
105 pub from_header: String,
106 #[serde(default = "default_rl_separator")]
107 pub separator: String,
108}
109
110fn default_rl_separator() -> String {
111 ",".to_owned()
112}
113
114#[derive(Debug, Deserialize)]
115pub struct LoadBalanceSpec {
116 pub strategy: LoadBalanceStrategy,
117 pub to: Vec<String>,
118}
119
120#[derive(Debug, Deserialize)]
121#[serde(rename_all = "lowercase")]
122pub enum LoadBalanceStrategy {
123 #[serde(alias = "round_robin", alias = "roundrobin")]
124 RoundRobin,
125 Failover,
126}
127
128#[derive(Debug, Deserialize)]
129#[serde(untagged, deny_unknown_fields)]
130pub enum IdempotentSpec {
131 ByBody { by_body: bool },
132 ByHeader { by_header: String },
133}
134
135#[derive(Debug, Deserialize)]
136pub struct OnExceptionSpec {
137 pub max_redeliveries: u32,
138 #[serde(default)]
139 pub backoff_millis: u64,
140 #[serde(default = "default_backoff_multiplier")]
141 pub backoff_multiplier: f64,
142 #[serde(default)]
143 pub dead_letter: Option<String>,
144}
145
146fn default_backoff_multiplier() -> f64 {
147 2.0
148}