Skip to content

Commit d446f97

Browse files
Gunter Schmidtsylvestre
authored andcommitted
fix: Restore file not found test and correct prg.
Instead of 'fixing' the test, the program now acts like the GNU original and returns up to two error messages, one for each file.
1 parent 3127494 commit d446f97

File tree

4 files changed

+69
-26
lines changed

4 files changed

+69
-26
lines changed

src/diff.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
4141

4242
let (from_content, to_content) = match utils::read_both_files(&params.from, &params.to) {
4343
Ok(contents) => contents,
44-
Err((filepath, error)) => {
44+
Err(e) => {
4545
eprintln!(
4646
"{}",
47-
utils::format_failure_to_read_input_file(&params.executable, &filepath, &error)
47+
utils::format_failure_to_read_input_files(&params.executable, &e)
4848
);
4949
return ExitCode::from(2);
5050
}

src/sdiff.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ pub fn main(opts: Peekable<ArgsOs>) -> ExitCode {
168168

169169
let (from_content, to_content) = match utils::read_both_files(&params.from, &params.to) {
170170
Ok(contents) => contents,
171-
Err((filepath, error)) => {
171+
Err(e) => {
172172
eprintln!(
173173
"{}",
174-
utils::format_failure_to_read_input_file(&params.executable, &filepath, &error)
174+
utils::format_failure_to_read_input_files(&params.executable, &e)
175175
);
176176
return ExitCode::from(2);
177177
}

src/utils.rs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ pub fn format_failure_to_read_input_file(
8888
)
8989
}
9090

91+
/// Formats the error messages of both files.
92+
pub fn format_failure_to_read_input_files(
93+
executable: &OsString,
94+
errors: &[(OsString, Error)],
95+
) -> String {
96+
let mut msg = format_failure_to_read_input_file(
97+
executable,
98+
&errors[0].0, // filepath,
99+
&errors[0].1, // &error,
100+
);
101+
if errors.len() > 1 {
102+
msg.push('\n');
103+
msg.push_str(&format_failure_to_read_input_file(
104+
executable,
105+
&errors[1].0, // filepath,
106+
&errors[1].1, // &error,
107+
));
108+
}
109+
110+
msg
111+
}
112+
91113
pub fn read_file_contents(filepath: &OsString) -> io::Result<Vec<u8>> {
92114
if filepath == "-" {
93115
let mut content = Vec::new();
@@ -97,13 +119,30 @@ pub fn read_file_contents(filepath: &OsString) -> io::Result<Vec<u8>> {
97119
}
98120
}
99121

100-
pub fn read_both_files(
101-
from: &OsString,
102-
to: &OsString,
103-
) -> Result<(Vec<u8>, Vec<u8>), (OsString, Error)> {
104-
let from_content = read_file_contents(from).map_err(|e| (from.clone(), e))?;
105-
let to_content = read_file_contents(to).map_err(|e| (to.clone(), e))?;
106-
Ok((from_content, to_content))
122+
pub type ResultReadBothFiles = Result<(Vec<u8>, Vec<u8>), Vec<(OsString, Error)>>;
123+
/// Reads both files and returns the files or a list of errors, as both files can produce a separate error.
124+
pub fn read_both_files(from: &OsString, to: &OsString) -> ResultReadBothFiles {
125+
let mut read_errors = Vec::new();
126+
let from_content = match read_file_contents(from).map_err(|e| (from.clone(), e)) {
127+
Ok(r) => r,
128+
Err(e) => {
129+
read_errors.push(e);
130+
Vec::new()
131+
}
132+
};
133+
let to_content = match read_file_contents(to).map_err(|e| (to.clone(), e)) {
134+
Ok(r) => r,
135+
Err(e) => {
136+
read_errors.push(e);
137+
Vec::new()
138+
}
139+
};
140+
141+
if read_errors.is_empty() {
142+
Ok((from_content, to_content))
143+
} else {
144+
Err(read_errors)
145+
}
107146
}
108147

109148
#[cfg(test)]
@@ -189,13 +228,13 @@ mod tests {
189228

190229
let res = read_both_files(&non_exist_file_path, &exist_file_path);
191230
assert!(res.is_err());
192-
let (err_path, _) = res.unwrap_err();
193-
assert_eq!(err_path, non_exist_file_path);
231+
let err_path = res.unwrap_err();
232+
assert_eq!(err_path[0].0, non_exist_file_path);
194233

195234
let res = read_both_files(&exist_file_path, &non_exist_file_path);
196235
assert!(res.is_err());
197-
let (err_path, _) = res.unwrap_err();
198-
assert_eq!(err_path, non_exist_file_path);
236+
let err_path = res.unwrap_err();
237+
assert_eq!(err_path[0].0, non_exist_file_path);
199238
}
200239
}
201240

tests/integration.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,22 @@ mod common {
8181
": {}: {error_message}\n",
8282
&nopath.as_os_str().to_string_lossy()
8383
)));
84-
}
8584

86-
let mut cmd = cargo_bin_cmd!("diffutils");
87-
cmd.arg("diff");
88-
cmd.arg(&nopath).arg(&nopath);
89-
cmd.assert()
90-
.code(predicate::eq(2))
91-
.failure()
92-
.stderr(predicate::str::contains(format!(
93-
": {}: {error_message}\n",
94-
&nopath.as_os_str().to_string_lossy()
95-
)));
85+
// TODO test fails for cmp
86+
if subcmd == "cmp" {
87+
continue;
88+
}
89+
let mut cmd = cargo_bin_cmd!("diffutils");
90+
cmd.arg(subcmd);
91+
cmd.arg(&nopath).arg(&nopath);
92+
cmd.assert().code(predicate::eq(2)).failure().stderr(
93+
predicate::str::contains(format!(
94+
": {}: {error_message}\n",
95+
&nopath.as_os_str().to_string_lossy()
96+
))
97+
.count(2),
98+
);
99+
}
96100

97101
Ok(())
98102
}

0 commit comments

Comments
 (0)