1use crate::note::Note;
2use std::collections::HashMap;
3
4pub trait MergeStrategy: Send + Sync {
5 fn merge(&self, local: &[Note], remote: &[Note]) -> Vec<Note>;
6 fn name(&self) -> &'static str;
7}
8
9pub struct UnionStrategy;
10
11impl MergeStrategy for UnionStrategy {
12 fn merge(&self, local: &[Note], remote: &[Note]) -> Vec<Note> {
13 let mut notes_map = HashMap::new();
14
15 for note in local {
16 notes_map.insert(note.id, note.clone());
17 }
18 for note in remote {
19 notes_map.insert(note.id, note.clone());
20 }
21
22 notes_map.into_values().collect()
23 }
24
25 fn name(&self) -> &'static str {
26 "union"
27 }
28}
29
30pub struct LwwStrategy;
31
32impl MergeStrategy for LwwStrategy {
33 fn merge(&self, local: &[Note], remote: &[Note]) -> Vec<Note> {
34 let mut notes_map: HashMap<_, Note> = HashMap::new();
35
36 for note in local.iter().chain(remote.iter()) {
37 notes_map
38 .entry(note.id)
39 .and_modify(|existing| {
40 if note.timestamp > existing.timestamp {
41 *existing = note.clone();
42 }
43 })
44 .or_insert_with(|| note.clone());
45 }
46
47 notes_map.into_values().collect()
48 }
49
50 fn name(&self) -> &'static str {
51 "lww"
52 }
53}
54
55pub struct CompositeStrategy;
56
57impl MergeStrategy for CompositeStrategy {
58 fn merge(&self, local: &[Note], remote: &[Note]) -> Vec<Note> {
59 let lww = LwwStrategy;
62 lww.merge(local, remote)
63 }
64
65 fn name(&self) -> &'static str {
66 "composite"
67 }
68}