eidetica/instance/
settings_merge.rs1use crate::user::types::SyncSettings;
7
8pub fn merge_sync_settings(settings: Vec<SyncSettings>) -> SyncSettings {
49 if settings.is_empty() {
50 return SyncSettings::disabled();
51 }
52
53 let mut combined = settings[0].clone();
55
56 for setting in settings.iter().skip(1) {
58 combined.sync_enabled = combined.sync_enabled || setting.sync_enabled;
60 combined.sync_on_commit = combined.sync_on_commit || setting.sync_on_commit;
61
62 combined.interval_seconds = match (combined.interval_seconds, setting.interval_seconds) {
64 (Some(a), Some(b)) => Some(a.min(b)),
65 (Some(a), None) => Some(a),
66 (None, Some(b)) => Some(b),
67 (None, None) => None,
68 };
69
70 for (key, value) in &setting.properties {
72 combined.properties.insert(key.clone(), value.clone());
73 }
74 }
75
76 combined
77}
78
79#[cfg(test)]
80mod tests {
81 use std::collections::HashMap;
82
83 use super::*;
84
85 #[test]
86 fn test_merge_empty_settings() {
87 let result = merge_sync_settings(vec![]);
88 assert!(!result.sync_enabled);
89 assert!(!result.sync_on_commit);
90 assert_eq!(result.interval_seconds, None);
91 assert!(result.properties.is_empty());
92 }
93
94 #[test]
95 fn test_merge_single_setting() {
96 let settings = SyncSettings {
97 sync_enabled: true,
98 sync_on_commit: true,
99 interval_seconds: Some(60),
100 properties: {
101 let mut map = HashMap::new();
102 map.insert("key1".to_string(), "value1".to_string());
103 map
104 },
105 };
106
107 let result = merge_sync_settings(vec![settings.clone()]);
108 assert_eq!(result.sync_enabled, settings.sync_enabled);
109 assert_eq!(result.sync_on_commit, settings.sync_on_commit);
110 assert_eq!(result.interval_seconds, settings.interval_seconds);
111 assert_eq!(result.properties.len(), 1);
112 }
113
114 #[test]
115 fn test_merge_sync_enabled_or() {
116 let settings1 = SyncSettings {
117 sync_enabled: true,
118 ..Default::default()
119 };
120
121 let settings2 = SyncSettings {
122 sync_enabled: false,
123 ..Default::default()
124 };
125
126 let result = merge_sync_settings(vec![settings1, settings2.clone()]);
127 assert!(result.sync_enabled); let result2 = merge_sync_settings(vec![settings2.clone(), settings2]);
130 assert!(!result2.sync_enabled); }
132
133 #[test]
134 fn test_merge_sync_on_commit_or() {
135 let settings1 = SyncSettings {
136 sync_on_commit: true,
137 ..Default::default()
138 };
139
140 let settings2 = SyncSettings {
141 sync_on_commit: false,
142 ..Default::default()
143 };
144
145 let result = merge_sync_settings(vec![settings1, settings2]);
146 assert!(result.sync_on_commit); }
148
149 #[test]
150 fn test_merge_interval_min() {
151 let settings1 = SyncSettings {
152 interval_seconds: Some(300),
153 ..Default::default()
154 };
155
156 let settings2 = SyncSettings {
157 interval_seconds: Some(60),
158 ..Default::default()
159 };
160
161 let settings3 = SyncSettings {
162 interval_seconds: Some(120),
163 ..Default::default()
164 };
165
166 let result = merge_sync_settings(vec![settings1, settings2, settings3]);
167 assert_eq!(result.interval_seconds, Some(60)); }
169
170 #[test]
171 fn test_merge_interval_with_none() {
172 let settings1 = SyncSettings {
173 interval_seconds: Some(300),
174 ..Default::default()
175 };
176
177 let settings2 = SyncSettings {
178 interval_seconds: None,
179 ..Default::default()
180 };
181
182 let result = merge_sync_settings(vec![settings1.clone(), settings2.clone()]);
183 assert_eq!(result.interval_seconds, Some(300)); let result2 = merge_sync_settings(vec![settings2.clone(), settings1]);
186 assert_eq!(result2.interval_seconds, Some(300));
187
188 let result3 = merge_sync_settings(vec![settings2.clone(), settings2]);
189 assert_eq!(result3.interval_seconds, None); }
191
192 #[test]
193 fn test_merge_properties_union() {
194 let settings1 = SyncSettings {
195 properties: {
196 let mut map = HashMap::new();
197 map.insert("key1".to_string(), "value1".to_string());
198 map.insert("key2".to_string(), "value2".to_string());
199 map
200 },
201 ..Default::default()
202 };
203
204 let settings2 = SyncSettings {
205 properties: {
206 let mut map = HashMap::new();
207 map.insert("key2".to_string(), "value2_override".to_string());
208 map.insert("key3".to_string(), "value3".to_string());
209 map
210 },
211 ..Default::default()
212 };
213
214 let result = merge_sync_settings(vec![settings1, settings2]);
215
216 assert_eq!(result.properties.len(), 3);
217 assert_eq!(result.properties.get("key1"), Some(&"value1".to_string()));
218 assert_eq!(
219 result.properties.get("key2"),
220 Some(&"value2_override".to_string())
221 ); assert_eq!(result.properties.get("key3"), Some(&"value3".to_string()));
223 }
224
225 #[test]
226 fn test_merge_all_features() {
227 let settings1 = SyncSettings {
228 sync_enabled: true,
229 sync_on_commit: false,
230 interval_seconds: Some(300),
231 properties: {
232 let mut map = HashMap::new();
233 map.insert("priority".to_string(), "low".to_string());
234 map
235 },
236 };
237
238 let settings2 = SyncSettings {
239 sync_enabled: false,
240 sync_on_commit: true,
241 interval_seconds: Some(60),
242 properties: {
243 let mut map = HashMap::new();
244 map.insert("priority".to_string(), "high".to_string());
245 map.insert("transport".to_string(), "http".to_string());
246 map
247 },
248 };
249
250 let settings3 = SyncSettings {
251 sync_enabled: false,
252 sync_on_commit: false,
253 interval_seconds: Some(120),
254 properties: {
255 let mut map = HashMap::new();
256 map.insert("region".to_string(), "us-west".to_string());
257 map
258 },
259 };
260
261 let result = merge_sync_settings(vec![settings1, settings2, settings3]);
262
263 assert!(result.sync_enabled); assert!(result.sync_on_commit); assert_eq!(result.interval_seconds, Some(60)); assert_eq!(result.properties.len(), 3);
270 assert_eq!(result.properties.get("priority"), Some(&"high".to_string())); assert_eq!(
272 result.properties.get("transport"),
273 Some(&"http".to_string())
274 );
275 assert_eq!(
276 result.properties.get("region"),
277 Some(&"us-west".to_string())
278 );
279 }
280}