dex_sdk/
start_flow_options.rs1use std::time::Duration;
10
11use std::sync::Arc;
12
13use dex_protocol::dex::{AttributeSyncConfig, IndexConfig};
14
15use crate::registry::physical_name;
16use crate::step::{ErasedValue, TypedValue};
17use crate::{Attribute, AttributeMap, FlowConfig, RetryPolicy, Value};
18
19#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub enum IdReusePolicy {
22 Default,
24 AllowIfPreviousFailed,
26 AllowIfNotRunning,
28 Disallow,
30 TerminateIfRunning,
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35pub enum FlowTimeoutPolicy {
37 Default,
39 Fail,
41 Cancel,
43 Handler,
45}
46
47#[derive(Clone)]
48pub struct StartFlowOptions {
67 pub(crate) timeout: Option<Duration>,
68 pub(crate) timeout_policy: FlowTimeoutPolicy,
69 pub(crate) start_delay: Option<Duration>,
70 pub(crate) id_reuse_policy: IdReusePolicy,
71 pub(crate) retry_policy: Option<RetryPolicy>,
72 pub(crate) config_override: Option<FlowConfig>,
73 pub(crate) ignore_already_started: bool,
74 pub(crate) request_id: Option<String>,
75 pub(crate) attributes: Vec<InitialAttribute>,
76}
77
78#[derive(Clone)]
79pub(crate) struct InitialAttribute {
80 pub(crate) key: String,
81 pub(crate) value: Arc<dyn ErasedValue>,
82 pub(crate) index_config: Option<IndexConfig>,
83 pub(crate) sync_config: Option<AttributeSyncConfig>,
84}
85
86impl InitialAttribute {
87 pub(crate) fn for_attribute<T: Value>(attribute: &Attribute<T>, value: T) -> Self {
88 Self {
89 key: attribute.name().to_string(),
90 value: Arc::new(TypedValue(value)),
91 index_config: attribute.index().map(|index| index.proto_config(false)),
92 sync_config: attribute.sync_config(),
93 }
94 }
95
96 pub(crate) fn for_attribute_map<T: Value>(
97 attribute: &AttributeMap<T>,
98 instance: &str,
99 value: T,
100 ) -> Self {
101 Self {
102 key: physical_name(attribute.name(), instance),
103 value: Arc::new(TypedValue(value)),
104 index_config: attribute.index().map(|index| index.proto_config(true)),
105 sync_config: attribute.sync_config(),
106 }
107 }
108}
109
110impl StartFlowOptions {
111 pub fn new() -> Self {
113 Self {
114 timeout: None,
115 timeout_policy: FlowTimeoutPolicy::Default,
116 start_delay: None,
117 id_reuse_policy: IdReusePolicy::Default,
118 retry_policy: None,
119 config_override: None,
120 ignore_already_started: false,
121 request_id: None,
122 attributes: Vec::new(),
123 }
124 }
125
126 pub fn timeout(mut self, value: Duration) -> Self {
128 self.timeout = Some(value);
129 self
130 }
131
132 pub fn timeout_policy(mut self, value: FlowTimeoutPolicy) -> Self {
136 self.timeout_policy = value;
137 self
138 }
139
140 pub fn start_delay(mut self, value: Duration) -> Self {
142 self.start_delay = Some(value);
143 self
144 }
145
146 pub fn id_reuse_policy(mut self, value: IdReusePolicy) -> Self {
148 self.id_reuse_policy = value;
149 self
150 }
151
152 pub fn retry_policy(mut self, value: RetryPolicy) -> Self {
154 self.retry_policy = Some(value);
155 self
156 }
157
158 pub fn initial_attribute<T: Value>(mut self, attribute: &Attribute<T>, value: T) -> Self {
160 self.attributes
161 .push(InitialAttribute::for_attribute(attribute, value));
162 self
163 }
164
165 pub fn initial_attribute_map<T: Value>(
167 mut self,
168 attribute: &AttributeMap<T>,
169 instance: &str,
170 value: T,
171 ) -> Self {
172 self.attributes.push(InitialAttribute::for_attribute_map(
173 attribute, instance, value,
174 ));
175 self
176 }
177
178 pub fn config_override(mut self, value: FlowConfig) -> Self {
180 self.config_override = Some(value);
181 self
182 }
183
184 pub fn ignore_already_started(mut self, value: bool) -> Self {
186 self.ignore_already_started = value;
187 self
188 }
189
190 pub fn request_id(mut self, value: impl Into<String>) -> Self {
192 self.request_id = Some(value.into());
193 self
194 }
195}
196
197impl Default for StartFlowOptions {
198 fn default() -> Self {
199 Self::new()
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::StartFlowOptions;
206 use crate::{Attribute, AttributeMap};
207
208 #[test]
209 fn initial_attributes_retain_sync_configuration() {
210 let plain = Attribute::<String>::new("plain");
211 let synced = Attribute::<String>::new("synced").sync_to_attribute_store();
212 let synced_map = AttributeMap::<String>::new("map").sync_to_attribute_store();
213 let options = StartFlowOptions::new()
214 .initial_attribute(&plain, "plain".to_string())
215 .initial_attribute(&synced, "synced".to_string())
216 .initial_attribute_map(&synced_map, "tenant-1", "mapped".to_string());
217
218 assert!(options.attributes[0].sync_config.is_none());
219 assert_eq!(
220 options.attributes[1]
221 .sync_config
222 .as_ref()
223 .map(|config| config.enabled),
224 Some(true)
225 );
226 assert_eq!(
227 options.attributes[2]
228 .sync_config
229 .as_ref()
230 .map(|config| config.enabled),
231 Some(true)
232 );
233 }
234}