1use std::collections::{BTreeMap, BTreeSet};
10
11use super::hunk::{FolderName, FolderSyncHunk, FoldersName};
12use crate::sync::SyncDestination;
13
14pub type FolderSyncPatch = BTreeSet<FolderSyncHunk>;
17
18pub type FolderSyncPatches = BTreeMap<FolderName, FolderSyncPatch>;
21
22pub fn build(
28 local_cache: FoldersName,
29 local: FoldersName,
30 remote_cache: FoldersName,
31 remote: FoldersName,
32) -> FolderSyncPatches {
33 let mut folders = BTreeSet::new();
34
35 folders.extend(local_cache.clone());
37 folders.extend(local.clone());
38 folders.extend(remote_cache.clone());
39 folders.extend(remote.clone());
40
41 let patches = folders.into_iter().map(|folder| {
44 let local_cache = local_cache.get(&folder);
45 let local = local.get(&folder);
46 let remote_cache = remote_cache.get(&folder);
47 let remote = remote.get(&folder);
48
49 let patch = match (local_cache, local, remote_cache, remote) {
50 (None, None, None, None) => BTreeSet::from_iter([]),
52
53 (None, None, None, Some(_)) => BTreeSet::from_iter([
55 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left),
56 FolderSyncHunk::Create(folder.clone(), SyncDestination::Left),
57 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Right),
58 ]),
59
60 (None, None, Some(_), None) => BTreeSet::from_iter([FolderSyncHunk::Uncache(
62 folder.clone(),
63 SyncDestination::Right,
64 )]),
65
66 (None, None, Some(_), Some(_)) => BTreeSet::from_iter([
68 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left),
69 FolderSyncHunk::Create(folder.clone(), SyncDestination::Left),
70 ]),
71
72 (None, Some(_), None, None) => BTreeSet::from_iter([
74 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left),
75 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Right),
76 FolderSyncHunk::Create(folder.clone(), SyncDestination::Right),
77 ]),
78
79 (None, Some(_), None, Some(_)) => BTreeSet::from_iter([
81 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left),
82 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Right),
83 ]),
84
85 (None, Some(_), Some(_), None) => BTreeSet::from_iter([
87 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left),
88 FolderSyncHunk::Create(folder.clone(), SyncDestination::Right),
89 ]),
90
91 (None, Some(_), Some(_), Some(_)) => {
93 BTreeSet::from_iter([FolderSyncHunk::Cache(folder.clone(), SyncDestination::Left)])
94 }
95
96 (Some(_), None, None, None) => BTreeSet::from_iter([FolderSyncHunk::Uncache(
98 folder.clone(),
99 SyncDestination::Left,
100 )]),
101
102 (Some(_), None, None, Some(_)) => BTreeSet::from_iter([
104 FolderSyncHunk::Create(folder.clone(), SyncDestination::Left),
105 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Right),
106 ]),
107
108 (Some(_), None, Some(_), None) => BTreeSet::from_iter([
110 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Left),
111 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Right),
112 ]),
113
114 (Some(_), None, Some(_), Some(_)) => BTreeSet::from_iter([
116 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Left),
117 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Right),
118 FolderSyncHunk::Delete(folder.clone(), SyncDestination::Right),
119 ]),
120
121 (Some(_), Some(_), None, None) => BTreeSet::from_iter([
123 FolderSyncHunk::Cache(folder.clone(), SyncDestination::Right),
124 FolderSyncHunk::Create(folder.clone(), SyncDestination::Right),
125 ]),
126
127 (Some(_), Some(_), None, Some(_)) => BTreeSet::from_iter([FolderSyncHunk::Cache(
129 folder.clone(),
130 SyncDestination::Right,
131 )]),
132
133 (Some(_), Some(_), Some(_), None) => BTreeSet::from_iter([
135 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Left),
136 FolderSyncHunk::Delete(folder.clone(), SyncDestination::Left),
137 FolderSyncHunk::Uncache(folder.clone(), SyncDestination::Right),
138 ]),
139
140 (Some(_), Some(_), Some(_), Some(_)) => BTreeSet::from_iter([]),
142 };
143
144 (folder, patch)
145 });
146
147 BTreeMap::from_iter(patches)
148}
149
150#[cfg(test)]
151mod tests {
152 use std::collections::{BTreeMap, BTreeSet};
153
154 use super::{FolderSyncHunk, FoldersName};
155 use crate::sync::SyncDestination;
156
157 #[test]
158 fn build_folder_patch() {
159 assert_eq!(
161 super::build(
162 FoldersName::default(),
163 FoldersName::default(),
164 FoldersName::default(),
165 FoldersName::default(),
166 ),
167 BTreeMap::new()
168 );
169
170 assert_eq!(
172 super::build(
173 FoldersName::default(),
174 FoldersName::default(),
175 FoldersName::default(),
176 FoldersName::from_iter(["folder".into()]),
177 ),
178 BTreeMap::from_iter([(
179 "folder".into(),
180 BTreeSet::from_iter([
181 FolderSyncHunk::Cache("folder".into(), SyncDestination::Left),
182 FolderSyncHunk::Create("folder".into(), SyncDestination::Left),
183 FolderSyncHunk::Cache("folder".into(), SyncDestination::Right),
184 ])
185 )]),
186 );
187
188 assert_eq!(
190 super::build(
191 FoldersName::default(),
192 FoldersName::default(),
193 FoldersName::from_iter(["folder".into()]),
194 FoldersName::default(),
195 ),
196 BTreeMap::from_iter([(
197 "folder".into(),
198 BTreeSet::from_iter([FolderSyncHunk::Uncache(
199 "folder".into(),
200 SyncDestination::Right
201 )]),
202 )]),
203 );
204
205 assert_eq!(
207 super::build(
208 FoldersName::default(),
209 FoldersName::default(),
210 FoldersName::from_iter(["folder".into()]),
211 FoldersName::from_iter(["folder".into()]),
212 ),
213 BTreeMap::from_iter([(
214 "folder".into(),
215 BTreeSet::from_iter([
216 FolderSyncHunk::Cache("folder".into(), SyncDestination::Left),
217 FolderSyncHunk::Create("folder".into(), SyncDestination::Left),
218 ]),
219 )]),
220 );
221
222 assert_eq!(
224 super::build(
225 FoldersName::default(),
226 FoldersName::from_iter(["folder".into()]),
227 FoldersName::default(),
228 FoldersName::default(),
229 ),
230 BTreeMap::from_iter([(
231 "folder".into(),
232 BTreeSet::from_iter([
233 FolderSyncHunk::Cache("folder".into(), SyncDestination::Left),
234 FolderSyncHunk::Cache("folder".into(), SyncDestination::Right),
235 FolderSyncHunk::Create("folder".into(), SyncDestination::Right),
236 ]),
237 )]),
238 );
239
240 assert_eq!(
242 super::build(
243 FoldersName::default(),
244 FoldersName::from_iter(["folder".into()]),
245 FoldersName::default(),
246 FoldersName::from_iter(["folder".into()]),
247 ),
248 BTreeMap::from_iter([(
249 "folder".into(),
250 BTreeSet::from_iter([
251 FolderSyncHunk::Cache("folder".into(), SyncDestination::Left),
252 FolderSyncHunk::Cache("folder".into(), SyncDestination::Right),
253 ]),
254 )]),
255 );
256
257 assert_eq!(
259 super::build(
260 FoldersName::default(),
261 FoldersName::from_iter(["folder".into()]),
262 FoldersName::from_iter(["folder".into()]),
263 FoldersName::default(),
264 ),
265 BTreeMap::from_iter([(
266 "folder".into(),
267 BTreeSet::from_iter([
268 FolderSyncHunk::Cache("folder".into(), SyncDestination::Left),
269 FolderSyncHunk::Create("folder".into(), SyncDestination::Right),
270 ]),
271 )]),
272 );
273
274 assert_eq!(
276 super::build(
277 FoldersName::default(),
278 FoldersName::from_iter(["folder".into()]),
279 FoldersName::from_iter(["folder".into()]),
280 FoldersName::from_iter(["folder".into()]),
281 ),
282 BTreeMap::from_iter([(
283 "folder".into(),
284 BTreeSet::from_iter([FolderSyncHunk::Cache(
285 "folder".into(),
286 SyncDestination::Left
287 )]),
288 )]),
289 );
290
291 assert_eq!(
293 super::build(
294 FoldersName::from_iter(["folder".into()]),
295 FoldersName::default(),
296 FoldersName::default(),
297 FoldersName::default(),
298 ),
299 BTreeMap::from_iter([(
300 "folder".into(),
301 BTreeSet::from_iter([FolderSyncHunk::Uncache(
302 "folder".into(),
303 SyncDestination::Left
304 )]),
305 )]),
306 );
307
308 assert_eq!(
310 super::build(
311 FoldersName::from_iter(["folder".into()]),
312 FoldersName::default(),
313 FoldersName::default(),
314 FoldersName::from_iter(["folder".into()]),
315 ),
316 BTreeMap::from_iter([(
317 "folder".into(),
318 BTreeSet::from_iter([
319 FolderSyncHunk::Create("folder".into(), SyncDestination::Left),
320 FolderSyncHunk::Cache("folder".into(), SyncDestination::Right),
321 ]),
322 )]),
323 );
324
325 assert_eq!(
327 super::build(
328 FoldersName::from_iter(["folder".into()]),
329 FoldersName::default(),
330 FoldersName::from_iter(["folder".into()]),
331 FoldersName::default(),
332 ),
333 BTreeMap::from_iter([(
334 "folder".into(),
335 BTreeSet::from_iter([
336 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Left),
337 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Right),
338 ]),
339 )]),
340 );
341
342 assert_eq!(
344 super::build(
345 FoldersName::from_iter(["folder".into()]),
346 FoldersName::default(),
347 FoldersName::from_iter(["folder".into()]),
348 FoldersName::from_iter(["folder".into()]),
349 ),
350 BTreeMap::from_iter([(
351 "folder".into(),
352 BTreeSet::from_iter([
353 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Left),
354 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Right),
355 FolderSyncHunk::Delete("folder".into(), SyncDestination::Right),
356 ]),
357 )]),
358 );
359
360 assert_eq!(
362 super::build(
363 FoldersName::from_iter(["folder".into()]),
364 FoldersName::from_iter(["folder".into()]),
365 FoldersName::default(),
366 FoldersName::default(),
367 ),
368 BTreeMap::from_iter([(
369 "folder".into(),
370 BTreeSet::from_iter([
371 FolderSyncHunk::Cache("folder".into(), SyncDestination::Right),
372 FolderSyncHunk::Create("folder".into(), SyncDestination::Right),
373 ]),
374 )]),
375 );
376
377 assert_eq!(
379 super::build(
380 FoldersName::from_iter(["folder".into()]),
381 FoldersName::from_iter(["folder".into()]),
382 FoldersName::default(),
383 FoldersName::from_iter(["folder".into()]),
384 ),
385 BTreeMap::from_iter([(
386 "folder".into(),
387 BTreeSet::from_iter([FolderSyncHunk::Cache(
388 "folder".into(),
389 SyncDestination::Right
390 )]),
391 )]),
392 );
393
394 assert_eq!(
396 super::build(
397 FoldersName::from_iter(["folder".into()]),
398 FoldersName::from_iter(["folder".into()]),
399 FoldersName::from_iter(["folder".into()]),
400 FoldersName::default(),
401 ),
402 BTreeMap::from_iter([(
403 "folder".into(),
404 BTreeSet::from_iter([
405 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Left),
406 FolderSyncHunk::Delete("folder".into(), SyncDestination::Left),
407 FolderSyncHunk::Uncache("folder".into(), SyncDestination::Right),
408 ]),
409 )]),
410 );
411
412 assert_eq!(
414 super::build(
415 FoldersName::from_iter(["folder".into()]),
416 FoldersName::from_iter(["folder".into()]),
417 FoldersName::from_iter(["folder".into()]),
418 FoldersName::from_iter(["folder".into()]),
419 ),
420 BTreeMap::from_iter([("folder".into(), BTreeSet::from_iter([]))])
421 );
422 }
423}