diff --git a/crates/nu-command/src/conversions/into/filesize.rs b/crates/nu-command/src/conversions/into/filesize.rs index b3c1e65a3b9..101a9fe6f01 100644 --- a/crates/nu-command/src/conversions/into/filesize.rs +++ b/crates/nu-command/src/conversions/into/filesize.rs @@ -138,6 +138,7 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { ), } } + fn int_from_string(a_string: &str, span: Span) -> Result { // Get the Locale so we know what the thousands separator is let locale = get_system_locale(); @@ -148,29 +149,35 @@ fn int_from_string(a_string: &str, span: Span) -> Result { let clean_string = no_comma_string.trim(); // Hadle negative file size - if let Some(stripped_string) = clean_string.strip_prefix('-') { - match stripped_string.parse::() { + if let Some(stripped_negative_string) = clean_string.strip_prefix('-') { + match stripped_negative_string.parse::() { Ok(n) => Ok(-(n.as_u64() as i64)), - Err(_) => Err(ShellError::CantConvert { - to_type: "int".into(), - from_type: "string".into(), - span, - help: None, - }), + 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) + } + _ => Err(string_convert_error(span)), } } else { match clean_string.parse::() { - Ok(n) => Ok(n.0 as i64), - Err(_) => Err(ShellError::CantConvert { - to_type: "int".into(), - from_type: "string".into(), - span, - help: None, - }), + Ok(n) => Ok(n.as_u64() as i64), + Err(_) => Err(string_convert_error(span)), } } } +fn string_convert_error(span: Span) -> ShellError { + ShellError::CantConvert { + to_type: "filesize".into(), + from_type: "string".into(), + span, + help: None, + } +} + #[cfg(test)] mod test { use super::*; diff --git a/crates/nu-command/tests/commands/into_filesize.rs b/crates/nu-command/tests/commands/into_filesize.rs index 2917e141dbe..d8ba88021c4 100644 --- a/crates/nu-command/tests/commands/into_filesize.rs +++ b/crates/nu-command/tests/commands/into_filesize.rs @@ -63,8 +63,57 @@ fn into_filesize_negative_filesize() { } #[test] -fn into_negative_filesize() { +fn into_filesize_negative_str_filesize() { + let actual = nu!("'-3kib' | into filesize"); + + assert!(actual.out.contains("-3.0 KiB")); +} + +#[test] +fn into_filesize_wrong_negative_str_filesize() { + let actual = nu!("'--3kib' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +} + +#[test] +fn into_filesize_negative_str() { let actual = nu!("'-1' | into filesize"); assert!(actual.out.contains("-1 B")); } + +#[test] +fn into_filesize_wrong_negative_str() { + let actual = nu!("'--1' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +} + +#[test] +fn into_filesize_positive_str_filesize() { + let actual = nu!("'+1Kib' | into filesize"); + + assert!(actual.out.contains("1.0 KiB")); +} + +#[test] +fn into_filesize_wrong_positive_str_filesize() { + let actual = nu!("'++1Kib' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +} + +#[test] +fn into_filesize_positive_str() { + let actual = nu!("'+1' | into filesize"); + + assert!(actual.out.contains("1 B")); +} + +#[test] +fn into_filesize_wrong_positive_str() { + let actual = nu!("'++1' | into filesize"); + + assert!(actual.err.contains("can't convert string to filesize")); +}