summaryrefslogtreecommitdiffstats
path: root/vendor/similar/src/algorithms/capture.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/similar/src/algorithms/capture.rs')
-rw-r--r--vendor/similar/src/algorithms/capture.rs117
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);
+}