similar/algorithms/
capture.rs
1use std::convert::Infallible;
2
3use crate::algorithms::DiffHook;
4use crate::{group_diff_ops, DiffOp};
5
6#[derive(Default, Clone)]
8pub struct Capture(Vec<DiffOp>);
9
10impl Capture {
11 pub fn new() -> Capture {
13 Capture::default()
14 }
15
16 pub fn into_ops(self) -> Vec<DiffOp> {
18 self.0
19 }
20
21 pub fn into_grouped_ops(self, n: usize) -> Vec<Vec<DiffOp>> {
25 group_diff_ops(self.into_ops(), n)
26 }
27
28 pub fn ops(&self) -> &[DiffOp] {
30 &self.0
31 }
32}
33
34impl DiffHook for Capture {
35 type Error = Infallible;
36
37 #[inline(always)]
38 fn equal(&mut self, old_index: usize, new_index: usize, len: usize) -> Result<(), Self::Error> {
39 self.0.push(DiffOp::Equal {
40 old_index,
41 new_index,
42 len,
43 });
44 Ok(())
45 }
46
47 #[inline(always)]
48 fn delete(
49 &mut self,
50 old_index: usize,
51 old_len: usize,
52 new_index: usize,
53 ) -> Result<(), Self::Error> {
54 self.0.push(DiffOp::Delete {
55 old_index,
56 old_len,
57 new_index,
58 });
59 Ok(())
60 }
61
62 #[inline(always)]
63 fn insert(
64 &mut self,
65 old_index: usize,
66 new_index: usize,
67 new_len: usize,
68 ) -> Result<(), Self::Error> {
69 self.0.push(DiffOp::Insert {
70 old_index,
71 new_index,
72 new_len,
73 });
74 Ok(())
75 }
76
77 #[inline(always)]
78 fn replace(
79 &mut self,
80 old_index: usize,
81 old_len: usize,
82 new_index: usize,
83 new_len: usize,
84 ) -> Result<(), Self::Error> {
85 self.0.push(DiffOp::Replace {
86 old_index,
87 old_len,
88 new_index,
89 new_len,
90 });
91 Ok(())
92 }
93}
94
95#[test]
96fn test_capture_hook_grouping() {
97 use crate::algorithms::{diff_slices, Algorithm, Replace};
98
99 let rng = (1..100).collect::<Vec<_>>();
100 let mut rng_new = rng.clone();
101 rng_new[10] = 1000;
102 rng_new[13] = 1000;
103 rng_new[16] = 1000;
104 rng_new[34] = 1000;
105
106 let mut d = Replace::new(Capture::new());
107 diff_slices(Algorithm::Myers, &mut d, &rng, &rng_new).unwrap();
108
109 let ops = d.into_inner().into_grouped_ops(3);
110 let tags = ops
111 .iter()
112 .map(|group| group.iter().map(|x| x.as_tag_tuple()).collect::<Vec<_>>())
113 .collect::<Vec<_>>();
114
115 insta::assert_debug_snapshot!(ops);
116 insta::assert_debug_snapshot!(tags);
117}