diff --git a/crates/nu-command/tests/commands/into_filesize.rs b/crates/nu-command/tests/commands/into_filesize.rs index 40edb39e94..710abcbb0b 100644 --- a/crates/nu-command/tests/commands/into_filesize.rs +++ b/crates/nu-command/tests/commands/into_filesize.rs @@ -74,3 +74,15 @@ fn into_filesize_filesize() { assert!(actual.out.contains("3.0 KiB")); } + +#[test] +fn into_filesize_negative_filesize() { + let actual = nu!( + cwd: ".", pipeline( + r#" + -3kib | into filesize + "# + )); + + assert!(actual.out.contains("-3.0 KiB")); +} diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 60ee3762df..5b5c8a519a 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -3089,7 +3089,7 @@ pub fn format_filesize(num_bytes: i64, format_value: &str, filesize_metric: bool // Allow the user to specify how they want their numbers formatted let filesize_format_var = get_filesize_format(format_value, filesize_metric); - let byte = byte_unit::Byte::from_bytes(num_bytes as u128); + let byte = byte_unit::Byte::from_bytes(num_bytes.unsigned_abs() as u128); let adj_byte = if filesize_format_var.0 == byte_unit::ByteUnit::B && filesize_format_var.1 == "auto" { byte.get_appropriate_unit(!filesize_metric) @@ -3102,14 +3102,25 @@ pub fn format_filesize(num_bytes: i64, format_value: &str, filesize_metric: bool let locale = get_system_locale(); let locale_byte = adj_byte.get_value() as u64; let locale_byte_string = locale_byte.to_formatted_string(&locale); - - if filesize_format_var.1 == "auto" { - format!("{} B", locale_byte_string) + let locale_signed_byte_string = if num_bytes.is_negative() { + format!("-{}", locale_byte_string) } else { locale_byte_string + }; + + if filesize_format_var.1 == "auto" { + format!("{} B", locale_signed_byte_string) + } else { + locale_signed_byte_string + } + } + _ => { + if num_bytes.is_negative() { + format!("-{}", adj_byte.format(1)) + } else { + adj_byte.format(1) } } - _ => adj_byte.format(1), } } diff --git a/src/tests/test_math.rs b/src/tests/test_math.rs index 75e1f8546e..b93246c1e9 100644 --- a/src/tests/test_math.rs +++ b/src/tests/test_math.rs @@ -104,3 +104,8 @@ fn floating_add() -> TestResult { fn precedence_of_or_groups() -> TestResult { run_test(r#"4 mod 3 == 0 || 5 mod 5 == 0"#, "true") } + +#[test] +fn test_filesize_op() -> TestResult { + run_test("-5kb + 4kb", "-1,000 B") +}