mirror of
https://github.com/uutils/diffutils.git
synced 2026-06-10 15:48:59 -07:00
Merge pull request #37 from oSoMoN/diff-arguments
Pass a Params reference to the various diff() functions, instead of a long list of arguments
This commit is contained in:
@@ -3,12 +3,13 @@
|
||||
extern crate libfuzzer_sys;
|
||||
use diffutilslib::ed_diff;
|
||||
use diffutilslib::ed_diff::DiffError;
|
||||
use diffutilslib::params::Params;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
|
||||
fn diff_w(expected: &[u8], actual: &[u8], filename: &str) -> Result<Vec<u8>, DiffError> {
|
||||
let mut output = ed_diff::diff(expected, actual, false, false, 8)?;
|
||||
let mut output = ed_diff::diff(expected, actual, &Params::default())?;
|
||||
writeln!(&mut output, "w {filename}").unwrap();
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#[macro_use]
|
||||
extern crate libfuzzer_sys;
|
||||
use diffutilslib::normal_diff;
|
||||
use diffutilslib::params::Params;
|
||||
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
@@ -21,7 +22,7 @@ fuzz_target!(|x: (Vec<u8>, Vec<u8>)| {
|
||||
} else {
|
||||
return
|
||||
}*/
|
||||
let diff = normal_diff::diff(&from, &to, false, false, 8);
|
||||
let diff = normal_diff::diff(&from, &to, &Params::default());
|
||||
File::create("target/fuzz.file.original")
|
||||
.unwrap()
|
||||
.write_all(&from)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![no_main]
|
||||
#[macro_use]
|
||||
extern crate libfuzzer_sys;
|
||||
use diffutilslib::params::Params;
|
||||
use diffutilslib::unified_diff;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
@@ -22,13 +23,13 @@ fuzz_target!(|x: (Vec<u8>, Vec<u8>, u8)| {
|
||||
}*/
|
||||
let diff = unified_diff::diff(
|
||||
&from,
|
||||
"a/fuzz.file",
|
||||
&to,
|
||||
"target/fuzz.file",
|
||||
context as usize,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/fuzz.file".into(),
|
||||
to: "target/fuzz.file".into(),
|
||||
context_count: context as usize,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
File::create("target/fuzz.file.original")
|
||||
.unwrap()
|
||||
|
||||
+62
-69
@@ -6,6 +6,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::params::Params;
|
||||
use crate::utils::do_write_line;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -265,23 +266,18 @@ fn make_diff(
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn diff(
|
||||
expected: &[u8],
|
||||
expected_filename: &str,
|
||||
actual: &[u8],
|
||||
actual_filename: &str,
|
||||
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);
|
||||
pub fn diff(expected: &[u8], actual: &[u8], params: &Params) -> Vec<u8> {
|
||||
let mut output = format!(
|
||||
"*** {0}\t\n--- {1}\t\n",
|
||||
params.from.to_string_lossy(),
|
||||
params.to.to_string_lossy()
|
||||
)
|
||||
.into_bytes();
|
||||
let diff_results = make_diff(expected, actual, params.context_count, params.brief);
|
||||
if diff_results.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
if stop_early {
|
||||
if params.brief {
|
||||
return output;
|
||||
}
|
||||
for result in diff_results {
|
||||
@@ -319,19 +315,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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.tabsize)
|
||||
.expect("write to Vec is infallible");
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
@@ -349,19 +345,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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.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, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.tabsize)
|
||||
.expect("write to Vec is infallible");
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
@@ -430,13 +426,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alef",
|
||||
&bet,
|
||||
&format!("{target}/alef"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alef".into(),
|
||||
to: (&format!("{target}/alef")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/ab.diff"))
|
||||
.unwrap()
|
||||
@@ -511,13 +507,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alef_",
|
||||
&bet,
|
||||
&format!("{target}/alef_"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alef_".into(),
|
||||
to: (&format!("{target}/alef_")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/ab_.diff"))
|
||||
.unwrap()
|
||||
@@ -595,13 +591,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alefx",
|
||||
&bet,
|
||||
&format!("{target}/alefx"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alefx".into(),
|
||||
to: (&format!("{target}/alefx")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/abx.diff"))
|
||||
.unwrap()
|
||||
@@ -682,13 +678,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alefr",
|
||||
&bet,
|
||||
&format!("{target}/alefr"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alefr".into(),
|
||||
to: (&format!("{target}/alefr")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/abr.diff"))
|
||||
.unwrap()
|
||||
@@ -725,17 +721,15 @@ mod tests {
|
||||
let from = ["a", "b", "c", ""].join("\n");
|
||||
let to_filename = "bar";
|
||||
let to = ["a", "d", "c", ""].join("\n");
|
||||
let context_size: usize = 3;
|
||||
|
||||
let diff_full = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
to.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let expected_full = [
|
||||
"*** foo\t",
|
||||
@@ -756,38 +750,37 @@ mod tests {
|
||||
|
||||
let diff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
to.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
true,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let expected_brief = ["*** foo\t", "--- bar\t", ""].join("\n");
|
||||
assert_eq!(diff_brief, expected_brief.as_bytes());
|
||||
|
||||
let nodiff_full = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
from.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert!(nodiff_full.is_empty());
|
||||
|
||||
let nodiff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
from.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
true,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert!(nodiff_brief.is_empty());
|
||||
}
|
||||
|
||||
+27
-16
@@ -5,6 +5,7 @@
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use crate::params::Params;
|
||||
use crate::utils::do_write_line;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -109,16 +110,10 @@ fn make_diff(expected: &[u8], actual: &[u8], stop_early: bool) -> Result<Vec<Mis
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub fn diff(
|
||||
expected: &[u8],
|
||||
actual: &[u8],
|
||||
stop_early: bool,
|
||||
expand_tabs: bool,
|
||||
tabsize: usize,
|
||||
) -> Result<Vec<u8>, DiffError> {
|
||||
pub fn diff(expected: &[u8], actual: &[u8], params: &Params) -> Result<Vec<u8>, DiffError> {
|
||||
let mut output = Vec::new();
|
||||
let diff_results = make_diff(expected, actual, stop_early)?;
|
||||
if stop_early && !diff_results.is_empty() {
|
||||
let diff_results = make_diff(expected, actual, params.brief)?;
|
||||
if params.brief && !diff_results.is_empty() {
|
||||
write!(&mut output, "\0").unwrap();
|
||||
return Ok(output);
|
||||
}
|
||||
@@ -153,7 +148,7 @@ pub fn diff(
|
||||
if actual == b"." {
|
||||
writeln!(&mut output, "..\n.\ns/.//\na").unwrap();
|
||||
} else {
|
||||
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
|
||||
do_write_line(&mut output, actual, params.expand_tabs, params.tabsize).unwrap();
|
||||
writeln!(&mut output).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -168,7 +163,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, 8)?;
|
||||
let mut output = diff(expected, actual, &Params::default())?;
|
||||
writeln!(&mut output, "w {filename}").unwrap();
|
||||
Ok(output)
|
||||
}
|
||||
@@ -177,7 +172,7 @@ mod tests {
|
||||
fn test_basic() {
|
||||
let from = b"a\n";
|
||||
let to = b"b\n";
|
||||
let diff = diff(from, to, false, false, 8).unwrap();
|
||||
let diff = diff(from, to, &Params::default()).unwrap();
|
||||
let expected = ["1c", "b", ".", ""].join("\n");
|
||||
assert_eq!(diff, expected.as_bytes());
|
||||
}
|
||||
@@ -412,18 +407,34 @@ mod tests {
|
||||
let from = ["a", "b", "c", ""].join("\n");
|
||||
let to = ["a", "d", "c", ""].join("\n");
|
||||
|
||||
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8).unwrap();
|
||||
let diff_full = diff(from.as_bytes(), to.as_bytes(), &Params::default()).unwrap();
|
||||
let expected_full = ["2c", "d", ".", ""].join("\n");
|
||||
assert_eq!(diff_full, expected_full.as_bytes());
|
||||
|
||||
let diff_brief = diff(from.as_bytes(), to.as_bytes(), true, false, 8).unwrap();
|
||||
let diff_brief = diff(
|
||||
from.as_bytes(),
|
||||
to.as_bytes(),
|
||||
&Params {
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.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, 8).unwrap();
|
||||
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), &Params::default()).unwrap();
|
||||
assert!(nodiff_full.is_empty());
|
||||
|
||||
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8).unwrap();
|
||||
let nodiff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from.as_bytes(),
|
||||
&Params {
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
assert!(nodiff_brief.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod context_diff;
|
||||
pub mod ed_diff;
|
||||
pub mod normal_diff;
|
||||
pub mod params;
|
||||
pub mod unified_diff;
|
||||
pub mod utils;
|
||||
|
||||
|
||||
+19
-49
@@ -3,7 +3,7 @@
|
||||
// For the full copyright and license information, please view the LICENSE-*
|
||||
// files that was distributed with this source code.
|
||||
|
||||
use crate::params::{parse_params, Format, Params};
|
||||
use crate::params::{parse_params, Format};
|
||||
use std::env;
|
||||
|
||||
use std::fs;
|
||||
@@ -24,42 +24,33 @@ mod utils;
|
||||
// and 2 means trouble.
|
||||
fn main() -> ExitCode {
|
||||
let opts = env::args_os();
|
||||
let Params {
|
||||
from,
|
||||
to,
|
||||
context_count,
|
||||
format,
|
||||
report_identical_files,
|
||||
brief,
|
||||
expand_tabs,
|
||||
tabsize,
|
||||
} = parse_params(opts).unwrap_or_else(|error| {
|
||||
let params = parse_params(opts).unwrap_or_else(|error| {
|
||||
eprintln!("{error}");
|
||||
exit(2);
|
||||
});
|
||||
// if from and to are the same file, no need to perform any comparison
|
||||
let maybe_report_identical_files = || {
|
||||
if report_identical_files {
|
||||
if params.report_identical_files {
|
||||
println!(
|
||||
"Files {} and {} are identical",
|
||||
from.to_string_lossy(),
|
||||
to.to_string_lossy(),
|
||||
params.from.to_string_lossy(),
|
||||
params.to.to_string_lossy(),
|
||||
)
|
||||
}
|
||||
};
|
||||
if same_file::is_same_file(&from, &to).unwrap_or(false) {
|
||||
if same_file::is_same_file(¶ms.from, ¶ms.to).unwrap_or(false) {
|
||||
maybe_report_identical_files();
|
||||
return ExitCode::SUCCESS;
|
||||
}
|
||||
// read files
|
||||
let from_content = match fs::read(&from) {
|
||||
let from_content = match fs::read(¶ms.from) {
|
||||
Ok(from_content) => from_content,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to read from-file: {e}");
|
||||
return ExitCode::from(2);
|
||||
}
|
||||
};
|
||||
let to_content = match fs::read(&to) {
|
||||
let to_content = match fs::read(¶ms.to) {
|
||||
Ok(to_content) => to_content,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to read to-file: {e}");
|
||||
@@ -67,41 +58,20 @@ fn main() -> ExitCode {
|
||||
}
|
||||
};
|
||||
// run diff
|
||||
let result: Vec<u8> = match format {
|
||||
Format::Normal => {
|
||||
normal_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
|
||||
}
|
||||
Format::Unified => unified_diff::diff(
|
||||
&from_content,
|
||||
&from.to_string_lossy(),
|
||||
&to_content,
|
||||
&to.to_string_lossy(),
|
||||
context_count,
|
||||
brief,
|
||||
expand_tabs,
|
||||
tabsize,
|
||||
),
|
||||
Format::Context => context_diff::diff(
|
||||
&from_content,
|
||||
&from.to_string_lossy(),
|
||||
&to_content,
|
||||
&to.to_string_lossy(),
|
||||
context_count,
|
||||
brief,
|
||||
expand_tabs,
|
||||
tabsize,
|
||||
),
|
||||
Format::Ed => ed_diff::diff(&from_content, &to_content, brief, expand_tabs, tabsize)
|
||||
.unwrap_or_else(|error| {
|
||||
eprintln!("{error}");
|
||||
exit(2);
|
||||
}),
|
||||
let result: Vec<u8> = match params.format {
|
||||
Format::Normal => normal_diff::diff(&from_content, &to_content, ¶ms),
|
||||
Format::Unified => unified_diff::diff(&from_content, &to_content, ¶ms),
|
||||
Format::Context => context_diff::diff(&from_content, &to_content, ¶ms),
|
||||
Format::Ed => ed_diff::diff(&from_content, &to_content, ¶ms).unwrap_or_else(|error| {
|
||||
eprintln!("{error}");
|
||||
exit(2);
|
||||
}),
|
||||
};
|
||||
if brief && !result.is_empty() {
|
||||
if params.brief && !result.is_empty() {
|
||||
println!(
|
||||
"Files {} and {} differ",
|
||||
from.to_string_lossy(),
|
||||
to.to_string_lossy()
|
||||
params.from.to_string_lossy(),
|
||||
params.to.to_string_lossy()
|
||||
);
|
||||
} else {
|
||||
io::stdout().write_all(&result).unwrap();
|
||||
|
||||
+29
-20
@@ -5,6 +5,7 @@
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use crate::params::Params;
|
||||
use crate::utils::do_write_line;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -116,18 +117,12 @@ 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,
|
||||
tabsize: usize,
|
||||
) -> Vec<u8> {
|
||||
pub fn diff(expected: &[u8], actual: &[u8], params: &Params) -> 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();
|
||||
let diff_results = make_diff(expected, actual, stop_early);
|
||||
if stop_early && !diff_results.is_empty() {
|
||||
let diff_results = make_diff(expected, actual, params.brief);
|
||||
if params.brief && !diff_results.is_empty() {
|
||||
write!(&mut output, "\0").unwrap();
|
||||
return output;
|
||||
}
|
||||
@@ -196,7 +191,7 @@ pub fn diff(
|
||||
}
|
||||
for expected in &result.expected {
|
||||
write!(&mut output, "< ").unwrap();
|
||||
do_write_line(&mut output, expected, expand_tabs, tabsize).unwrap();
|
||||
do_write_line(&mut output, expected, params.expand_tabs, params.tabsize).unwrap();
|
||||
writeln!(&mut output).unwrap();
|
||||
}
|
||||
if result.expected_missing_nl {
|
||||
@@ -207,7 +202,7 @@ pub fn diff(
|
||||
}
|
||||
for actual in &result.actual {
|
||||
write!(&mut output, "> ").unwrap();
|
||||
do_write_line(&mut output, actual, expand_tabs, tabsize).unwrap();
|
||||
do_write_line(&mut output, actual, params.expand_tabs, params.tabsize).unwrap();
|
||||
writeln!(&mut output).unwrap();
|
||||
}
|
||||
if result.actual_missing_nl {
|
||||
@@ -228,7 +223,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, 8);
|
||||
let diff = diff(&a, &b, &Params::default());
|
||||
let expected = b"1c1\n< a\n---\n> b\n".to_vec();
|
||||
assert_eq!(diff, expected);
|
||||
}
|
||||
@@ -281,7 +276,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, 8);
|
||||
let diff = diff(&alef, &bet, &Params::default());
|
||||
File::create(&format!("{target}/ab.diff"))
|
||||
.unwrap()
|
||||
.write_all(&diff)
|
||||
@@ -373,7 +368,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, 8);
|
||||
let diff = diff(&alef, &bet, &Params::default());
|
||||
File::create(&format!("{target}/abn.diff"))
|
||||
.unwrap()
|
||||
.write_all(&diff)
|
||||
@@ -447,7 +442,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, 8);
|
||||
let diff = diff(&alef, &bet, &Params::default());
|
||||
File::create(&format!("{target}/ab_.diff"))
|
||||
.unwrap()
|
||||
.write_all(&diff)
|
||||
@@ -525,7 +520,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, 8);
|
||||
let diff = diff(&alef, &bet, &Params::default());
|
||||
File::create(&format!("{target}/abr.diff"))
|
||||
.unwrap()
|
||||
.write_all(&diff)
|
||||
@@ -560,18 +555,32 @@ mod tests {
|
||||
let from = ["a", "b", "c"].join("\n");
|
||||
let to = ["a", "d", "c"].join("\n");
|
||||
|
||||
let diff_full = diff(from.as_bytes(), to.as_bytes(), false, false, 8);
|
||||
let diff_full = diff(from.as_bytes(), to.as_bytes(), &Params::default());
|
||||
let expected_full = ["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, 8);
|
||||
let diff_brief = diff(
|
||||
from.as_bytes(),
|
||||
to.as_bytes(),
|
||||
&Params {
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let expected_brief = "\0".as_bytes();
|
||||
assert_eq!(diff_brief, expected_brief);
|
||||
|
||||
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), false, false, 8);
|
||||
let nodiff_full = diff(from.as_bytes(), from.as_bytes(), &Params::default());
|
||||
assert!(nodiff_full.is_empty());
|
||||
|
||||
let nodiff_brief = diff(from.as_bytes(), from.as_bytes(), true, false, 8);
|
||||
let nodiff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from.as_bytes(),
|
||||
&Params {
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert!(nodiff_brief.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
+65
-72
@@ -6,6 +6,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::params::Params;
|
||||
use crate::utils::do_write_line;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -236,23 +237,18 @@ fn make_diff(
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn diff(
|
||||
expected: &[u8],
|
||||
expected_filename: &str,
|
||||
actual: &[u8],
|
||||
actual_filename: &str,
|
||||
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);
|
||||
pub fn diff(expected: &[u8], actual: &[u8], params: &Params) -> Vec<u8> {
|
||||
let mut output = format!(
|
||||
"--- {0}\t\n+++ {1}\t\n",
|
||||
params.from.to_string_lossy(),
|
||||
params.to.to_string_lossy()
|
||||
)
|
||||
.into_bytes();
|
||||
let diff_results = make_diff(expected, actual, params.context_count, params.brief);
|
||||
if diff_results.is_empty() {
|
||||
return Vec::new();
|
||||
}
|
||||
if stop_early {
|
||||
if params.brief {
|
||||
return output;
|
||||
}
|
||||
for result in diff_results {
|
||||
@@ -376,19 +372,19 @@ pub fn diff(
|
||||
match line {
|
||||
DiffLine::Expected(e) => {
|
||||
write!(output, "-").expect("write to Vec is infallible");
|
||||
do_write_line(&mut output, &e, expand_tabs, tabsize)
|
||||
do_write_line(&mut output, &e, params.expand_tabs, params.tabsize)
|
||||
.expect("write to Vec is infallible");
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
DiffLine::Context(c) => {
|
||||
write!(output, " ").expect("write to Vec is infallible");
|
||||
do_write_line(&mut output, &c, expand_tabs, tabsize)
|
||||
do_write_line(&mut output, &c, params.expand_tabs, params.tabsize)
|
||||
.expect("write to Vec is infallible");
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
DiffLine::Actual(r) => {
|
||||
write!(output, "+",).expect("write to Vec is infallible");
|
||||
do_write_line(&mut output, &r, expand_tabs, tabsize)
|
||||
do_write_line(&mut output, &r, params.expand_tabs, params.tabsize)
|
||||
.expect("write to Vec is infallible");
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
@@ -457,13 +453,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alef",
|
||||
&bet,
|
||||
&format!("{target}/alef"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alef".into(),
|
||||
to: (&format!("{target}/alef")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/ab.diff"))
|
||||
.unwrap()
|
||||
@@ -573,13 +569,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alefn",
|
||||
&bet,
|
||||
&format!("{target}/alefn"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alefn".into(),
|
||||
to: (&format!("{target}/alefn")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/abn.diff"))
|
||||
.unwrap()
|
||||
@@ -669,13 +665,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alef_",
|
||||
&bet,
|
||||
&format!("{target}/alef_"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alef_".into(),
|
||||
to: (&format!("{target}/alef_")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/ab_.diff"))
|
||||
.unwrap()
|
||||
@@ -750,13 +746,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alefx",
|
||||
&bet,
|
||||
&format!("{target}/alefx"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alefx".into(),
|
||||
to: (&format!("{target}/alefx")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/abx.diff"))
|
||||
.unwrap()
|
||||
@@ -836,13 +832,13 @@ mod tests {
|
||||
// We want it to turn the alef into bet.
|
||||
let diff = diff(
|
||||
&alef,
|
||||
"a/alefr",
|
||||
&bet,
|
||||
&format!("{target}/alefr"),
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: "a/alefr".into(),
|
||||
to: (&format!("{target}/alefr")).into(),
|
||||
context_count: 2,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
File::create(&format!("{target}/abr.diff"))
|
||||
.unwrap()
|
||||
@@ -878,17 +874,15 @@ mod tests {
|
||||
let from = ["a", "b", "c", ""].join("\n");
|
||||
let to_filename = "bar";
|
||||
let to = ["a", "d", "c", ""].join("\n");
|
||||
let context_size: usize = 3;
|
||||
|
||||
let diff_full = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
to.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let expected_full = [
|
||||
"--- foo\t",
|
||||
@@ -905,38 +899,37 @@ mod tests {
|
||||
|
||||
let diff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
to.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
true,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
let expected_brief = ["--- foo\t", "+++ bar\t", ""].join("\n");
|
||||
assert_eq!(diff_brief, expected_brief.as_bytes());
|
||||
|
||||
let nodiff_full = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
from.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
false,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert!(nodiff_full.is_empty());
|
||||
|
||||
let nodiff_brief = diff(
|
||||
from.as_bytes(),
|
||||
from_filename,
|
||||
from.as_bytes(),
|
||||
to_filename,
|
||||
context_size,
|
||||
true,
|
||||
false,
|
||||
8,
|
||||
&Params {
|
||||
from: from_filename.into(),
|
||||
to: to_filename.into(),
|
||||
brief: true,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert!(nodiff_brief.is_empty());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user