Compare commits

...

5 Commits

Author SHA1 Message Date
Juhani Krekelä 055ab32a99 Add support for square miles 2023-05-29 03:28:09 +03:00
Juhani Krekelä 7a7959c172 Add support for acres 2023-05-29 03:28:09 +03:00
Juhani Krekelä 85c5c9d66f Add support for square feet 2023-05-29 03:28:09 +03:00
Juhani Krekelä 7eb31b1b4b Add support for square inches 2023-05-29 03:28:09 +03:00
Juhani Krekelä d6441454fc Split format::test::units to per-unit tests 2023-05-29 02:54:27 +03:00
5 changed files with 168 additions and 1 deletions

View File

@ -64,6 +64,27 @@ fn get_conversion(unit: NonMetric) -> Conversion {
from: 9.0,
to: MetricQuantity { amount: 5.0, unit: Metric::Celcius },
},
// Area
NonMetric::SquareInch => Conversion {
offset: 0.0,
from: inch_from * inch_from,
to: MetricQuantity { amount: inch_to * inch_to, unit: Metric::SquareMetre },
},
NonMetric::SquareFoot => Conversion {
offset: 0.0,
from: inch_from * inch_from,
to: MetricQuantity { amount: 12.0 * inch_to * 12.0 * inch_to, unit: Metric::SquareMetre },
},
NonMetric::Acre => Conversion {
offset: 0.0,
from: inch_from * inch_from,
to: MetricQuantity { amount: 43_560.0 * 12.0 * inch_to * 12.0 * inch_to, unit: Metric::SquareMetre },
},
NonMetric::SquareMile => Conversion {
offset: 0.0,
from: inch_from * inch_from,
to: MetricQuantity { amount: 1760.0 * 3.0 * 12.0 * inch_to * 1760.0 * 3.0 * 12.0 * inch_to, unit: Metric::SquareMetre },
},
}
}
@ -112,6 +133,17 @@ mod test {
});
}
#[test]
fn area() {
let tests = [
Test(NonMetric::SquareInch, 0.00064516),
Test(NonMetric::SquareFoot, 0.09290304),
Test(NonMetric::Acre, 4046.8564224),
Test(NonMetric::SquareMile, 2589988.110336),
];
run_tests(&tests, Metric::SquareMetre);
}
fn run_tests(tests: &[Test], unit: Metric) {
for test in tests {
let from = NonMetricQuantity {

View File

@ -84,6 +84,17 @@ fn prefixed_unit(quantity: MetricQuantity) -> PrefixedUnit {
}
}
Metric::Celcius => PrefixedUnit(1.0, "°C"),
Metric::SquareMetre => {
if absolute >= 1000.0 * 1000.0 {
return PrefixedUnit(1000.0 * 1000.0, "km²");
} else if absolute >= 1.0 {
return PrefixedUnit(1.0, "");
} else if absolute >= 0.01 * 0.01 {
return PrefixedUnit(0.01 * 0.01, "cm²");
} else {
return PrefixedUnit(0.001 * 0.001, "mm²");
}
}
}
}
@ -154,7 +165,7 @@ mod test {
}
#[test]
fn units() {
fn metres() {
assert_eq!(PrefixedUnit(0.001, "mm"), prefixed_unit(MetricQuantity {
amount: 0.0001,
unit: Metric::Metre,
@ -208,7 +219,10 @@ mod test {
amount: -1000.0,
unit: Metric::Metre,
}));
}
#[test]
fn grams() {
assert_eq!(PrefixedUnit(1.0, "g"), prefixed_unit(MetricQuantity {
amount: 0.1,
unit: Metric::Gram,
@ -242,7 +256,10 @@ mod test {
amount: -1000.0,
unit: Metric::Gram,
}));
}
#[test]
fn celcius() {
assert_eq!(PrefixedUnit(1.0, "°C"), prefixed_unit(MetricQuantity {
amount: 0.0001,
unit: Metric::Celcius,
@ -256,4 +273,72 @@ mod test {
unit: Metric::Celcius,
}));
}
#[test]
fn square_metres() {
assert_eq!(PrefixedUnit(0.000_001, "mm²"), prefixed_unit(MetricQuantity {
amount: 0.000_000_1,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_001, "mm²"), prefixed_unit(MetricQuantity {
amount: 0.000_001,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_001, "mm²"), prefixed_unit(MetricQuantity {
amount: 0.000_01,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_1, "cm²"), prefixed_unit(MetricQuantity {
amount: 0.000_1,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_1, "cm²"), prefixed_unit(MetricQuantity {
amount: 0.001,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_1, "cm²"), prefixed_unit(MetricQuantity {
amount: 0.01,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_1, "cm²"), prefixed_unit(MetricQuantity {
amount: 0.01,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(0.000_1, "cm²"), prefixed_unit(MetricQuantity {
amount: 0.1,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 1.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 10.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 100.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 1_000.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 10_000.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1.0, ""), prefixed_unit(MetricQuantity {
amount: 100_000.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1_000_000.0, "km²"), prefixed_unit(MetricQuantity {
amount: 1_000_000.0,
unit: Metric::SquareMetre,
}));
assert_eq!(PrefixedUnit(1_000_000.0, "km²"), prefixed_unit(MetricQuantity {
amount: 10_000_000.0,
unit: Metric::SquareMetre,
}));
}
}

View File

@ -72,6 +72,11 @@ fn unit_to_name(unit: NonMetric) -> &'static str {
NonMetric::Stone => "stones",
// Temperature
NonMetric::Fahrenheit => "degrees Fahrenheit",
// Area
NonMetric::SquareInch => "square inches",
NonMetric::SquareFoot => "square feet",
NonMetric::Acre => "acres",
NonMetric::SquareMile => "square miles",
}
}
@ -104,5 +109,10 @@ mod test {
assert_eq!(run("-40 °F"), Ok("-40 °C".to_string()));
assert_eq!(run("0 °F"), Ok("-17.78 °C".to_string()));
assert_eq!(run("32 °F"), Ok("0 °C".to_string()));
// Area
assert_eq!(run("1 in²"), Ok("6.452 cm²".to_string()));
assert_eq!(run("1 ft²"), Ok("929 cm²".to_string()));
assert_eq!(run("1 acre"), Ok("4 047 m²".to_string()));
assert_eq!(run("1 mi²"), Ok("2.59 km²".to_string()));
}
}

View File

@ -101,6 +101,23 @@ fn parse_unit(input: String) -> Result<NonMetric, ParseError> {
"°F" => Ok(NonMetric::Fahrenheit),
"F" => Ok(NonMetric::Fahrenheit),
// Area
"inch²" => Ok(NonMetric::SquareInch),
"inches²" => Ok(NonMetric::SquareInch),
"in²" => Ok(NonMetric::SquareInch),
"foot²" => Ok(NonMetric::SquareFoot),
"feet²" => Ok(NonMetric::SquareFoot),
"ft²" => Ok(NonMetric::SquareFoot),
"acre" => Ok(NonMetric::Acre),
"acres" => Ok(NonMetric::Acre),
"ac" => Ok(NonMetric::Acre),
"mile²" => Ok(NonMetric::SquareMile),
"miles²" => Ok(NonMetric::SquareMile),
"mi²" => Ok(NonMetric::SquareMile),
_ => Err(ParseError::UnknownUnit(input)),
}
}
@ -249,6 +266,23 @@ mod test {
assert_eq!(parse_unit("°F".to_string()), Ok(NonMetric::Fahrenheit));
assert_eq!(parse_unit("F".to_string()), Ok(NonMetric::Fahrenheit));
// Area
assert_eq!(parse_unit("inch²".to_string()), Ok(NonMetric::SquareInch));
assert_eq!(parse_unit("inches²".to_string()), Ok(NonMetric::SquareInch));
assert_eq!(parse_unit("in²".to_string()), Ok(NonMetric::SquareInch));
assert_eq!(parse_unit("foot²".to_string()), Ok(NonMetric::SquareFoot));
assert_eq!(parse_unit("feet²".to_string()), Ok(NonMetric::SquareFoot));
assert_eq!(parse_unit("ft²".to_string()), Ok(NonMetric::SquareFoot));
assert_eq!(parse_unit("acre".to_string()), Ok(NonMetric::Acre));
assert_eq!(parse_unit("acres".to_string()), Ok(NonMetric::Acre));
assert_eq!(parse_unit("ac".to_string()), Ok(NonMetric::Acre));
assert_eq!(parse_unit("mile²".to_string()), Ok(NonMetric::SquareMile));
assert_eq!(parse_unit("miles²".to_string()), Ok(NonMetric::SquareMile));
assert_eq!(parse_unit("mi²".to_string()), Ok(NonMetric::SquareMile));
// Unknown unit
assert_eq!(parse_unit("hutenosa".to_string()), Err(ParseError::UnknownUnit("hutenosa".to_string())));
}

View File

@ -3,6 +3,7 @@ pub enum Metric {
Metre,
Gram,
Celcius,
SquareMetre,
}
#[derive(Clone, Copy, Debug, PartialEq)]
@ -18,6 +19,11 @@ pub enum NonMetric {
Stone,
// Temperature
Fahrenheit,
// Area
SquareInch,
SquareFoot,
Acre,
SquareMile,
}
#[derive(Clone, Copy, Debug, PartialEq)]