Skip to content

Commit

Permalink
added reverse operation to reverse a patch (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonpollack23 authored Jan 10, 2024
1 parent 34377f1 commit 824674e
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/diff/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,3 +664,45 @@ Second:

assert_eq!(result, expected);
}

#[test]
fn reverse_empty_file() {
let p = create_patch("", "make it so");
let reverse = p.reverse();

let hunk_lines = p.hunks().iter().map(|h| h.lines());
let reverse_hunk_lines = reverse.hunks().iter().map(|h| h.lines());

for (lines, reverse_lines) in hunk_lines.zip(reverse_hunk_lines) {
for (line, reverse) in lines.iter().zip(reverse_lines.iter()) {
match line {
l @ Line::Context(_) => assert_eq!(l, reverse),
Line::Delete(d) => assert!(matches!(reverse, Line::Insert(i) if d == i)),
Line::Insert(i) => assert!(matches!(reverse, Line::Delete(d) if d == i)),
}
}
}

let re_reverse = apply(&apply("", &p).unwrap(), &reverse).unwrap();
assert_eq!(re_reverse, "");
}

#[test]
fn reverse_multi_line_file() {
let original = r"Commander Worf
What do you want this time, Picard?!
Commander Worf how dare you speak to mean that way!
";
let modified = r"Commander Worf
Yes, Captain Picard?
Commander Worf, you are a valued member of my crew
Why, thank you Captain. As are you. A true warrior. Kupluh!
Kupluh, Indeed
";

let p = create_patch(original, modified);
let reverse = p.reverse();

let re_reverse = apply(&apply(original, &p).unwrap(), &reverse).unwrap();
assert_eq!(re_reverse, original);
}
31 changes: 31 additions & 0 deletions src/patch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ impl<'a, T: ToOwned + ?Sized> Patch<'a, T> {
pub fn hunks(&self) -> &[Hunk<'_, T>] {
&self.hunks
}

pub fn reverse(&self) -> Patch<'_, T> {
let hunks = self.hunks.iter().map(Hunk::reverse).collect();
Patch {
original: self.modified.clone(),
modified: self.original.clone(),
hunks,
}
}
}

impl<T: AsRef<[u8]> + ToOwned + ?Sized> Patch<'_, T> {
Expand Down Expand Up @@ -278,6 +287,18 @@ impl<'a, T: ?Sized> Hunk<'a, T> {
pub fn lines(&self) -> &[Line<'a, T>] {
&self.lines
}

/// Creates a reverse patch for the hunk. This is equivalent to what
/// XDL_PATCH_REVERSE would apply in libxdiff.
pub fn reverse(&self) -> Self {
let lines = self.lines.iter().map(Line::reverse).collect();
Self {
old_range: self.new_range,
new_range: self.old_range,
function_context: self.function_context,
lines,
}
}
}

impl<T: ?Sized> Clone for Hunk<'_, T> {
Expand Down Expand Up @@ -362,3 +383,13 @@ impl<T: ?Sized> Clone for Line<'_, T> {
*self
}
}

impl<T: ?Sized> Line<'_, T> {
pub fn reverse(&self) -> Self {
match self {
Line::Context(s) => Line::Context(s),
Line::Delete(s) => Line::Insert(s),
Line::Insert(s) => Line::Delete(s),
}
}
}

0 comments on commit 824674e

Please sign in to comment.