Skip to main content

cumulo_dipa/
cow.rs

1use crate::{CreatedDelta, Diffable, Patchable};
2use std::borrow::{Borrow, Cow};
3
4impl<'s, 'e, 'a, T> Diffable<'s, 'e, Cow<'a, T>> for Cow<'a, T>
5where
6    T: ToOwned,
7    T: ?Sized,
8    T: Diffable<'s, 'e, T>,
9{
10    type Delta = <T as Diffable<'s, 'e, T>>::Delta;
11    type DeltaOwned = <T as Diffable<'s, 'e, T>>::DeltaOwned;
12
13    fn create_delta_towards(&'s self, end_state: &'e Cow<'a, T>) -> CreatedDelta<Self::Delta> {
14        let inner_self: &T = self.borrow();
15
16        inner_self.create_delta_towards(end_state.borrow())
17    }
18}
19
20impl<'s, 'e, 'a, T> Patchable<<Self as Diffable<'s, 'e, Self>>::DeltaOwned> for Cow<'a, T>
21where
22    T: ToOwned,
23    T: ?Sized,
24    T: Diffable<'s, 'e, T>,
25    <T as ToOwned>::Owned: Patchable<<T as Diffable<'s, 'e, T>>::DeltaOwned>,
26{
27    fn apply_patch(&mut self, patch: <T as Diffable<'s, 'e, T>>::DeltaOwned) {
28        self.to_mut().apply_patch(patch)
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use crate::sequence::SequenceModificationDelta;
35    use crate::DipaImplTester;
36    use std::borrow::Cow;
37
38    /// Verify that we can diff and batch Cow's
39    #[test]
40    fn cow_impl() {
41        let hello_static = "hello";
42        let empty_static = "";
43
44        DipaImplTester {
45            label: Some("Cow no change Borrowed -> Owned"),
46            start: &mut Cow::Borrowed(hello_static),
47            end: &Cow::Owned(hello_static.to_string()),
48            expected_delta: vec![],
49            expected_serialized_patch_size: 1,
50            expected_did_change: false,
51        }
52        .test();
53
54        DipaImplTester {
55            label: Some("Cow no change Owned -> Borrowed"),
56            start: &mut Cow::Owned(hello_static.to_string()),
57            end: &Cow::Borrowed(hello_static),
58            expected_delta: vec![],
59            expected_serialized_patch_size: 1,
60            expected_did_change: false,
61        }
62        .test();
63
64        DipaImplTester {
65            label: Some("Cow no change Borrowed -> Borrowed"),
66            start: &mut Cow::Borrowed(hello_static),
67            end: &Cow::Borrowed(hello_static),
68            expected_delta: vec![],
69            expected_serialized_patch_size: 1,
70            expected_did_change: false,
71        }
72        .test();
73
74        DipaImplTester {
75            label: Some("Cow no change Owned -> Owned"),
76            start: &mut Cow::Owned::<'static, str>(hello_static.to_string()),
77            end: &Cow::Owned(hello_static.to_string()),
78            expected_delta: vec![],
79            expected_serialized_patch_size: 1,
80            expected_did_change: false,
81        }
82        .test();
83
84        DipaImplTester {
85            label: Some("Cow change Borrowed -> Owned"),
86            start: &mut Cow::Borrowed(hello_static),
87            end: &Cow::Owned(empty_static.to_string()),
88            expected_delta: vec![SequenceModificationDelta::DeleteAll],
89            expected_serialized_patch_size: 2,
90            expected_did_change: true,
91        }
92        .test();
93
94        DipaImplTester {
95            label: Some("Cow change Borrowed -> Borrowed"),
96            start: &mut Cow::Borrowed(hello_static),
97            end: &Cow::Borrowed(empty_static),
98            expected_delta: vec![SequenceModificationDelta::DeleteAll],
99            expected_serialized_patch_size: 2,
100            expected_did_change: true,
101        }
102        .test();
103
104        DipaImplTester {
105            label: Some("Cow change Owned -> Borrowed"),
106            start: &mut Cow::Owned(hello_static.to_string()),
107            end: &Cow::Borrowed(empty_static),
108            expected_delta: vec![SequenceModificationDelta::DeleteAll],
109            expected_serialized_patch_size: 2,
110            expected_did_change: true,
111        }
112        .test();
113
114        DipaImplTester {
115            label: Some("Cow change Owned -> Owned"),
116            start: &mut Cow::Owned::<'static, str>(hello_static.to_string()),
117            end: &Cow::Owned(empty_static.to_string()),
118            expected_delta: vec![SequenceModificationDelta::DeleteAll],
119            expected_serialized_patch_size: 2,
120            expected_did_change: true,
121        }
122        .test();
123    }
124}