Skip to content

Commit

Permalink
Implement --tabsize option
Browse files Browse the repository at this point in the history
  • Loading branch information
oSoMoN committed Mar 19, 2024
1 parent 022084d commit f373fb5
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 40 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ path = "src/main.rs"

[dependencies]
diff = "0.1.10"
regex = "1.10.3"
same-file = "1.0.6"
unicode-width = "0.1.11"

Expand Down
21 changes: 15 additions & 6 deletions src/context_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub fn diff(
context_size: usize,
stop_early: bool,
expand_tabs: bool,
tabsize: usize,
) -> Vec<u8> {
let mut output = format!("*** {expected_filename}\t\n--- {actual_filename}\t\n").into_bytes();
let diff_results = make_diff(expected, actual, context_size, stop_early);
Expand Down Expand Up @@ -317,19 +318,19 @@ pub fn diff(
match line {
DiffLine::Context(e) => {
write!(output, " ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
DiffLine::Change(e) => {
write!(output, "! ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
DiffLine::Add(e) => {
write!(output, "- ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
Expand All @@ -347,19 +348,19 @@ pub fn diff(
match line {
DiffLine::Context(e) => {
write!(output, " ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
DiffLine::Change(e) => {
write!(output, "! ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
DiffLine::Add(e) => {
write!(output, "+ ").expect("write to Vec is infallible");
do_write_line(&mut output, &e, expand_tabs)
do_write_line(&mut output, &e, expand_tabs, tabsize)
.expect("write to Vec is infallible");
writeln!(output).unwrap();
}
Expand Down Expand Up @@ -434,6 +435,7 @@ mod tests {
2,
false,
false,
8,
);
File::create(&format!("{target}/ab.diff"))
.unwrap()
Expand Down Expand Up @@ -514,6 +516,7 @@ mod tests {
2,
false,
false,
8,
);
File::create(&format!("{target}/ab_.diff"))
.unwrap()
Expand Down Expand Up @@ -597,6 +600,7 @@ mod tests {
2,
false,
false,
8,
);
File::create(&format!("{target}/abx.diff"))
.unwrap()
Expand Down Expand Up @@ -683,6 +687,7 @@ mod tests {
2,
false,
false,
8,
);
File::create(&format!("{target}/abr.diff"))
.unwrap()
Expand Down Expand Up @@ -729,6 +734,7 @@ mod tests {
context_size,
false,
false,
8,
);
let expected_full = vec![
"*** foo\t",
Expand All @@ -755,6 +761,7 @@ mod tests {
context_size,
true,
false,
8,
);
let expected_brief = vec!["*** foo\t", "--- bar\t", ""].join("\n");
assert_eq!(diff_brief, expected_brief.as_bytes());
Expand All @@ -767,6 +774,7 @@ mod tests {
context_size,
false,
false,
8,
);
assert!(nodiff_full.is_empty());

Expand All @@ -778,6 +786,7 @@ mod tests {
context_size,
true,
false,
8,
);
assert!(nodiff_brief.is_empty());
}
Expand Down
15 changes: 8 additions & 7 deletions src/ed_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ pub fn diff(
actual: &[u8],
stop_early: bool,
expand_tabs: bool,
tabsize: usize,
) -> Result<Vec<u8>, DiffError> {
let mut output = Vec::new();
let diff_results = make_diff(expected, actual, stop_early)?;
Expand Down Expand Up @@ -152,7 +153,7 @@ pub fn diff(
if actual == b"." {
writeln!(&mut output, "..\n.\ns/.//\na").unwrap();
} else {
do_write_line(&mut output, actual, expand_tabs).unwrap();
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
writeln!(&mut output).unwrap();
}
}
Expand All @@ -167,7 +168,7 @@ mod tests {
use super::*;
use pretty_assertions::assert_eq;
pub fn diff_w(expected: &[u8], actual: &[u8], filename: &str) -> Result<Vec<u8>, DiffError> {
let mut output = diff(expected, actual, false, false)?;
let mut output = diff(expected, actual, false, false, 8)?;
writeln!(&mut output, "w {filename}").unwrap();
Ok(output)
}
Expand All @@ -176,7 +177,7 @@ mod tests {
fn test_basic() {
let from = b"a\n";
let to = b"b\n";
let diff = diff(from, to, false, false).unwrap();
let diff = diff(from, to, false, false, 8).unwrap();
let expected = vec!["1c", "b", ".", ""].join("\n");
assert_eq!(diff, expected.as_bytes());
}
Expand Down Expand Up @@ -411,18 +412,18 @@ mod tests {
let from = vec!["a", "b", "c", ""].join("\n");
let to = vec!["a", "d", "c", ""].join("\n");

let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false).unwrap();
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8).unwrap();
let expected_full = vec!["2c", "d", ".", ""].join("\n");
assert_eq!(diff_full, expected_full.as_bytes());

let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false).unwrap();
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false, 8).unwrap();
let expected_brief = "\0".as_bytes();
assert_eq!(diff_brief, expected_brief);

let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false).unwrap();
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false, 8).unwrap();
assert!(nodiff_full.is_empty());

let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false).unwrap();
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8).unwrap();
assert!(nodiff_brief.is_empty());
}
}
14 changes: 9 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ fn main() -> ExitCode {
report_identical_files,
brief,
expand_tabs,
tabsize,
} = parse_params(opts).unwrap_or_else(|error| {
eprintln!("{error}");
exit(2);
Expand Down Expand Up @@ -67,7 +68,9 @@ fn main() -> ExitCode {
};
// run diff
let result: Vec<u8> = match format {
Format::Normal => normal_diff::diff(&from_content, &to_content, brief, expand_tabs),
Format::Normal => {
normal_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
}
Format::Unified => unified_diff::diff(
&from_content,
&from.to_string_lossy(),
Expand All @@ -76,6 +79,7 @@ fn main() -> ExitCode {
context_count,
brief,
expand_tabs,
tabsize,
),
Format::Context => context_diff::diff(
&from_content,
Expand All @@ -85,13 +89,13 @@ fn main() -> ExitCode {
context_count,
brief,
expand_tabs,
tabsize,
),
Format::Ed => {
ed_diff::diff(&from_content, &to_content, brief, expand_tabs).unwrap_or_else(|error| {
Format::Ed => ed_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
.unwrap_or_else(|error| {
eprintln!("{error}");
exit(2);
})
}
}),
};
if brief && !result.is_empty() {
println!(
Expand Down
30 changes: 18 additions & 12 deletions src/normal_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,13 @@ fn make_diff(expected: &[u8], actual: &[u8], stop_early: bool) -> Vec<Mismatch>
}

#[must_use]
pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool) -> Vec<u8> {
pub fn diff(
expected: &[u8],
actual: &[u8],
stop_early: bool,
expand_tabs: bool,
tabsize: usize,
) -> Vec<u8> {
// See https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Normal.html
// for details on the syntax of the normal format.
let mut output = Vec::new();
Expand Down Expand Up @@ -190,7 +196,7 @@ pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool)
}
for expected in &result.expected {
write!(&mut output, "< ").unwrap();
do_write_line(&mut output, expected, expand_tabs).unwrap();
do_write_line(&mut output, expected, expand_tabs, tabsize).unwrap();
writeln!(&mut output).unwrap();
}
if result.expected_missing_nl {
Expand All @@ -201,7 +207,7 @@ pub fn diff(expected: &[u8], actual: &[u8], stop_early: bool, expand_tabs: bool)
}
for actual in &result.actual {
write!(&mut output, "> ").unwrap();
do_write_line(&mut output, actual, expand_tabs).unwrap();
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
writeln!(&mut output).unwrap();
}
if result.actual_missing_nl {
Expand All @@ -222,7 +228,7 @@ mod tests {
a.write_all(b"a\n").unwrap();
let mut b = Vec::new();
b.write_all(b"b\n").unwrap();
let diff = diff(&a, &b, false, false);
let diff = diff(&a, &b, false, false, 8);
let expected = b"1c1\n< a\n---\n> b\n".to_vec();
assert_eq!(diff, expected);
}
Expand Down Expand Up @@ -275,7 +281,7 @@ mod tests {
}
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, false, false);
let diff = diff(&alef, &bet, false, false, 8);
File::create(&format!("{target}/ab.diff"))
.unwrap()
.write_all(&diff)
Expand Down Expand Up @@ -367,7 +373,7 @@ mod tests {
}
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, false, false);
let diff = diff(&alef, &bet, false, false, 8);
File::create(&format!("{target}/abn.diff"))
.unwrap()
.write_all(&diff)
Expand Down Expand Up @@ -441,7 +447,7 @@ mod tests {
}
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, false, false);
let diff = diff(&alef, &bet, false, false, 8);
File::create(&format!("{target}/ab_.diff"))
.unwrap()
.write_all(&diff)
Expand Down Expand Up @@ -519,7 +525,7 @@ mod tests {
}
// This test diff is intentionally reversed.
// We want it to turn the alef into bet.
let diff = diff(&alef, &bet, false, false);
let diff = diff(&alef, &bet, false, false, 8);
File::create(&format!("{target}/abr.diff"))
.unwrap()
.write_all(&diff)
Expand Down Expand Up @@ -554,18 +560,18 @@ mod tests {
let from = vec!["a", "b", "c"].join("\n");
let to = vec!["a", "d", "c"].join("\n");

let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false);
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8);
let expected_full = vec!["2c2", "< b", "---", "> d", ""].join("\n");
assert_eq!(diff_full, expected_full.as_bytes());

let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false);
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false, 8);
let expected_brief = "\0".as_bytes();
assert_eq!(diff_brief, expected_brief);

let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false);
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false, 8);
assert!(nodiff_full.is_empty());

let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false);
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8);
assert!(nodiff_brief.is_empty());
}
}
Loading

0 comments on commit f373fb5

Please sign in to comment.