1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
//! Various diff (longest common subsequence) algorithms, used in
//! practice:
//!
//! - Myers' diff, in time O((N+M)D) and space O(N+M), where N and M
//! are the sizes of the old and new version, respectively. See [the
//! original article by Eugene
//! W. Myers](http://www.xmailserver.org/diff2.pdf).
//!
//! - Patience diff, in time O(N log N + M log M + (N+M)D), and space
//! O(N+M), which tends to give more human-readable outputs. See [Bram
//! Cohen's blog post describing
//! it](https://bramcohen.livejournal.com/73318.html).
mod replace;
pub use replace::*;
/// Myers' diff algorithm
pub mod myers;
/// Patience diff algorithm
pub mod patience;
pub use myers::diff;
#[cfg(test)]
mod test;
#[allow(unused_variables)]
/// A trait for reacting to an edit script from the "old" version to
/// the "new" version.
pub trait Diff: Sized {
type Error;
/// Called when lines with indices `old` (in the old version) and
/// `new` (in the new version) start an section equal in both
/// versions, of length `len`.
fn equal(&mut self, old: usize, new: usize, len: usize) -> Result<(), Self::Error> { Ok(()) }
/// Called when a section of length `len`, starting at `old`,
/// needs to be deleted from the old version.
fn delete(&mut self, old: usize, len: usize) -> Result<(), Self::Error> { Ok(()) }
/// Called when a section of the new version, of length `new_len`
/// and starting at `new`, needs to be inserted at position `old'.
fn insert(&mut self, old: usize, new: usize, new_len: usize) -> Result<(), Self::Error> { Ok(()) }
/// Called when a section of the old version, starting at index
/// `old` and of length `old_len`, needs to be replaced with a
/// section of length `new_len`, starting at `new`, of the new
/// version.
fn replace(&mut self, old: usize, old_len: usize, new: usize, new_len: usize) -> Result<(), Self::Error> {
self.delete(old, old_len)?;
self.insert(old, new, new_len)
}
/// Always called at the end of the algorithm.
fn finish(&mut self) -> Result<(), Self::Error> { Ok(()) }
}
impl<'a, D: Diff + 'a> Diff for &'a mut D {
type Error = D::Error;
fn equal(&mut self, old: usize, new: usize, len: usize) -> Result<(), Self::Error> {
(*self).equal(old, new, len)
}
fn delete(&mut self, old: usize, len: usize) -> Result<(), Self::Error> {
(*self).delete(old, len)
}
fn insert(&mut self, old: usize, new: usize, new_len: usize) -> Result<(), Self::Error> {
(*self).insert(old, new, new_len)
}
fn replace(&mut self, old: usize, old_len: usize, new: usize, new_len: usize) -> Result<(), Self::Error> {
(*self).replace(old, old_len, new, new_len)
}
fn finish(&mut self) -> Result<(), Self::Error> {
(*self).finish()
}
}