Skip to main content

cumulo_dipa/
string.rs

1use crate::sequence::{SequenceModificationDelta, SequenceModificationDeltaOwned};
2use crate::{CreatedDelta, Diffable, Patchable};
3
4impl<'s, 'e> Diffable<'s, 'e, String> for String {
5    type Delta = Vec<SequenceModificationDelta<'e, u8>>;
6    type DeltaOwned = Vec<SequenceModificationDeltaOwned<u8>>;
7
8    fn create_delta_towards(&self, end_state: &'e String) -> CreatedDelta<Self::Delta> {
9        self.as_bytes().create_delta_towards(&end_state.as_bytes())
10    }
11}
12
13impl Patchable<Vec<SequenceModificationDeltaOwned<u8>>> for String {
14    fn apply_patch(&mut self, patch: Vec<SequenceModificationDeltaOwned<u8>>) {
15        // TODO: More efficient implementation without copying.. Just quickly getting things working.
16        let mut bytes = self.as_bytes().to_vec();
17
18        bytes.apply_patch(patch);
19
20        *self = String::from_utf8(bytes).unwrap()
21    }
22}
23
24impl<'s, 'e> Diffable<'s, 'e, str> for str {
25    type Delta = Vec<SequenceModificationDelta<'e, u8>>;
26    type DeltaOwned = Vec<SequenceModificationDeltaOwned<u8>>;
27
28    fn create_delta_towards(&'s self, end_state: &'e str) -> CreatedDelta<Self::Delta> {
29        self.as_bytes().create_delta_towards(&end_state.as_bytes())
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use crate::sequence::SequenceModificationDelta;
36    use crate::DipaImplTester;
37
38    /// Verify that we can diff and patch strings.
39    #[test]
40    fn string_dipa() {
41        DipaImplTester {
42            label: Some("String unchanged"),
43            start: &mut "XYZ".to_string(),
44            end: &"XYZ".to_string(),
45            expected_delta: vec![],
46            // 1 for vec length
47            expected_serialized_patch_size: 1,
48            expected_did_change: false,
49        }
50        .test();
51
52        DipaImplTester {
53            label: Some("String changed"),
54            start: &mut "ABCDE".to_string(),
55            end: &"ABDE".to_string(),
56            expected_delta: vec![SequenceModificationDelta::DeleteOne { index: 2 }],
57            // 1 for vec length, 1 for variant, 1 for index
58            expected_serialized_patch_size: 3,
59            expected_did_change: true,
60        }
61        .test();
62    }
63}