From 079550d7d98ae5683d35fa612362af876113333d Mon Sep 17 00:00:00 2001 From: Phil Gebhardt Date: Mon, 29 Jul 2024 14:19:42 -0700 Subject: [PATCH] add support for nano and micro --- src/parser.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/scale.rs | 6 ++++++ src/utils.rs | 4 ++++ 3 files changed, 60 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 63880c6..0ad9100 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -95,6 +95,8 @@ fn parse_suffix(input: &str) -> IResult<&str, (Format, Scale)> { tag("Ti"), tag("Pi"), tag("Ei"), + tag("n"), + tag("u"), tag("m"), tag("k"), tag("M"), @@ -114,6 +116,8 @@ fn parse_suffix(input: &str) -> IResult<&str, (Format, Scale)> { "Pi" => (Format::BinarySI, Scale::Peta), "Ei" => (Format::BinarySI, Scale::Exa), // + "n" => (Format::DecimalSI, Scale::Nano), + "u" => (Format::DecimalSI, Scale::Micro), "m" => (Format::DecimalSI, Scale::Milli), "" => (Format::DecimalSI, Scale::One), "k" => (Format::DecimalSI, Scale::Kilo), @@ -202,6 +206,32 @@ mod tests { assert_eq!(quantity.to_string(), "0".to_owned()); } + #[test] + fn test_nano_quantity() { + let quantity = parse_quantity_string("100000000n"); + assert!(quantity.is_ok()); + + let quantity = quantity.unwrap().1; + assert_eq!(quantity.value, Decimal::new(100000000, 0)); + assert_eq!(quantity.scale, Scale::Nano); + assert_eq!(quantity.format, Format::DecimalSI); + + assert_eq!(quantity.to_string(), "100000000n"); + } + + #[test] + fn test_micro_quantity() { + let quantity = parse_quantity_string("100000u"); + assert!(quantity.is_ok()); + + let quantity = quantity.unwrap().1; + assert_eq!(quantity.value, Decimal::new(100000, 0)); + assert_eq!(quantity.scale, Scale::Micro); + assert_eq!(quantity.format, Format::DecimalSI); + + assert_eq!(quantity.to_string(), "100000u"); + } + #[test] fn test_milli_quantity() { let quantity = parse_quantity_string("100m"); @@ -245,6 +275,26 @@ mod tests { assert_eq!(q3.to_string(), "2049Ki"); } + #[test] + fn test_quantity_addition_binary_si_mixed_scales_2() { + let q1 = parse_quantity_string("50m").unwrap().1; + let q2 = parse_quantity_string("50000000n").unwrap().1; + + let q3 = q1 + q2; + + assert_eq!(q3.to_string(), "100000000n"); + } + + #[test] + fn test_quantity_addition_binary_si_mixed_scales_3() { + let q1 = parse_quantity_string("1.5u").unwrap().1; + let q2 = parse_quantity_string("500n").unwrap().1; + + let q3 = q1 + q2; + + assert_eq!(q3.to_string(), "2000n"); + } + #[test] fn test_quantity_addition_binary_si_decimal_exponent() { let q1 = parse_quantity_string("12Mi").unwrap().1; diff --git a/src/scale.rs b/src/scale.rs index f350b0c..9b0740f 100644 --- a/src/scale.rs +++ b/src/scale.rs @@ -2,6 +2,8 @@ /// scales are omitted for mathematical simplicity. #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Default)] pub(crate) enum Scale { + Nano, + Micro, Milli, #[default] One, @@ -25,6 +27,8 @@ impl From<&Scale> for i32 { fn from(value: &Scale) -> Self { // https://en.wikipedia.org/wiki/Kilobyte match value { + Scale::Nano => -3, + Scale::Micro => -2, Scale::Milli => -1, Scale::One => 0, Scale::Kilo => 1, @@ -42,6 +46,8 @@ impl TryFrom for Scale { fn try_from(value: i32) -> Result { match value { + -3 => Ok(Scale::Nano), + -2 => Ok(Scale::Micro), -1 => Ok(Scale::Milli), 0 => Ok(Scale::One), 1 => Ok(Scale::Kilo), diff --git a/src/utils.rs b/src/utils.rs index 2dd4b7d..63b5095 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,6 +4,8 @@ use crate::{format::Format, scale::Scale}; pub(crate) fn scale_format_to_string(scale: &Scale, format: &Format) -> String { match format { Format::BinarySI => match scale { + Scale::Nano => "n".to_owned(), + Scale::Micro => "u".to_owned(), Scale::Milli => "".to_owned(), Scale::One => "".to_owned(), Scale::Kilo => "Ki".to_owned(), @@ -14,6 +16,8 @@ pub(crate) fn scale_format_to_string(scale: &Scale, format: &Format) -> String { Scale::Exa => "Ei".to_owned(), }, Format::DecimalSI => match scale { + Scale::Nano => "n".to_owned(), + Scale::Micro => "u".to_owned(), Scale::Milli => "m".to_owned(), Scale::One => "".to_owned(), Scale::Kilo => "k".to_owned(),