From af5919e466f41e28ae7090c499d3b996c025e12e Mon Sep 17 00:00:00 2001 From: Sebastian Holgersson Date: Sat, 1 Jan 2022 21:44:11 +0100 Subject: [PATCH 1/3] numfmt: implement missing --suffix option adds support for the --suffix option from issue #1280. --- src/uu/numfmt/src/format.rs | 26 ++++++++++++--- src/uu/numfmt/src/numfmt.rs | 12 +++++++ src/uu/numfmt/src/options.rs | 2 ++ tests/by-util/test_numfmt.rs | 64 ++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/uu/numfmt/src/format.rs b/src/uu/numfmt/src/format.rs index aa90f7936..42f7d45bf 100644 --- a/src/uu/numfmt/src/format.rs +++ b/src/uu/numfmt/src/format.rs @@ -220,16 +220,34 @@ fn format_string( options: &NumfmtOptions, implicit_padding: Option, ) -> Result { + // strip the (optional) suffix before applying any transformation + let source_without_suffix = if let Some(suffix) = &options.suffix { + source.strip_suffix(suffix).unwrap_or(source) + } else { + source + }; + let number = transform_to( - transform_from(source, &options.transform.from)?, + transform_from(source_without_suffix, &options.transform.from)?, &options.transform.to, options.round, )?; + // bring back the suffix before applying padding + let number_with_suffix = if let Some(suffix) = &options.suffix { + format!("{}{}", number, suffix) + } else { + number + }; + Ok(match implicit_padding.unwrap_or(options.padding) { - 0 => number, - p if p > 0 => format!("{:>padding$}", number, padding = p as usize), - p => format!("{: number_with_suffix, + p if p > 0 => format!("{:>padding$}", number_with_suffix, padding = p as usize), + p => format!( + "{: Result { _ => unreachable!("Should be restricted by clap"), }; + let suffix = args.value_of(options::SUFFIX).map(|s| s.to_owned()); + Ok(NumfmtOptions { transform, padding, @@ -149,6 +151,7 @@ fn parse_options(args: &ArgMatches) -> Result { fields, delimiter, round, + suffix, }) } @@ -242,5 +245,14 @@ pub fn uu_app() -> App<'static, 'static> { .default_value("from-zero") .possible_values(&["up", "down", "from-zero", "towards-zero", "nearest"]), ) + .arg( + Arg::with_name(options::SUFFIX) + .long(options::SUFFIX) + .help( + "print SUFFIX after each formatted number, and accept \ + inputs optionally ending with SUFFIX", + ) + .value_name("SUFFIX"), + ) .arg(Arg::with_name(options::NUMBER).hidden(true).multiple(true)) } diff --git a/src/uu/numfmt/src/options.rs b/src/uu/numfmt/src/options.rs index 59bf9d8d3..bd76b18b8 100644 --- a/src/uu/numfmt/src/options.rs +++ b/src/uu/numfmt/src/options.rs @@ -11,6 +11,7 @@ pub const HEADER_DEFAULT: &str = "1"; pub const NUMBER: &str = "NUMBER"; pub const PADDING: &str = "padding"; pub const ROUND: &str = "round"; +pub const SUFFIX: &str = "suffix"; pub const TO: &str = "to"; pub const TO_DEFAULT: &str = "none"; @@ -26,6 +27,7 @@ pub struct NumfmtOptions { pub fields: Vec, pub delimiter: Option, pub round: RoundMethod, + pub suffix: Option, } #[derive(Clone, Copy)] diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index 336b0f7cd..9043eb541 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -505,3 +505,67 @@ fn test_round() { .stdout_only(exp.join("\n") + "\n"); } } + +#[test] +fn test_suffix_is_added_if_not_supplied() { + new_ucmd!() + .args(&["--suffix=TEST"]) + .pipe_in("1000") + .succeeds() + .stdout_only("1000TEST\n"); +} + +#[test] +fn test_suffix_is_preserved() { + new_ucmd!() + .args(&["--suffix=TEST"]) + .pipe_in("1000TEST") + .succeeds() + .stdout_only("1000TEST\n"); +} + +#[test] +fn test_suffix_is_only_applied_to_selected_field() { + new_ucmd!() + .args(&["--suffix=TEST", "--field=2"]) + .pipe_in("1000 2000 3000") + .succeeds() + .stdout_only("1000 2000TEST 3000\n"); +} + +#[test] +fn test_transform_with_suffix_on_input() { + new_ucmd!() + .args(&["--suffix=TEST", "--to=si"]) + .pipe_in("2000TEST") + .succeeds() + .stdout_only("2.0KTEST\n"); +} + +#[test] +fn test_transform_without_suffix_on_input() { + new_ucmd!() + .args(&["--suffix=TEST", "--to=si"]) + .pipe_in("2000") + .succeeds() + .stdout_only("2.0KTEST\n"); +} + +#[test] +fn test_transform_with_suffix_and_delimiter() { + new_ucmd!() + .args(&["--suffix=mysuffix", "--to=si", "-d=|"]) + .pipe_in("1000mysuffix|2000|3000") + .succeeds() + .stdout_only("1.0Kmysuffix|2000|3000\n"); +} + +#[test] +fn test_suffix_with_padding() { + new_ucmd!() + .args(&["--suffix=padme", "--padding=12"]) + .pipe_in("1000 2000 3000") + .succeeds() + .stdout_only(" 1000padme 2000 3000\n"); +} + From 84798a520ea9c92519b81ff971734bea7e6c12f2 Mon Sep 17 00:00:00 2001 From: Sebastian Holgersson Date: Sat, 1 Jan 2022 22:55:50 +0100 Subject: [PATCH 2/3] numfmt: fix spelling and formatting issues in tests --- tests/by-util/test_numfmt.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index 9043eb541..596aab6ba 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -536,36 +536,35 @@ fn test_suffix_is_only_applied_to_selected_field() { #[test] fn test_transform_with_suffix_on_input() { new_ucmd!() - .args(&["--suffix=TEST", "--to=si"]) - .pipe_in("2000TEST") + .args(&["--suffix=b", "--to=si"]) + .pipe_in("2000b") .succeeds() - .stdout_only("2.0KTEST\n"); + .stdout_only("2.0Kb\n"); } #[test] fn test_transform_without_suffix_on_input() { new_ucmd!() - .args(&["--suffix=TEST", "--to=si"]) + .args(&["--suffix=b", "--to=si"]) .pipe_in("2000") .succeeds() - .stdout_only("2.0KTEST\n"); + .stdout_only("2.0Kb\n"); } #[test] fn test_transform_with_suffix_and_delimiter() { new_ucmd!() - .args(&["--suffix=mysuffix", "--to=si", "-d=|"]) - .pipe_in("1000mysuffix|2000|3000") + .args(&["--suffix=b", "--to=si", "-d=|"]) + .pipe_in("1000b|2000|3000") .succeeds() - .stdout_only("1.0Kmysuffix|2000|3000\n"); + .stdout_only("1.0Kb|2000|3000\n"); } #[test] fn test_suffix_with_padding() { new_ucmd!() - .args(&["--suffix=padme", "--padding=12"]) + .args(&["--suffix=pad", "--padding=12"]) .pipe_in("1000 2000 3000") .succeeds() - .stdout_only(" 1000padme 2000 3000\n"); + .stdout_only(" 1000pad 2000 3000\n"); } - From a3895bba595149922bd7aaef9783f0f7bd9d9513 Mon Sep 17 00:00:00 2001 From: Sebastian Holgersson Date: Sun, 2 Jan 2022 02:16:59 +0100 Subject: [PATCH 3/3] numfmt: replace if let with simpler match --- src/uu/numfmt/src/format.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/uu/numfmt/src/format.rs b/src/uu/numfmt/src/format.rs index 42f7d45bf..f66e1ac0a 100644 --- a/src/uu/numfmt/src/format.rs +++ b/src/uu/numfmt/src/format.rs @@ -221,10 +221,9 @@ fn format_string( implicit_padding: Option, ) -> Result { // strip the (optional) suffix before applying any transformation - let source_without_suffix = if let Some(suffix) = &options.suffix { - source.strip_suffix(suffix).unwrap_or(source) - } else { - source + let source_without_suffix = match &options.suffix { + Some(suffix) => source.strip_suffix(suffix).unwrap_or(source), + None => source, }; let number = transform_to( @@ -234,10 +233,9 @@ fn format_string( )?; // bring back the suffix before applying padding - let number_with_suffix = if let Some(suffix) = &options.suffix { - format!("{}{}", number, suffix) - } else { - number + let number_with_suffix = match &options.suffix { + Some(suffix) => format!("{}{}", number, suffix), + None => number, }; Ok(match implicit_padding.unwrap_or(options.padding) {