mirror of
https://github.com/uutils/coreutils
synced 2024-12-13 23:02:38 +00:00
commit
dc8d07ccce
2 changed files with 125 additions and 14 deletions
|
@ -42,6 +42,7 @@ struct Settings {
|
|||
show_max_line_length: bool,
|
||||
files0_from_stdin_mode: bool,
|
||||
title_quoting_style: QuotingStyle,
|
||||
total_when: TotalWhen,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
|
@ -65,6 +66,7 @@ impl Settings {
|
|||
show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH),
|
||||
files0_from_stdin_mode,
|
||||
title_quoting_style,
|
||||
total_when: matches.get_one::<String>(options::TOTAL).unwrap().into(),
|
||||
};
|
||||
|
||||
if settings.show_bytes
|
||||
|
@ -84,6 +86,7 @@ impl Settings {
|
|||
show_max_line_length: false,
|
||||
files0_from_stdin_mode,
|
||||
title_quoting_style: settings.title_quoting_style,
|
||||
total_when: settings.total_when,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +110,7 @@ pub mod options {
|
|||
pub static FILES0_FROM: &str = "files0-from";
|
||||
pub static LINES: &str = "lines";
|
||||
pub static MAX_LINE_LENGTH: &str = "max-line-length";
|
||||
pub static TOTAL: &str = "total";
|
||||
pub static WORDS: &str = "words";
|
||||
}
|
||||
|
||||
|
@ -160,6 +164,37 @@ impl Input {
|
|||
}
|
||||
}
|
||||
|
||||
/// When to show the "total" line
|
||||
#[derive(PartialEq)]
|
||||
enum TotalWhen {
|
||||
Auto,
|
||||
Always,
|
||||
Only,
|
||||
Never,
|
||||
}
|
||||
|
||||
impl From<&String> for TotalWhen {
|
||||
fn from(s: &String) -> Self {
|
||||
match s.as_ref() {
|
||||
"auto" => Self::Auto,
|
||||
"always" => Self::Always,
|
||||
"only" => Self::Only,
|
||||
"never" => Self::Never,
|
||||
_ => unreachable!("Should have been caught by clap"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TotalWhen {
|
||||
fn is_total_row_visible(&self, num_inputs: usize) -> bool {
|
||||
match self {
|
||||
Self::Auto => num_inputs > 1,
|
||||
Self::Always | Self::Only => true,
|
||||
Self::Never => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum WcError {
|
||||
FilesDisabled(String),
|
||||
|
@ -246,6 +281,15 @@ pub fn uu_app() -> Command {
|
|||
.help("print the length of the longest line")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::TOTAL)
|
||||
.long(options::TOTAL)
|
||||
.value_parser(["auto", "always", "only", "never"])
|
||||
.default_value("auto")
|
||||
.hide_default_value(true)
|
||||
.value_name("WHEN")
|
||||
.help("when to print a line with total counts"),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::WORDS)
|
||||
.short('w')
|
||||
|
@ -561,11 +605,19 @@ fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize {
|
|||
}
|
||||
|
||||
fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
||||
let number_width = compute_number_width(inputs, settings);
|
||||
|
||||
let mut total_word_count = WordCount::default();
|
||||
|
||||
let num_inputs = inputs.len();
|
||||
let (number_width, are_stats_visible, total_row_title) =
|
||||
if settings.total_when == TotalWhen::Only {
|
||||
(1, false, None)
|
||||
} else {
|
||||
let number_width = compute_number_width(inputs, settings);
|
||||
let title = Some(String::from("total"));
|
||||
|
||||
(number_width, true, title)
|
||||
};
|
||||
|
||||
let is_total_row_visible = settings.total_when.is_total_row_visible(inputs.len());
|
||||
|
||||
for input in inputs {
|
||||
let word_count = match word_count_from_input(input, settings) {
|
||||
|
@ -595,20 +647,23 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
|||
};
|
||||
total_word_count += word_count;
|
||||
let result = word_count.with_title(input.to_title(&settings.title_quoting_style));
|
||||
if let Err(err) = print_stats(settings, &result, number_width) {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"failed to print result for {}: {}",
|
||||
&result.title.unwrap_or_else(|| String::from("<stdin>")),
|
||||
err,
|
||||
),
|
||||
));
|
||||
|
||||
if are_stats_visible {
|
||||
if let Err(err) = print_stats(settings, &result, number_width) {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
format!(
|
||||
"failed to print result for {}: {}",
|
||||
&result.title.unwrap_or_else(|| String::from("<stdin>")),
|
||||
err,
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if num_inputs > 1 {
|
||||
let total_result = total_word_count.with_title(Some(String::from("total")));
|
||||
if is_total_row_visible {
|
||||
let total_result = total_word_count.with_title(total_row_title);
|
||||
if let Err(err) = print_stats(settings, &total_result, number_width) {
|
||||
show!(USimpleError::new(
|
||||
1,
|
||||
|
|
|
@ -464,3 +464,59 @@ fn test_files0_from_with_stdin_try_read_from_stdin() {
|
|||
.stderr_contains(MSG)
|
||||
.stdout_is("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_total_auto() {
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--total=auto"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=auto"])
|
||||
.run()
|
||||
.stdout_is(
|
||||
" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_total_always() {
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--total=always"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n 13 109 772 total\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=always"])
|
||||
.run()
|
||||
.stdout_is(
|
||||
" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 31 313 1887 total\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_total_never() {
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--total=never"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=never"])
|
||||
.run()
|
||||
.stdout_is(" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_total_only() {
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "--total=only"])
|
||||
.run()
|
||||
.stdout_is("13 109 772\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["lorem_ipsum.txt", "moby_dick.txt", "--total=only"])
|
||||
.run()
|
||||
.stdout_is("31 313 1887\n");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue