diff options
Diffstat (limited to 'vendor/similar/src/algorithms/capture.rs')
-rw-r--r-- | vendor/similar/src/algorithms/capture.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/vendor/similar/src/algorithms/capture.rs b/vendor/similar/src/algorithms/capture.rs new file mode 100644 index 0000000..4f4990d --- /dev/null +++ b/vendor/similar/src/algorithms/capture.rs @@ -0,0 +1,117 @@ +use std::convert::Infallible; + +use crate::algorithms::DiffHook; +use crate::{group_diff_ops, DiffOp}; + +/// A [`DiffHook`] that captures all diff operations. +#[derive(Default, Clone)] +pub struct Capture(Vec<DiffOp>); + +impl Capture { + /// Creates a new capture hook. + pub fn new() -> Capture { + Capture::default() + } + + /// Converts the capture hook into a vector of ops. + pub fn into_ops(self) -> Vec<DiffOp> { + self.0 + } + + /// Isolate change clusters by eliminating ranges with no changes. + /// + /// This is equivalent to calling [`group_diff_ops`] on [`Capture::into_ops`]. + pub fn into_grouped_ops(self, n: usize) -> Vec<Vec<DiffOp>> { + group_diff_ops(self.into_ops(), n) + } + + /// Accesses the captured operations. + pub fn ops(&self) -> &[DiffOp] { + &self.0 + } +} + +impl DiffHook for Capture { + type Error = Infallible; + + #[inline(always)] + fn equal(&mut self, old_index: usize, new_index: usize, len: usize) -> Result<(), Self::Error> { + self.0.push(DiffOp::Equal { + old_index, + new_index, + len, + }); + Ok(()) + } + + #[inline(always)] + fn delete( + &mut self, + old_index: usize, + old_len: usize, + new_index: usize, + ) -> Result<(), Self::Error> { + self.0.push(DiffOp::Delete { + old_index, + old_len, + new_index, + }); + Ok(()) + } + + #[inline(always)] + fn insert( + &mut self, + old_index: usize, + new_index: usize, + new_len: usize, + ) -> Result<(), Self::Error> { + self.0.push(DiffOp::Insert { + old_index, + new_index, + new_len, + }); + Ok(()) + } + + #[inline(always)] + fn replace( + &mut self, + old_index: usize, + old_len: usize, + new_index: usize, + new_len: usize, + ) -> Result<(), Self::Error> { + self.0.push(DiffOp::Replace { + old_index, + old_len, + new_index, + new_len, + }); + Ok(()) + } +} + +#[test] +fn test_capture_hook_grouping() { + use crate::algorithms::{diff_slices, Algorithm, Replace}; + + let rng = (1..100).collect::<Vec<_>>(); + let mut rng_new = rng.clone(); + rng_new[10] = 1000; + rng_new[13] = 1000; + rng_new[16] = 1000; + rng_new[34] = 1000; + + let mut d = Replace::new(Capture::new()); + diff_slices(Algorithm::Myers, &mut d, &rng, &rng_new).unwrap(); + + let ops = d.into_inner().into_grouped_ops(3); + let tags = ops + .iter() + .map(|group| group.iter().map(|x| x.as_tag_tuple()).collect::<Vec<_>>()) + .collect::<Vec<_>>(); + + insta::assert_debug_snapshot!(ops); + insta::assert_debug_snapshot!(tags); +} |