mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
wc: implement --total
This commit is contained in:
parent
5d0f0144c1
commit
0fa08757fa
2 changed files with 125 additions and 14 deletions
|
@ -42,6 +42,7 @@ struct Settings {
|
||||||
show_max_line_length: bool,
|
show_max_line_length: bool,
|
||||||
files0_from_stdin_mode: bool,
|
files0_from_stdin_mode: bool,
|
||||||
title_quoting_style: QuotingStyle,
|
title_quoting_style: QuotingStyle,
|
||||||
|
total_when: TotalWhen,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
@ -65,6 +66,7 @@ impl Settings {
|
||||||
show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH),
|
show_max_line_length: matches.get_flag(options::MAX_LINE_LENGTH),
|
||||||
files0_from_stdin_mode,
|
files0_from_stdin_mode,
|
||||||
title_quoting_style,
|
title_quoting_style,
|
||||||
|
total_when: matches.get_one::<String>(options::TOTAL).unwrap().into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if settings.show_bytes
|
if settings.show_bytes
|
||||||
|
@ -84,6 +86,7 @@ impl Settings {
|
||||||
show_max_line_length: false,
|
show_max_line_length: false,
|
||||||
files0_from_stdin_mode,
|
files0_from_stdin_mode,
|
||||||
title_quoting_style: settings.title_quoting_style,
|
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 FILES0_FROM: &str = "files0-from";
|
||||||
pub static LINES: &str = "lines";
|
pub static LINES: &str = "lines";
|
||||||
pub static MAX_LINE_LENGTH: &str = "max-line-length";
|
pub static MAX_LINE_LENGTH: &str = "max-line-length";
|
||||||
|
pub static TOTAL: &str = "total";
|
||||||
pub static WORDS: &str = "words";
|
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)]
|
#[derive(Debug)]
|
||||||
enum WcError {
|
enum WcError {
|
||||||
FilesDisabled(String),
|
FilesDisabled(String),
|
||||||
|
@ -246,6 +281,15 @@ pub fn uu_app() -> Command {
|
||||||
.help("print the length of the longest line")
|
.help("print the length of the longest line")
|
||||||
.action(ArgAction::SetTrue),
|
.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(
|
||||||
Arg::new(options::WORDS)
|
Arg::new(options::WORDS)
|
||||||
.short('w')
|
.short('w')
|
||||||
|
@ -561,11 +605,19 @@ fn compute_number_width(inputs: &[Input], settings: &Settings) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
||||||
let number_width = compute_number_width(inputs, settings);
|
|
||||||
|
|
||||||
let mut total_word_count = WordCount::default();
|
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 {
|
for input in inputs {
|
||||||
let word_count = match word_count_from_input(input, settings) {
|
let word_count = match word_count_from_input(input, settings) {
|
||||||
|
@ -595,6 +647,8 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
||||||
};
|
};
|
||||||
total_word_count += word_count;
|
total_word_count += word_count;
|
||||||
let result = word_count.with_title(input.to_title(&settings.title_quoting_style));
|
let result = word_count.with_title(input.to_title(&settings.title_quoting_style));
|
||||||
|
|
||||||
|
if are_stats_visible {
|
||||||
if let Err(err) = print_stats(settings, &result, number_width) {
|
if let Err(err) = print_stats(settings, &result, number_width) {
|
||||||
show!(USimpleError::new(
|
show!(USimpleError::new(
|
||||||
1,
|
1,
|
||||||
|
@ -606,9 +660,10 @@ fn wc(inputs: &[Input], settings: &Settings) -> UResult<()> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if num_inputs > 1 {
|
if is_total_row_visible {
|
||||||
let total_result = total_word_count.with_title(Some(String::from("total")));
|
let total_result = total_word_count.with_title(total_row_title);
|
||||||
if let Err(err) = print_stats(settings, &total_result, number_width) {
|
if let Err(err) = print_stats(settings, &total_result, number_width) {
|
||||||
show!(USimpleError::new(
|
show!(USimpleError::new(
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -464,3 +464,59 @@ fn test_files0_from_with_stdin_try_read_from_stdin() {
|
||||||
.stderr_contains(MSG)
|
.stderr_contains(MSG)
|
||||||
.stdout_is("");
|
.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…
Add table
Add a link
Reference in a new issue