Skip to content

Commit

Permalink
Allow custom original and modified file names in DiffOptions.
Browse files Browse the repository at this point in the history
Fixes: bmwill#2
  • Loading branch information
rjuju committed Jul 11, 2021
1 parent dec51c4 commit aa3d7e3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/diff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ where

/// A collection of options for modifying the way a diff is performed
#[derive(Debug)]
pub struct DiffOptions {
pub struct DiffOptions<'a> {
compact: bool,
context_len: usize,
original: &'a str,
modified: &'a str,
}

impl DiffOptions {
impl<'a> DiffOptions<'a> {
/// Construct a new `DiffOptions` with default settings
///
/// ## Defaults
Expand All @@ -57,6 +59,8 @@ impl DiffOptions {
Self {
compact: true,
context_len: 3,
original: "original",
modified: "modified",
}
}

Expand All @@ -76,9 +80,21 @@ impl DiffOptions {
self
}

/// Set the name of the old file should be used when producing a patch
pub fn set_original(&mut self, original: &'a str) -> &mut Self {
self.original = original;
self
}

/// Set the name of the new file that should be used when producing a patch
pub fn set_modified(&mut self, modified: &'a str) -> &mut Self {
self.modified = modified;
self
}

// TODO determine if this should be exposed in the public API
#[allow(dead_code)]
fn diff<'a>(&self, original: &'a str, modified: &'a str) -> Vec<Diff<'a, str>> {
fn diff(&self, original: &'a str, modified: &'a str) -> Vec<Diff<'a, str>> {
let solution = myers::diff(original.as_bytes(), modified.as_bytes());

let mut solution = solution
Expand All @@ -94,19 +110,19 @@ impl DiffOptions {
}

/// Produce a Patch between two texts based on the configured options
pub fn create_patch<'a>(&self, original: &'a str, modified: &'a str) -> Patch<'a, str> {
pub fn create_patch(&self, original: &'a str, modified: &'a str) -> Patch<'a, str> {
let mut classifier = Classifier::default();
let (old_lines, old_ids) = classifier.classify_lines(original);
let (new_lines, new_ids) = classifier.classify_lines(modified);

let solution = self.diff_slice(&old_ids, &new_ids);

let hunks = to_hunks(&old_lines, &new_lines, &solution, self.context_len);
Patch::new(Some("original"), Some("modified"), hunks)
Patch::new(Some(self.original), Some(self.modified), hunks)
}

/// Create a patch between two potentially non-utf8 texts
pub fn create_patch_bytes<'a>(
pub fn create_patch_bytes(
&self,
original: &'a [u8],
modified: &'a [u8],
Expand All @@ -118,10 +134,10 @@ impl DiffOptions {
let solution = self.diff_slice(&old_ids, &new_ids);

let hunks = to_hunks(&old_lines, &new_lines, &solution, self.context_len);
Patch::new(Some(&b"original"[..]), Some(&b"modified"[..]), hunks)
Patch::new(Some(self.original.as_bytes()), Some(self.modified.as_bytes()), hunks)
}

pub(crate) fn diff_slice<'a, T: PartialEq>(
pub(crate) fn diff_slice<T: PartialEq>(
&self,
old: &'a [T],
new: &'a [T],
Expand All @@ -136,7 +152,7 @@ impl DiffOptions {
}
}

impl Default for DiffOptions {
impl<'a> Default for DiffOptions<'a> {
fn default() -> Self {
Self::new()
}
Expand Down
21 changes: 21 additions & 0 deletions src/diff/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,27 @@ The door of all subtleties!
";
opts.set_context_len(1);
assert_patch!(opts, lao, tzu, expected);

let expected = "\
--- from
+++ to
@@ -1,5 +1,4 @@
-The Way that can be told of is not the eternal Way;
-The name that can be named is not the eternal name.
The Nameless is the origin of Heaven and Earth;
-The Named is the mother of all things.
+The named is the mother of all things.
+
Therefore let there always be non-being,
@@ -11 +10,4 @@
they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
";
opts.set_original("from");
opts.set_modified("to");
assert_patch!(opts, lao, tzu, expected);
}

#[test]
Expand Down

0 comments on commit aa3d7e3

Please sign in to comment.