diff --git a/crates/nu-command/src/conversions/into/filesize.rs b/crates/nu-command/src/conversions/into/filesize.rs index 101a9fe6f0..010c031b2a 100644 --- a/crates/nu-command/src/conversions/into/filesize.rs +++ b/crates/nu-command/src/conversions/into/filesize.rs @@ -122,7 +122,7 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { Value::Filesize { .. } => input.clone(), Value::Int { val, .. } => Value::filesize(*val, value_span), Value::Float { val, .. } => Value::filesize(*val as i64, value_span), - Value::String { val, .. } => match int_from_string(val, value_span) { + Value::String { val, .. } => match i64_from_string(val, value_span) { Ok(val) => Value::filesize(val, value_span), Err(error) => Value::error(error, value_span), }, @@ -139,7 +139,7 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { } } -fn int_from_string(a_string: &str, span: Span) -> Result { +fn i64_from_string(a_string: &str, span: Span) -> Result { // Get the Locale so we know what the thousands separator is let locale = get_system_locale(); @@ -151,24 +151,35 @@ fn int_from_string(a_string: &str, span: Span) -> Result { // Hadle negative file size if let Some(stripped_negative_string) = clean_string.strip_prefix('-') { match stripped_negative_string.parse::() { - Ok(n) => Ok(-(n.as_u64() as i64)), + Ok(n) => i64_from_byte_size(n, true, span), Err(_) => Err(string_convert_error(span)), } } else if let Some(stripped_positive_string) = clean_string.strip_prefix('+') { match stripped_positive_string.parse::() { Ok(n) if stripped_positive_string.starts_with(|c: char| c.is_ascii_digit()) => { - Ok(n.as_u64() as i64) + i64_from_byte_size(n, false, span) } _ => Err(string_convert_error(span)), } } else { match clean_string.parse::() { - Ok(n) => Ok(n.as_u64() as i64), + Ok(n) => i64_from_byte_size(n, false, span), Err(_) => Err(string_convert_error(span)), } } } +fn i64_from_byte_size( + byte_size: bytesize::ByteSize, + is_negative: bool, + span: Span, +) -> Result { + match i64::try_from(byte_size.as_u64()) { + Ok(n) => Ok(if is_negative { -n } else { n }), + Err(_) => Err(string_convert_error(span)), + } +} + fn string_convert_error(span: Span) -> ShellError { ShellError::CantConvert { to_type: "filesize".into(), diff --git a/crates/nu-command/tests/commands/into_filesize.rs b/crates/nu-command/tests/commands/into_filesize.rs index d8ba88021c..6a72c76b5d 100644 --- a/crates/nu-command/tests/commands/into_filesize.rs +++ b/crates/nu-command/tests/commands/into_filesize.rs @@ -76,6 +76,13 @@ fn into_filesize_wrong_negative_str_filesize() { assert!(actual.err.contains("can't convert string to filesize")); } +#[test] +fn into_filesize_large_negative_str_filesize() { + let actual = nu!("'-10000PiB' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +} + #[test] fn into_filesize_negative_str() { let actual = nu!("'-1' | into filesize"); @@ -104,6 +111,13 @@ fn into_filesize_wrong_positive_str_filesize() { assert!(actual.err.contains("can't convert string to filesize")); } +#[test] +fn into_filesize_large_positive_str_filesize() { + let actual = nu!("'+10000PiB' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +} + #[test] fn into_filesize_positive_str() { let actual = nu!("'+1' | into filesize");