Restructure crate layout

This commit is contained in:
Armin Ronacher 2021-02-02 22:44:52 +01:00
parent 1f73e01ff1
commit 1991955c52
10 changed files with 323 additions and 283 deletions

View file

@ -1,159 +1,7 @@
use crate::algorithms::hook::DiffHook;
use std::convert::Infallible;
use std::ops::Range;
/// Utility enum to capture a diff operation.
///
/// This is used by [`Capture`](crate::algorithms::Capture).
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum DiffOp {
/// A segment is equal (see [`DiffHook::equal`])
Equal {
/// The starting index in the old sequence.
old_index: usize,
/// The starting index in the new sequence.
new_index: usize,
/// The length of the segment.
len: usize,
},
/// A segment was deleted (see [`DiffHook::delete`])
Delete {
/// The starting index in the old sequence.
old_index: usize,
/// The length of the old segment.
old_len: usize,
/// The starting index in the new sequence.
new_index: usize,
},
/// A segment was inserted (see [`DiffHook::insert`])
Insert {
/// The starting index in the old sequence.
old_index: usize,
/// The starting index in the new sequence.
new_index: usize,
/// The length of the new segment.
new_len: usize,
},
/// A segment was replaced (see [`DiffHook::replace`])
Replace {
/// The starting index in the old sequence.
old_index: usize,
/// The length of the old segment.
old_len: usize,
/// The starting index in the new sequence.
new_index: usize,
/// The length of the new segment.
new_len: usize,
},
}
/// The tag of a diff operation.
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Ord, PartialOrd)]
pub enum DiffTag {
/// The diff op encodes an equal segment.
Equal,
/// The diff op encodes a deleted segment.
Delete,
/// The diff op encodes an inserted segment.
Insert,
/// The diff op encodes a replaced segment.
Replace,
}
impl DiffOp {
/// Returns the tag of the operation.
pub fn tag(self) -> DiffTag {
self.as_tag_tuple().0
}
/// Returns the old range.
pub fn old_range(&self) -> Range<usize> {
self.as_tag_tuple().1
}
/// Returns the new range.
pub fn new_range(&self) -> Range<usize> {
self.as_tag_tuple().2
}
/// Transform the op into a tuple of diff tag and ranges.
///
/// This is useful when operating on slices. The returned format is
/// `(tag, i1..i2, j1..j2)`:
///
/// * `Replace`: `a[i1..i2]` should be replaced by `b[j1..j2]`
/// * `Delete`: `a[i1..i2]` should be deleted (`j1 == j2` in this case).
/// * `Insert`: `b[j1..j2]` should be inserted at `a[i1..i2]` (`i1 == i2` in this case).
/// * `Equal`: `a[i1..i2]` is equal to `b[j1..j2]`.
pub fn as_tag_tuple(&self) -> (DiffTag, Range<usize>, Range<usize>) {
match *self {
DiffOp::Equal {
old_index,
new_index,
len,
} => (
DiffTag::Equal,
old_index..old_index + len,
new_index..new_index + len,
),
DiffOp::Delete {
old_index,
new_index,
old_len,
} => (
DiffTag::Delete,
old_index..old_index + old_len,
new_index..new_index,
),
DiffOp::Insert {
old_index,
new_index,
new_len,
} => (
DiffTag::Insert,
old_index..old_index,
new_index..new_index + new_len,
),
DiffOp::Replace {
old_index,
old_len,
new_index,
new_len,
} => (
DiffTag::Replace,
old_index..old_index + old_len,
new_index..new_index + new_len,
),
}
}
/// Apply this operation to a diff hook.
pub fn apply_to_hook<D: DiffHook>(&self, d: &mut D) -> Result<(), D::Error> {
match *self {
DiffOp::Equal {
old_index,
new_index,
len,
} => d.equal(old_index, new_index, len),
DiffOp::Delete {
old_index,
old_len,
new_index,
} => d.delete(old_index, old_len, new_index),
DiffOp::Insert {
old_index,
new_index,
new_len,
} => d.insert(old_index, new_index, new_len),
DiffOp::Replace {
old_index,
old_len,
new_index,
new_len,
} => d.replace(old_index, old_len, new_index, new_len),
}
}
}
use crate::algorithms::hook::DiffHook;
use crate::DiffOp;
/// Isolate change clusters by eliminating ranges with no changes.
///

View file

@ -14,6 +14,20 @@
//!
//! Most of the crate operates on the [`Algorithm`] enum which abstracts over
//! the different algorithms.
//!
//! # Example
//!
//! This is a simple example that shows how you can calculate the difference
//! between two sequences and capture the [`DiffOp`]s into a vector.
//!
//! ```rust
//! use similar::Algorithm;
//! use similar::algorithms::capture_diff_slices;
//!
//! let a = vec![1, 2, 3, 4, 5];
//! let b = vec![1, 2, 3, 4, 7];
//! let ops = capture_diff_slices(Algorithm::Myers, &a, &b);
//! ```
// general traits and utilities
mod capture;
@ -23,7 +37,9 @@ mod replace;
use std::hash::Hash;
use std::ops::{Index, Range};
pub use capture::{get_diff_ratio, group_diff_ops, Capture, DiffOp, DiffTag};
use crate::types::{Algorithm, DiffOp};
pub use capture::{get_diff_ratio, group_diff_ops, Capture};
pub use hook::DiffHook;
pub use replace::Replace;
@ -31,22 +47,6 @@ pub use replace::Replace;
pub mod myers;
pub mod patience;
/// An enum representing a diffing algorithm.
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum Algorithm {
/// Picks the myers algorithm from [`myers`]
Myers,
/// Picks the patience algorithm from [`patience`]
Patience,
}
impl Default for Algorithm {
/// Returns the default algorithm ([`Algorithm::Myers`]).
fn default() -> Algorithm {
Algorithm::Myers
}
}
/// Creates a diff between old and new with the given algorithm.
///
/// Diffs `old`, between indices `old_range` and `new` between indices `new_range`.