Skip to content

Commit 02632e9

Browse files
authored
Merge pull request #11 from oSoMoN/compact-range-of-lines
Normal diff: compact ranges of lines where possible (fixes #10)
2 parents c28973c + 3f9556a commit 02632e9

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/normal_diff.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ fn make_diff(expected: &[u8], actual: &[u8]) -> Vec<Mismatch> {
111111

112112
#[must_use]
113113
pub fn diff(expected: &[u8], actual: &[u8]) -> Vec<u8> {
114+
// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Normal.html
115+
// for details on the syntax of the normal format.
114116
let mut output = Vec::new();
115117
let diff_results = make_diff(expected, actual);
116118
for result in diff_results {
@@ -121,6 +123,7 @@ pub fn diff(expected: &[u8], actual: &[u8]) -> Vec<u8> {
121123
match (expected_count, actual_count) {
122124
(0, 0) => unreachable!(),
123125
(0, _) => writeln!(
126+
// 'a' stands for "Add lines"
124127
&mut output,
125128
"{}a{},{}",
126129
line_number_expected - 1,
@@ -129,14 +132,43 @@ pub fn diff(expected: &[u8], actual: &[u8]) -> Vec<u8> {
129132
)
130133
.unwrap(),
131134
(_, 0) => writeln!(
135+
// 'd' stands for "Delete lines"
132136
&mut output,
133137
"{},{}d{}",
134138
line_number_expected,
135139
expected_count + line_number_expected - 1,
136140
line_number_actual - 1
137141
)
138142
.unwrap(),
143+
(1, 1) => writeln!(
144+
// 'c' stands for "Change lines"
145+
// exactly one line replaced by one line
146+
&mut output,
147+
"{}c{}",
148+
line_number_expected,
149+
line_number_actual
150+
)
151+
.unwrap(),
152+
(1, _) => writeln!(
153+
// one line replaced by multiple lines
154+
&mut output,
155+
"{}c{},{}",
156+
line_number_expected,
157+
line_number_actual,
158+
actual_count + line_number_actual - 1
159+
)
160+
.unwrap(),
161+
(_, 1) => writeln!(
162+
// multiple lines replaced by one line
163+
&mut output,
164+
"{},{}c{}",
165+
line_number_expected,
166+
expected_count + line_number_expected - 1,
167+
line_number_actual
168+
)
169+
.unwrap(),
139170
_ => writeln!(
171+
// general case: multiple lines replaced by multiple lines
140172
&mut output,
141173
"{},{}c{},{}",
142174
line_number_expected,
@@ -173,6 +205,18 @@ pub fn diff(expected: &[u8], actual: &[u8]) -> Vec<u8> {
173205
mod tests {
174206
use super::*;
175207
use pretty_assertions::assert_eq;
208+
209+
#[test]
210+
fn test_basic() {
211+
let mut a = Vec::new();
212+
a.write_all(b"a\n").unwrap();
213+
let mut b = Vec::new();
214+
b.write_all(b"b\n").unwrap();
215+
let diff = diff(&a, &b);
216+
let expected = b"1c1\n< a\n---\n> b\n".to_vec();
217+
assert_eq!(diff, expected);
218+
}
219+
176220
#[test]
177221
fn test_permutations() {
178222
let target = "target/normal-diff/";

0 commit comments

Comments
 (0)