From fb1846120d54f31db687eb4f9c88a57534a03a3c Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Wed, 3 Feb 2021 07:19:38 -0600 Subject: [PATCH] standardize on how to get file size (#2992) * standardize on how to get file size * forgot to remove comment * make specified size lowercase * fix the test due to precision * added another test * Update README.md add contributors graphic * clippy - test adjustment * tweaked matching --- README.md | 1 - .../src/commands/format/format_filesize.rs | 114 ++++-------------- crates/nu-command/src/commands/str_/from.rs | 2 +- crates/nu-command/tests/commands/format.rs | 31 ++++- crates/nu-data/src/base/shape.rs | 20 +-- 5 files changed, 65 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index 502c29cfc..d0279ec81 100644 --- a/README.md +++ b/README.md @@ -318,7 +318,6 @@ Thanks to all the people who already contributed! - ## License The project is made available under the MIT license. See the `LICENSE` file for more information. diff --git a/crates/nu-command/src/commands/format/format_filesize.rs b/crates/nu-command/src/commands/format/format_filesize.rs index 2b2f0a4dc..e87a0d90f 100644 --- a/crates/nu-command/src/commands/format/format_filesize.rs +++ b/crates/nu-command/src/commands/format/format_filesize.rs @@ -1,16 +1,13 @@ use crate::prelude::*; -use nu_errors::ShellError; - +use nu_data::base::shape::InlineShape; use nu_engine::WholeStreamCommand; +use nu_errors::ShellError; use nu_protocol::{ - ColumnPath, Primitive::Filesize, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, - UntaggedValue::Primitive, Value, + ColumnPath, Primitive::Filesize, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value, }; use nu_source::Tagged; use nu_value_ext::get_data_by_column_path; -use num_format::{Locale, ToFormattedString}; - pub struct FileSize; #[derive(Deserialize)] @@ -71,12 +68,25 @@ async fn process_row( Ok({ let replace_for = get_data_by_column_path(&input, &field, move |_, _, error| error); match replace_for { - Ok(s) => match convert_bytes_to_string_using_format(s, format) { - Ok(b) => OutputStream::one(ReturnSuccess::value( - input.replace_data_at_column_path(&field, b).expect("Given that the existence check was already done, this shouldn't trigger never"), - )), - Err(e) => OutputStream::one(Err(e)), - }, + Ok(s) => { + if let Value { + value: UntaggedValue::Primitive(Filesize(fs)), + .. + } = s + { + let byte_format = InlineShape::format_bytes(&fs, Some(&format.item)); + let byte_value = Value::from(byte_format.1); + OutputStream::one(ReturnSuccess::value( + input.replace_data_at_column_path(&field, byte_value).expect("Given that the existence check was already done, this shouldn't trigger never"), + )) + } else { + return Err(ShellError::labeled_error( + "the data in this row is not of the type filesize", + "invalid datatype in row", + input.tag(), + )); + } + } Err(e) => OutputStream::one(Err(e)), } }) @@ -102,86 +112,6 @@ async fn filesize(raw_args: CommandArgs) -> Result { .to_output_stream()) } -fn convert_bytes_to_string_using_format( - bytes: Value, - format: Tagged, -) -> Result { - match bytes.value { - Primitive(Filesize(b)) => { - if let Some(value) = b.to_u128() { - let byte = byte_unit::Byte::from_bytes(value); - let value = match format.item().to_lowercase().as_str() { - "b" => Ok(UntaggedValue::string( - value.to_formatted_string(&Locale::en), - )), - "kb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::KB).to_string(), - )), - "kib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::KiB).to_string(), - )), - "mb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::MB).to_string(), - )), - "mib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::MiB).to_string(), - )), - "gb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::GB).to_string(), - )), - "gib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::GiB).to_string(), - )), - "tb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::TB).to_string(), - )), - "tib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::TiB).to_string(), - )), - "pb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::PB).to_string(), - )), - "pib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::PiB).to_string(), - )), - "eb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::EB).to_string(), - )), - "eib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::EiB).to_string(), - )), - "zb" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::ZB).to_string(), - )), - "zib" => Ok(UntaggedValue::string( - byte.get_adjusted_unit(byte_unit::ByteUnit::ZiB).to_string(), - )), - _ => Err(ShellError::labeled_error( - format!("Invalid format code: {:}", format.item()), - "invalid format", - format.tag(), - )), - }; - match value { - Ok(b) => Ok(Value { value: b, ..bytes }), - Err(e) => Err(e), - } - } else { - Err(ShellError::labeled_error( - "Value too large to fit in 128 bits", - "value too large to fit in format", - format.span(), - )) - } - } - _ => Err(ShellError::labeled_error( - "the data in this row is not of the type filesize", - "invalid row type", - bytes.tag(), - )), - } -} - #[cfg(test)] mod tests { use super::FileSize; diff --git a/crates/nu-command/src/commands/str_/from.rs b/crates/nu-command/src/commands/str_/from.rs index de707d230..4498a35ad 100644 --- a/crates/nu-command/src/commands/str_/from.rs +++ b/crates/nu-command/src/commands/str_/from.rs @@ -132,7 +132,7 @@ pub fn action( Primitive::Date(a_date) => a_date.format("%c").to_string(), Primitive::FilePath(a_filepath) => a_filepath.as_path().display().to_string(), Primitive::Filesize(a_filesize) => { - let byte_string = InlineShape::format_bytes(a_filesize); + let byte_string = InlineShape::format_bytes(a_filesize, None); byte_string.1 } _ => { diff --git a/crates/nu-command/tests/commands/format.rs b/crates/nu-command/tests/commands/format.rs index 9db8b8152..d3b585ecf 100644 --- a/crates/nu-command/tests/commands/format.rs +++ b/crates/nu-command/tests/commands/format.rs @@ -1,4 +1,4 @@ -use nu_test_support::fs::Stub::EmptyFile; +use nu_test_support::fs::Stub::{EmptyFile, FileWithContentToBeTrimmed}; use nu_test_support::playground::Playground; use nu_test_support::{nu, pipeline}; @@ -61,6 +61,33 @@ fn format_filesize_works() { "# )); - assert_eq!(actual.out, "0.01 KB"); + assert_eq!(actual.out, "0.0 KB"); }) } + +#[test] +fn format_filesize_works_with_nonempty_files() { + Playground::setup( + "format_filesize_works_with_nonempty_files", + |dirs, sandbox| { + sandbox.with_files(vec![FileWithContentToBeTrimmed( + "sample.toml", + r#" + [dependency] + name = "nu" + "#, + )]); + + let actual = nu!( + cwd: dirs.test(), + "ls sample.toml | format filesize size B | get size | first" + ); + + #[cfg(not(windows))] + assert_eq!(actual.out, "25"); + + #[cfg(windows)] + assert_eq!(actual.out, "27"); + }, + ) +} diff --git a/crates/nu-data/src/base/shape.rs b/crates/nu-data/src/base/shape.rs index 54b9cd3e1..5d04f8288 100644 --- a/crates/nu-data/src/base/shape.rs +++ b/crates/nu-data/src/base/shape.rs @@ -128,15 +128,21 @@ impl InlineShape { } } - pub fn format_bytes(bytesize: &BigInt) -> (DbgDocBldr, String) { + pub fn format_bytes(bytesize: &BigInt, forced_format: Option<&str>) -> (DbgDocBldr, String) { use bigdecimal::ToPrimitive; // get the config value, if it doesn't exist make it 'auto' so it works how it originally did - let filesize_format_var = crate::config::config(Tag::unknown()) - .expect("unable to get the config.toml file") - .get("filesize_format") - .map(|val| val.convert_to_string().to_ascii_lowercase()) - .unwrap_or_else(|| "auto".to_string()); + let filesize_format_var; + if let Some(fmt) = forced_format { + filesize_format_var = fmt.to_ascii_lowercase(); + } else { + filesize_format_var = crate::config::config(Tag::unknown()) + .expect("unable to get the config.toml file") + .get("filesize_format") + .map(|val| val.convert_to_string().to_ascii_lowercase()) + .unwrap_or_else(|| "auto".to_string()); + } + // if there is a value, match it to one of the valid values for byte units let filesize_format = match filesize_format_var.as_str() { "b" => (byte_unit::ByteUnit::B, ""), @@ -233,7 +239,7 @@ impl PrettyDebug for FormatInlineShape { + right.clone().format().pretty() } InlineShape::Bytesize(bytesize) => { - let bytes = InlineShape::format_bytes(bytesize); + let bytes = InlineShape::format_bytes(bytesize, None); bytes.0 } InlineShape::String(string) => DbgDocBldr::primitive(string),