From 9ef0c9655d5c6b7ac82a5652acbbf279180a13ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Tue, 30 May 2023 20:01:35 +0300 Subject: [PATCH] Add support for imperial gallons --- src/conversions.rs | 17 +++++++++++++++++ src/format.rs | 39 +++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 ++++ src/parse.rs | 10 ++++++++++ src/units.rs | 3 +++ 5 files changed, 73 insertions(+) diff --git a/src/conversions.rs b/src/conversions.rs index f503a00..45c098b 100644 --- a/src/conversions.rs +++ b/src/conversions.rs @@ -20,6 +20,9 @@ fn get_conversion(unit: NonMetric) -> Conversion { let pound_from = 100_000.0; let pound_to = 45359237.0; + let imperial_gallon_from = 100_000.0; + let imperial_gallon_to = 454609.0; + match unit { // Length NonMetric::Inch => Conversion { @@ -96,6 +99,12 @@ fn get_conversion(unit: NonMetric) -> Conversion { from: inch_from * inch_from * inch_from, to: MetricQuantity { amount: 12.0 * inch_to * 12.0 * inch_to * 12.0 * inch_to, unit: Metric::CubicMetre }, }, + // Fluid volume + NonMetric::ImperialGallon => Conversion { + offset: 0.0, + from: imperial_gallon_from, + to: MetricQuantity { amount: imperial_gallon_to, unit: Metric::Litre }, + }, } } @@ -164,6 +173,14 @@ mod test { run_tests(&tests, Metric::CubicMetre); } + #[test] + fn fluid_volume() { + let tests = [ + Test(NonMetric::ImperialGallon, 4.54609), + ]; + run_tests(&tests, Metric::Litre); + } + fn run_tests(tests: &[Test], unit: Metric) { for test in tests { let from = NonMetricQuantity { diff --git a/src/format.rs b/src/format.rs index 7e9d197..b0759b4 100644 --- a/src/format.rs +++ b/src/format.rs @@ -106,6 +106,17 @@ fn prefixed_unit(quantity: MetricQuantity) -> PrefixedUnit { return PrefixedUnit(0.001 * 0.001 * 0.001, "mm³"); } } + Metric::Litre => { + if absolute >= 1.0 { + return PrefixedUnit(1.0, "l"); + } else if absolute >= 0.1 { + return PrefixedUnit(0.1, "dl"); + } else if absolute >= 0.01 { + return PrefixedUnit(0.01, "cl"); + } else { + return PrefixedUnit(0.001, "ml"); + } + } } } @@ -392,4 +403,32 @@ mod test { unit: Metric::CubicMetre, })); } + + #[test] + fn litre() { + assert_eq!(PrefixedUnit(0.001, "ml"), prefixed_unit(MetricQuantity { + amount: 0.000_1, + unit: Metric::Litre, + })); + assert_eq!(PrefixedUnit(0.001, "ml"), prefixed_unit(MetricQuantity { + amount: 0.001, + unit: Metric::Litre, + })); + assert_eq!(PrefixedUnit(0.01, "cl"), prefixed_unit(MetricQuantity { + amount: 0.01, + unit: Metric::Litre, + })); + assert_eq!(PrefixedUnit(0.1, "dl"), prefixed_unit(MetricQuantity { + amount: 0.1, + unit: Metric::Litre, + })); + assert_eq!(PrefixedUnit(1.0, "l"), prefixed_unit(MetricQuantity { + amount: 1.0, + unit: Metric::Litre, + })); + assert_eq!(PrefixedUnit(1.0, "l"), prefixed_unit(MetricQuantity { + amount: 10.0, + unit: Metric::Litre, + })); + } } diff --git a/src/lib.rs b/src/lib.rs index a526b46..be5bd68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,6 +84,8 @@ fn unit_to_name(unit: NonMetric) -> &'static str { // Volume NonMetric::CubicInch => "cubic inches", NonMetric::CubicFoot => "cubic feet", + // Fluid volume + NonMetric::ImperialGallon => "imperial gallons", } } @@ -125,5 +127,7 @@ mod test { // Volume assert_eq!(run("1 in³"), Ok("16.39 cm³".to_string())); assert_eq!(run("1 ft³"), Ok("28 317 cm³".to_string())); + // Fluid volume + assert_eq!(run("1 imp gal"), Ok("4.546 l".to_string())); } } diff --git a/src/parse.rs b/src/parse.rs index 814bb36..7172571 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -185,6 +185,11 @@ fn parse_unit(input: String) -> Result { "feet^3" => Ok(NonMetric::CubicFoot), "ft^3" => Ok(NonMetric::CubicFoot), + // Fluid volume + "imperial gallon" => Ok(NonMetric::ImperialGallon), + "imperial gallons" => Ok(NonMetric::ImperialGallon), + "imp gal" => Ok(NonMetric::ImperialGallon), + _ => Err(ParseError::UnknownUnit(input)), } } @@ -419,6 +424,11 @@ mod test { assert_eq!(parse_unit("feet^3".to_string()), Ok(NonMetric::CubicFoot)); assert_eq!(parse_unit("ft^3".to_string()), Ok(NonMetric::CubicFoot)); + // Fluid volume + assert_eq!(parse_unit("imperial gallon".to_string()), Ok(NonMetric::ImperialGallon)); + assert_eq!(parse_unit("imperial gallons".to_string()), Ok(NonMetric::ImperialGallon)); + assert_eq!(parse_unit("imp gal".to_string()), Ok(NonMetric::ImperialGallon)); + // Unknown unit assert_eq!(parse_unit("hutenosa".to_string()), Err(ParseError::UnknownUnit("hutenosa".to_string()))); } diff --git a/src/units.rs b/src/units.rs index 73e255b..5c6f6a5 100644 --- a/src/units.rs +++ b/src/units.rs @@ -5,6 +5,7 @@ pub enum Metric { Celsius, SquareMetre, CubicMetre, + Litre, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -28,6 +29,8 @@ pub enum NonMetric { // Volume CubicInch, CubicFoot, + // Fluid volume + ImperialGallon, } #[derive(Clone, Copy, Debug, PartialEq)]