1 | /// A trait for reacting to an edit script from the "old" version to |
2 | /// the "new" version. |
3 | pub trait DiffHook: Sized { |
4 | /// The error produced from the hook methods. |
5 | type Error; |
6 | |
7 | /// Called when lines with indices `old_index` (in the old version) and |
8 | /// `new_index` (in the new version) start an section equal in both |
9 | /// versions, of length `len`. |
10 | fn equal(&mut self, old_index: usize, new_index: usize, len: usize) -> Result<(), Self::Error> { |
11 | let _ = old_index; |
12 | let _ = new_index; |
13 | let _ = len; |
14 | Ok(()) |
15 | } |
16 | |
17 | /// Called when a section of length `old_len`, starting at `old_index`, |
18 | /// needs to be deleted from the old version. |
19 | fn delete( |
20 | &mut self, |
21 | old_index: usize, |
22 | old_len: usize, |
23 | new_index: usize, |
24 | ) -> Result<(), Self::Error> { |
25 | let _ = old_index; |
26 | let _ = old_len; |
27 | let _ = new_index; |
28 | Ok(()) |
29 | } |
30 | |
31 | /// Called when a section of the new version, of length `new_len` |
32 | /// and starting at `new_index`, needs to be inserted at position `old_index'. |
33 | fn insert( |
34 | &mut self, |
35 | old_index: usize, |
36 | new_index: usize, |
37 | new_len: usize, |
38 | ) -> Result<(), Self::Error> { |
39 | let _ = old_index; |
40 | let _ = new_index; |
41 | let _ = new_len; |
42 | Ok(()) |
43 | } |
44 | |
45 | /// Called when a section of the old version, starting at index |
46 | /// `old_index` and of length `old_len`, needs to be replaced with a |
47 | /// section of length `new_len`, starting at `new_index`, of the new |
48 | /// version. |
49 | /// |
50 | /// The default implementations invokes `delete` and `insert`. |
51 | /// |
52 | /// You can use the [`Replace`](crate::algorithms::Replace) hook to |
53 | /// automatically generate these. |
54 | #[inline (always)] |
55 | fn replace( |
56 | &mut self, |
57 | old_index: usize, |
58 | old_len: usize, |
59 | new_index: usize, |
60 | new_len: usize, |
61 | ) -> Result<(), Self::Error> { |
62 | self.delete(old_index, old_len, new_index)?; |
63 | self.insert(old_index, new_index, new_len) |
64 | } |
65 | |
66 | /// Always called at the end of the algorithm. |
67 | #[inline (always)] |
68 | fn finish(&mut self) -> Result<(), Self::Error> { |
69 | Ok(()) |
70 | } |
71 | } |
72 | |
73 | impl<'a, D: DiffHook + 'a> DiffHook for &'a mut D { |
74 | type Error = D::Error; |
75 | |
76 | #[inline (always)] |
77 | fn equal(&mut self, old_index: usize, new_index: usize, len: usize) -> Result<(), Self::Error> { |
78 | (*self).equal(old_index, new_index, len) |
79 | } |
80 | |
81 | #[inline (always)] |
82 | fn delete( |
83 | &mut self, |
84 | old_index: usize, |
85 | old_len: usize, |
86 | new_index: usize, |
87 | ) -> Result<(), Self::Error> { |
88 | (*self).delete(old_index, old_len, new_index) |
89 | } |
90 | |
91 | #[inline (always)] |
92 | fn insert( |
93 | &mut self, |
94 | old_index: usize, |
95 | new_index: usize, |
96 | new_len: usize, |
97 | ) -> Result<(), Self::Error> { |
98 | (*self).insert(old_index, new_index, new_len) |
99 | } |
100 | |
101 | #[inline (always)] |
102 | fn replace( |
103 | &mut self, |
104 | old: usize, |
105 | old_len: usize, |
106 | new: usize, |
107 | new_len: usize, |
108 | ) -> Result<(), Self::Error> { |
109 | (*self).replace(old, old_len, new, new_len) |
110 | } |
111 | |
112 | #[inline (always)] |
113 | fn finish(&mut self) -> Result<(), Self::Error> { |
114 | (*self).finish() |
115 | } |
116 | } |
117 | |
118 | /// Wrapper [`DiffHook`] that prevents calls to [`DiffHook::finish`]. |
119 | /// |
120 | /// This hook is useful in situations where diff hooks are composed but you |
121 | /// want to prevent that the finish hook method is called. |
122 | pub struct NoFinishHook<D: DiffHook>(D); |
123 | |
124 | impl<D: DiffHook> NoFinishHook<D> { |
125 | /// Wraps another hook. |
126 | pub fn new(d: D) -> NoFinishHook<D> { |
127 | NoFinishHook(d) |
128 | } |
129 | |
130 | /// Extracts the inner hook. |
131 | pub fn into_inner(self) -> D { |
132 | self.0 |
133 | } |
134 | } |
135 | |
136 | impl<D: DiffHook> DiffHook for NoFinishHook<D> { |
137 | type Error = D::Error; |
138 | |
139 | #[inline (always)] |
140 | fn equal(&mut self, old_index: usize, new_index: usize, len: usize) -> Result<(), Self::Error> { |
141 | self.0.equal(old_index, new_index, len) |
142 | } |
143 | |
144 | #[inline (always)] |
145 | fn delete( |
146 | &mut self, |
147 | old_index: usize, |
148 | old_len: usize, |
149 | new_index: usize, |
150 | ) -> Result<(), Self::Error> { |
151 | self.0.delete(old_index, old_len, new_index) |
152 | } |
153 | |
154 | #[inline (always)] |
155 | fn insert( |
156 | &mut self, |
157 | old_index: usize, |
158 | new_index: usize, |
159 | new_len: usize, |
160 | ) -> Result<(), Self::Error> { |
161 | self.0.insert(old_index, new_index, new_len) |
162 | } |
163 | |
164 | #[inline (always)] |
165 | fn replace( |
166 | &mut self, |
167 | old_index: usize, |
168 | old_len: usize, |
169 | new_index: usize, |
170 | new_len: usize, |
171 | ) -> Result<(), Self::Error> { |
172 | self.0.replace(old_index, old_len, new_index, new_len) |
173 | } |
174 | |
175 | fn finish(&mut self) -> Result<(), Self::Error> { |
176 | Ok(()) |
177 | } |
178 | } |
179 | |