cumulo_dipa/set/
set_impl_macro.rs1#[macro_export]
2macro_rules! set_impl {
3 ($map_ty:ty, $module:ident, $($additional_key_bounds:tt)*) => {
4 mod $module {
5 use super::{SetDelta, SetDeltaOwned};
6 use crate::{CreatedDelta, Diffable, Patchable};
7 use std::hash::Hash;
8
9 type SetAssociatedDeltaOwned<'s, 'e, K> =
10 <$map_ty as Diffable<'s, 'e, $map_ty>>::DeltaOwned;
11
12 impl<'s, 'e, K> Diffable<'s, 'e, $map_ty> for $map_ty
13 where
14 K: 's + 'e + Eq + Hash $($additional_key_bounds)*,
15 {
16 type Delta = SetDelta<'s, 'e, K>;
17 type DeltaOwned = SetDeltaOwned<K>;
18
19 fn create_delta_towards(
20 &'s self,
21 end_state: &'e $map_ty,
22 ) -> CreatedDelta<Self::Delta> {
23 let mut did_change = false;
24
25 if end_state.len() == 0 && self.len() > 0 {
26 let delta = SetDelta::RemoveAll;
27 return CreatedDelta {
28 delta,
29 did_change: true,
30 };
31 }
32
33 let mut delta = SetDelta::NoChange;
34
35 let mut fields_to_add = Vec::new();
36 let mut fields_to_remove = Vec::new();
37
38 for key in self.iter() {
39 if !end_state.contains(key) {
40 did_change = true;
41 fields_to_remove.push(key);
42 }
43 }
44
45 for key in end_state.iter() {
46 if !self.contains(key) {
47 did_change = true;
48 fields_to_add.push(key);
49 }
50 }
51
52 let many_fields_to_add = fields_to_add.len() > 1;
53 let many_fields_to_remove = fields_to_remove.len() > 1;
54
55 let one_field_to_add = fields_to_add.len() == 1;
56 let one_field_to_remove = fields_to_remove.len() == 1;
57
58 let encode_using_many_variant =
59 many_fields_to_add || many_fields_to_remove ;
60
61 if encode_using_many_variant {
62 delta = SetDelta::ModifyMany {
63 added: fields_to_add,
64 removed: fields_to_remove,
65 }
66 } else if one_field_to_add {
67 delta = SetDelta::AddOneField(fields_to_add[0]);
68 } else if one_field_to_remove {
69 delta = SetDelta::RemoveOneField(fields_to_remove[0]);
70 }
71
72 CreatedDelta {
73 delta,
74 did_change,
75 }
76 }
77 }
78
79 impl<'s, 'e, K> Patchable<SetAssociatedDeltaOwned<'s, 'e, K>> for $map_ty
80 where
81 K: 's + 'e + Eq + Hash $($additional_key_bounds)*,
82 {
83 fn apply_patch(&mut self, patch: SetAssociatedDeltaOwned<'s, 'e, K>) {
84 match patch {
85 SetDeltaOwned::NoChange => {}
86 SetDeltaOwned::RemoveAll => self.clear(),
87 SetDeltaOwned::AddOneField(k) => {
88 self.insert(k);
89 }
90 SetDeltaOwned::RemoveOneField(k) => {
91 self.remove(&k);
92 }
93 SetDeltaOwned::ModifyMany {
94 added,
95 removed,
96 } => {
97 for add in added {
98 self.insert(add);
99 }
100
101 for remove in removed {
102 self.remove(&remove);
103 }
104 }
105 }
106 }
107 }
108 }
109 };
110}