mirror of
https://github.com/nushell/nushell
synced 2024-11-15 01:17:07 +00:00
nu-parser + nu-protocol: switch to metric for KB, MB, GB, add KiB, MiB, GiB units (#3035)
fixes inconsistency with formatting/rendering which uses standard Rust byte_unit https://en.wikipedia.org/wiki/Byte#Multiple-byte_units
This commit is contained in:
parent
3443ca40c5
commit
b403fb1275
7 changed files with 128 additions and 17 deletions
|
@ -31,11 +31,18 @@ impl WholeStreamCommand for IntoInt {
|
|||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
vec![
|
||||
Example {
|
||||
description: "Convert filesize to integer",
|
||||
example: "into-int 1kb | each { = $it / 1024 }",
|
||||
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()]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
"#
|
||||
));
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -332,6 +332,9 @@ fn parse_unit(lite_arg: &Spanned<String>) -> (SpannedExpression, Option<ParseErr
|
|||
(Unit::Gigabyte, vec!["gb", "GB", "Gb", "gB"]),
|
||||
(Unit::Terabyte, vec!["tb", "TB", "Tb", "tB"]),
|
||||
(Unit::Petabyte, vec!["pb", "PB", "Pb", "pB"]),
|
||||
(Unit::Kibibyte, vec!["KiB", "kib", "kiB", "Kib"]),
|
||||
(Unit::Mebibyte, vec!["MiB", "mib", "miB", "Mib"]),
|
||||
(Unit::Gibibyte, vec!["GiB", "gib", "giB", "Gib"]),
|
||||
(Unit::Nanosecond, vec!["ns"]),
|
||||
(Unit::Microsecond, vec!["us"]),
|
||||
(Unit::Millisecond, vec!["ms"]),
|
||||
|
@ -2215,6 +2218,41 @@ fn unit_parse_byte_units() -> 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() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in a new issue