diff --git a/crates/nu-command/src/commands/into_int.rs b/crates/nu-command/src/commands/into_int.rs index 782554e2ba..2902ef61a3 100644 --- a/crates/nu-command/src/commands/into_int.rs +++ b/crates/nu-command/src/commands/into_int.rs @@ -31,11 +31,18 @@ impl WholeStreamCommand for IntoInt { } fn examples(&self) -> Vec { - vec![Example { - description: "Convert filesize to integer", - example: "into-int 1kb | each { = $it / 1024 }", - result: Some(vec![UntaggedValue::int(1).into()]), - }] + vec![ + Example { + description: "Convert filesize to integer", + example: "into-int 1kb | each { = $it / 1000 }", + result: Some(vec![UntaggedValue::int(1).into()]), + }, + Example { + description: "Convert filesize to integer", + example: "into-int 1kib | each { = $it / 1024 }", + result: Some(vec![UntaggedValue::int(1).into()]), + }, + ] } } diff --git a/crates/nu-command/tests/commands/into_int.rs b/crates/nu-command/tests/commands/into_int.rs index a604aa7ce0..6f7c755d89 100644 --- a/crates/nu-command/tests/commands/into_int.rs +++ b/crates/nu-command/tests/commands/into_int.rs @@ -5,7 +5,19 @@ fn into_int_filesize() { let actual = nu!( cwd: ".", pipeline( r#" - into-int 1kb | each {= $it / 1024 } + into-int 1kb | each {= $it / 1000 } + "# + )); + + assert!(actual.out.contains('1')); +} + +#[test] +fn into_int_filesize2() { + let actual = nu!( + cwd: ".", pipeline( + r#" + into-int 1kib | each {= $it / 1024 } "# )); diff --git a/crates/nu-command/tests/commands/where_.rs b/crates/nu-command/tests/commands/where_.rs index b389f7e0f2..16126cac6c 100644 --- a/crates/nu-command/tests/commands/where_.rs +++ b/crates/nu-command/tests/commands/where_.rs @@ -7,7 +7,7 @@ use nu_test_support::pipeline; fn filters_by_unit_size_comparison() { let actual = nu!( cwd: "tests/fixtures/formats", - "ls | where size > 1kb | sort-by size | get name | first 1 | str trim" + "ls | where size > 1kib | sort-by size | get name | first 1 | str trim" ); assert_eq!(actual.out, "cargo_sample.toml"); diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index 3054734e91..8652211951 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -332,6 +332,9 @@ fn parse_unit(lite_arg: &Spanned) -> (SpannedExpression, Option Result<(), ParseError> { value: 27, unit: Unit::Petabyte, }, + TestCase { + string: String::from("10kib"), + value: 10, + unit: Unit::Kibibyte, + }, + TestCase { + string: String::from("123KiB"), + value: 123, + unit: Unit::Kibibyte, + }, + TestCase { + string: String::from("24kiB"), + value: 24, + unit: Unit::Kibibyte, + }, + TestCase { + string: String::from("10mib"), + value: 10, + unit: Unit::Mebibyte, + }, + TestCase { + string: String::from("123MiB"), + value: 123, + unit: Unit::Mebibyte, + }, + TestCase { + string: String::from("10gib"), + value: 10, + unit: Unit::Gibibyte, + }, + TestCase { + string: String::from("123GiB"), + value: 123, + unit: Unit::Gibibyte, + }, ]; for case in cases.iter() { diff --git a/crates/nu-protocol/src/hir.rs b/crates/nu-protocol/src/hir.rs index 0dcf62bf17..1c3a4b44b0 100644 --- a/crates/nu-protocol/src/hir.rs +++ b/crates/nu-protocol/src/hir.rs @@ -346,7 +346,7 @@ impl HasSpan for ExternalCommand { #[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash, Copy, Deserialize, Serialize)] pub enum Unit { - // Filesize units + // Filesize units: metric Byte, Kilobyte, Megabyte, @@ -354,6 +354,11 @@ pub enum Unit { Terabyte, Petabyte, + // Filesize units: ISO/IEC 80000 + Kibibyte, + Mebibyte, + Gibibyte, + // Duration units Nanosecond, Microsecond, @@ -540,6 +545,9 @@ impl Unit { Unit::Gigabyte => "GB", Unit::Terabyte => "TB", Unit::Petabyte => "PB", + Unit::Kibibyte => "KiB", + Unit::Mebibyte => "MiB", + Unit::Gibibyte => "GiB", Unit::Nanosecond => "ns", Unit::Microsecond => "us", Unit::Millisecond => "ms", @@ -558,13 +566,18 @@ impl Unit { match self { Unit::Byte => filesize(convert_number_to_u64(&size)), - Unit::Kilobyte => filesize(convert_number_to_u64(&size) * 1024), - Unit::Megabyte => filesize(convert_number_to_u64(&size) * 1024 * 1024), - Unit::Gigabyte => filesize(convert_number_to_u64(&size) * 1024 * 1024 * 1024), - Unit::Terabyte => filesize(convert_number_to_u64(&size) * 1024 * 1024 * 1024 * 1024), + Unit::Kilobyte => filesize(convert_number_to_u64(&size) * 1000), + Unit::Megabyte => filesize(convert_number_to_u64(&size) * 1000 * 1000), + Unit::Gigabyte => filesize(convert_number_to_u64(&size) * 1000 * 1000 * 1000), + Unit::Terabyte => filesize(convert_number_to_u64(&size) * 1000 * 1000 * 1000 * 1000), Unit::Petabyte => { - filesize(convert_number_to_u64(&size) * 1024 * 1024 * 1024 * 1024 * 1024) + filesize(convert_number_to_u64(&size) * 1000 * 1000 * 1000 * 1000 * 1000) } + + Unit::Kibibyte => filesize(convert_number_to_u64(&size) * 1024), + Unit::Mebibyte => filesize(convert_number_to_u64(&size) * 1024 * 1024), + Unit::Gibibyte => filesize(convert_number_to_u64(&size) * 1024 * 1024 * 1024), + Unit::Nanosecond => duration(size.to_bigint().expect("Conversion should never fail.")), Unit::Microsecond => { duration(size.to_bigint().expect("Conversion should never fail.") * 1000) diff --git a/crates/nu-protocol/src/value/value_structure.rs b/crates/nu-protocol/src/value/value_structure.rs index 45c76122e2..65ee41b057 100644 --- a/crates/nu-protocol/src/value/value_structure.rs +++ b/crates/nu-protocol/src/value/value_structure.rs @@ -3,7 +3,10 @@ use nu_errors::ShellError; use std::path::{Component, Path, PathBuf}; fn is_value_tagged_dir(value: &Value) -> bool { - matches!(&value.value, UntaggedValue::Row(_) | UntaggedValue::Table(_)) + matches!( + &value.value, + UntaggedValue::Row(_) | UntaggedValue::Table(_) + ) } #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] diff --git a/tests/shell/pipeline/commands/internal.rs b/tests/shell/pipeline/commands/internal.rs index 1270276831..31833c8b8c 100644 --- a/tests/shell/pipeline/commands/internal.rs +++ b/tests/shell/pipeline/commands/internal.rs @@ -759,7 +759,9 @@ fn filesize_math() { "# ); - assert_eq!(actual.out, "1.0 MB"); + assert_eq!(actual.out, "1000.0 KB"); + // why 1000.0 KB instead of 1.0 MB? + // looks like `byte.get_appropriate_unit(false)` behaves this way } #[test] @@ -783,7 +785,7 @@ fn filesize_math3() { "# ); - assert_eq!(actual.out, "10.2 KB"); + assert_eq!(actual.out, "10.0 KB"); } #[test] fn filesize_math4() { @@ -794,7 +796,43 @@ fn filesize_math4() { "# ); - assert_eq!(actual.out, "512.0 KB"); + assert_eq!(actual.out, "500.0 KB"); +} + +#[test] +fn filesize_math5() { + let actual = nu!( + cwd: ".", + r#" + = 1001 * 1kb + "# + ); + + assert_eq!(actual.out, "1.0 MB"); +} + +#[test] +fn filesize_math6() { + let actual = nu!( + cwd: ".", + r#" + = 1001 * 1mb + "# + ); + + assert_eq!(actual.out, "1.0 GB"); +} + +#[test] +fn filesize_math7() { + let actual = nu!( + cwd: ".", + r#" + = 1001 * 1gb + "# + ); + + assert_eq!(actual.out, "1.0 TB"); } #[test]