Skip to content

Commit 5c99400

Browse files
authored
Merge pull request #91 from distil/fix_all_same
fix: Don't create overlapping prefix_eq/suffix_eq in the LCS
2 parents 1216ff5 + 06c0e54 commit 5c99400

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

diffus-derive-test/src/lib.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,33 @@ mod test {
9191
}
9292
}
9393

94+
#[test]
95+
fn changed_contents() {
96+
let left = vec![Identified { id: 1, value: 0 }];
97+
let right = vec![Identified { id: 1, value: 1 }];
98+
99+
let diff = left.diff(&right);
100+
101+
use edit::{self, collection};
102+
103+
if let edit::Edit::Change(diff) = diff {
104+
let diff = diff.into_iter().collect::<Vec<_>>();
105+
106+
assert_eq!(diff.len(), 1);
107+
108+
if let &collection::Edit::Change(EditedIdentified {
109+
id: edit::Edit::Copy(&1),
110+
value: edit::Edit::Change((&0, &1)),
111+
}) = &diff[0]
112+
{
113+
} else {
114+
unreachable!()
115+
}
116+
} else {
117+
unreachable!()
118+
}
119+
}
120+
94121
#[derive(Diffus)]
95122
enum NestedTest {
96123
T { test: Test },

diffus/src/lcs.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,25 @@ where
2828
I: DoubleEndedIterator<Item = T>,
2929
J: DoubleEndedIterator<Item = T>,
3030
{
31-
let prefix_eq = x().zip(y()).take_while(|(x, y)| x.same(y)).count();
32-
let suffix_eq = x()
33-
.rev()
34-
.zip(y().rev())
31+
let mut x_iter = x();
32+
let mut y_iter = y();
33+
let prefix_eq = x_iter
34+
.by_ref()
35+
.zip(y_iter.by_ref())
3536
.take_while(|(x, y)| x.same(y))
3637
.count();
38+
// Only check the suffix if we did not consume the entirety of either of the iterators
39+
// (If one of them are consumed, we would double count elements)
40+
let check_suffix = x_len.min(y_len) != prefix_eq;
41+
let suffix_eq = if check_suffix {
42+
x_iter
43+
.rev()
44+
.zip(y_iter.rev())
45+
.take_while(|(x, y)| x.same(y))
46+
.count()
47+
} else {
48+
0
49+
};
3750

3851
let width = x_len.saturating_sub(prefix_eq + suffix_eq) + 1;
3952
let height = y_len.saturating_sub(prefix_eq + suffix_eq) + 1;

0 commit comments

Comments
 (0)