Skip to content

Commit f1f0dbc

Browse files
author
Gunter Schmidt
committed
code cleanup
* ArgParser: removed default option, which does not exist in GNU diffutils * fix test 'cannot_read_files' (same as PR #188) * merge test from PR #159
1 parent 81d3fcf commit f1f0dbc

File tree

7 files changed

+102
-100
lines changed

7 files changed

+102
-100
lines changed

src/arg_parser.rs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ pub const OPT_HELP: AppOption = AppOption {
2525
long_name: "help",
2626
short: None,
2727
has_arg: false,
28-
arg_default: None,
2928
};
3029
pub const OPT_VERSION: AppOption = AppOption {
3130
long_name: "version",
3231
short: Some('v'),
3332
has_arg: false,
34-
arg_default: None,
3533
};
3634

3735
/// This contains the args/options the app allows. They must be all of const value.
@@ -41,26 +39,9 @@ pub struct AppOption {
4139
pub long_name: &'static str,
4240
pub short: Option<char>,
4341
pub has_arg: bool,
44-
pub arg_default: Option<&'static str>,
42+
// pub arg_default: Option<&'static str>,
4543
}
4644

47-
// #[derive(Debug)]
48-
// pub struct AppOptions(&'static [AppOption]);
49-
//
50-
// impl AppOptions {
51-
// fn identify_options_from_partial_text(&self, opt: &str) -> Vec<&'static AppOption> {
52-
// let l = opt.len();
53-
// let v: Vec<&'static AppOption> = self
54-
// .0
55-
// .iter()
56-
// .filter(|&it| it.long.len() >= l && &it.long[0..l] == opt)
57-
// // .copied()
58-
// .collect();
59-
//
60-
// v
61-
// }
62-
// }
63-
6445
#[derive(Debug, Clone, PartialEq)]
6546
pub struct ParsedOption {
6647
pub app_option: &'static AppOption,
@@ -106,11 +87,7 @@ impl ParsedOption {
10687
}
10788
}
10889
if self.arg_for_option.is_none() {
109-
if let Some(default) = self.app_option.arg_default {
110-
self.arg_for_option = Some(default.to_string())
111-
} else {
112-
return Err(ArgParserError::ArgForOptionMissing(self.clone()));
113-
}
90+
return Err(ArgParserError::ArgForOptionMissing(self.clone()));
11491
}
11592
}
11693
} else {
@@ -145,7 +122,6 @@ impl Default for ParsedOption {
145122
long_name: "dummy",
146123
short: None,
147124
has_arg: false,
148-
arg_default: None,
149125
},
150126
arg_for_option: None,
151127
name_type_used: OptionNameTypeUsed::LongName,
@@ -250,9 +226,6 @@ impl Display for ArgParserError {
250226
ArgParserError::NoExecutable => {
251227
write!(f, "Expected utility name as second argument, got nothing.")
252228
}
253-
// ParamsGenParseError::IgnoreInitialDouble( op3, ig) => {
254-
// write_err(f, &format!("option '--ignore-initial' ('-i') is set to {ig} but also values ares passed as operand '{op3}'"))
255-
// }
256229
ArgParserError::InvalidOption(opt) => {
257230
write!(f, "{}", &format!("invalid option '{opt}'"))
258231
}
@@ -493,6 +466,10 @@ impl ArgParser {
493466
Ok(arg_parser)
494467
}
495468

469+
pub fn add_copyright(text: &str) -> String {
470+
format!("{text}\n{TEXT_COPYRIGHT}")
471+
}
472+
496473
pub fn identify_options_from_partial_text(
497474
app_options: &'static [AppOption],
498475
opt: &str,

src/diff.rs

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

4040
let (from_content, to_content) = match utils::read_both_files(&params.from, &params.to) {
4141
Ok(contents) => contents,
42-
Err((filepath, error)) => {
42+
Err(e) => {
4343
eprintln!(
4444
"{}",
45-
utils::format_failure_to_read_input_file(&params.executable, &filepath, &error)
45+
utils::format_failure_to_read_input_files(&params.executable, &e)
4646
);
4747
return ExitCode::from(2);
4848
}

src/sdiff.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,9 @@ impl Display for SdiffError {
9191
pub fn sdiff(params: &ParamsSdiff) -> Result<SdiffOk, SdiffError> {
9292
let (from_content, to_content) = match utils::read_both_files(&params.from, &params.to) {
9393
Ok(contents) => contents,
94-
Err((filepath, error)) => {
95-
let msg = utils::format_failure_to_read_input_file(
96-
&params.util.executable(),
97-
&filepath,
98-
&error,
99-
);
94+
// Err((filepath, error)) => {
95+
Err(errors) => {
96+
let msg = utils::format_failure_to_read_input_files(&params.util.executable(), &errors);
10097
return Err(SdiffError::ReadFileError(msg));
10198
}
10299
};

src/sdiff/params_sdiff.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl ParamsSdiff {
7575
match *parsed_option.app_option {
7676
OPT_DIFF_PROGRAM => params.diff_program = parsed_option.arg_for_option.clone(),
7777
OPT_EXPAND_TABS => params.expand_tabs = true,
78-
OPT_HELP => return Ok(ParamsSdiffOk::Info(ParamsSdiffInfo::Help)),
78+
OPT_HELP => return Ok(ParamsSdiffOk::Info(ArgParser::add_copyright(TEXT_HELP))),
7979
OPT_IGNORE_ALL_SPACE => params.ignore_all_space = true,
8080
OPT_IGNORE_BLANK_LINES => params.ignore_blank_lines = true,
8181
OPT_IGNORE_CASE => params.ignore_case = true,
@@ -95,7 +95,7 @@ impl ParamsSdiff {
9595
params.set_tabsize(parsed_option)?;
9696
}
9797
OPT_TEXT => params.text = true,
98-
OPT_VERSION => return Ok(ParamsSdiffOk::Info(ParamsSdiffInfo::Version)),
98+
OPT_VERSION => return Ok(ParamsSdiffOk::Info(TEXT_VERSION.to_string())),
9999
OPT_WIDTH => {
100100
params.set_width(parsed_option)?;
101101
}

src/sdiff/params_sdiff_def.rs

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use const_format::concatcp;
55

66
use crate::{
77
arg_parser::{
8-
AppOption, ArgParserError, ParsedOption, OPT_HELP, OPT_VERSION, TEXT_COPYRIGHT,
9-
TEXT_HELP_FOOTER,
8+
AppOption, ArgParserError, ParsedOption, OPT_HELP, OPT_VERSION, TEXT_HELP_FOOTER,
109
},
1110
sdiff::{params_sdiff::ParamsSdiff, EXE_NAME},
1211
// sdiff::{Bytes, IgnInit, EXE_NAME},
@@ -19,109 +18,91 @@ pub(super) const OPT_DIFF_PROGRAM: AppOption = AppOption {
1918
long_name: "diff-program",
2019
short: None,
2120
has_arg: true,
22-
arg_default: None,
2321
};
2422
pub(super) const OPT_EXPAND_TABS: AppOption = AppOption {
2523
long_name: "expand-tabs",
2624
short: Some('t'),
2725
has_arg: false,
28-
arg_default: None,
2926
};
3027
pub(super) const OPT_IGNORE_ALL_SPACE: AppOption = AppOption {
3128
long_name: "ignore-all-space",
3229
short: Some('W'),
3330
has_arg: false,
34-
arg_default: None,
3531
};
3632
pub(super) const OPT_IGNORE_BLANK_LINES: AppOption = AppOption {
3733
long_name: "ignore-blank-lines",
3834
short: Some('B'),
3935
has_arg: false,
40-
arg_default: None,
4136
};
4237
pub(super) const OPT_IGNORE_CASE: AppOption = AppOption {
4338
long_name: "ignore-case",
4439
short: Some('i'),
4540
has_arg: false,
46-
arg_default: None,
4741
};
4842
pub(super) const OPT_IGNORE_MATCHING_LINES: AppOption = AppOption {
4943
long_name: "ignore-matching-lines",
5044
short: Some('I'),
5145
has_arg: true,
52-
arg_default: None,
5346
};
5447
pub(super) const OPT_IGNORE_SPACE_CHANGE: AppOption = AppOption {
5548
long_name: "ignore-space-change",
5649
short: Some('b'),
5750
has_arg: false,
58-
arg_default: None,
5951
};
6052
pub(super) const OPT_IGNORE_TAB_EXPANSION: AppOption = AppOption {
6153
long_name: "ignore-tab-expansion",
6254
short: Some('E'),
6355
has_arg: false,
64-
arg_default: None,
6556
};
6657
pub(super) const OPT_IGNORE_TRAILING_SPACE: AppOption = AppOption {
6758
long_name: "ignore-trailing-space",
6859
short: Some('Z'),
6960
has_arg: false,
70-
arg_default: None,
7161
};
7262
pub(super) const OPT_LEFT_COLUMN: AppOption = AppOption {
7363
long_name: "left-column",
7464
short: Some('l'),
7565
has_arg: false,
76-
arg_default: None,
7766
};
7867
pub(super) const OPT_MINIMAL: AppOption = AppOption {
7968
long_name: "minimal",
8069
short: Some('d'),
8170
has_arg: false,
82-
arg_default: None,
8371
};
8472
pub(super) const OPT_OUTPUT: AppOption = AppOption {
8573
long_name: "output",
8674
short: Some('o'),
8775
has_arg: true,
88-
arg_default: None,
8976
};
9077
pub(super) const OPT_SPEED_LARGE_FILES: AppOption = AppOption {
9178
long_name: "speed-large-files",
9279
short: Some('H'),
9380
has_arg: false,
94-
arg_default: None,
9581
};
9682
pub(super) const OPT_STRIP_TRAILING_CR: AppOption = AppOption {
9783
long_name: "strip-trailing-cr",
9884
short: None,
9985
has_arg: false,
100-
arg_default: None,
10186
};
10287
pub(super) const OPT_SUPPRESS_COMMON_LINES: AppOption = AppOption {
10388
long_name: "suppress-common-lines",
10489
short: Some('s'),
10590
has_arg: false,
106-
arg_default: None,
10791
};
10892
pub(super) const OPT_TABSIZE: AppOption = AppOption {
10993
long_name: "tabsize",
11094
short: None,
11195
has_arg: true,
112-
arg_default: Some("8"),
11396
};
11497
pub(super) const OPT_TEXT: AppOption = AppOption {
11598
long_name: "text",
11699
short: Some('a'),
117100
has_arg: false,
118-
arg_default: None,
119101
};
120102
pub(super) const OPT_WIDTH: AppOption = AppOption {
121103
long_name: "width",
122104
short: Some('w'),
123105
has_arg: true,
124-
arg_default: None,
125106
};
126107

127108
// Array for ParamsGen
@@ -200,31 +181,10 @@ pub const TEXT_VERSION: &str = concat!("sdiff (Rust DiffUtils) ", env!("CARGO_PK
200181
/// Error will be returned as [ParamsSdiffError] in the function Result.
201182
#[derive(Debug, PartialEq)]
202183
pub enum ParamsSdiffOk {
203-
Info(ParamsSdiffInfo),
184+
Info(String),
204185
ParamsSdiff(ParamsSdiff),
205186
}
206187

207-
/// Static texts for '--help' and '--version'.
208-
///
209-
/// The parser returns these enums to the caller, allowing to identify this as information,
210-
/// so the program exit code is SUCCESS(0).
211-
#[derive(Debug, PartialEq)]
212-
pub enum ParamsSdiffInfo {
213-
Help,
214-
Version,
215-
}
216-
217-
impl Display for ParamsSdiffInfo {
218-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219-
let info = match self {
220-
ParamsSdiffInfo::Help => TEXT_HELP,
221-
ParamsSdiffInfo::Version => &format!("{TEXT_VERSION}\n{TEXT_COPYRIGHT}"),
222-
};
223-
224-
write!(f, "{}", info)
225-
}
226-
}
227-
228188
/// Contains all parser errors and their text messages.
229189
/// This allows centralized maintenance.
230190
#[derive(Debug, PartialEq)]

src/utils.rs

Lines changed: 46 additions & 7 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)]

0 commit comments

Comments
 (0)