From 4d8e802520726b56bc2513c966f063b7ed4ef6af Mon Sep 17 00:00:00 2001 From: Matthew Gamble Date: Tue, 6 Jul 2021 00:21:12 +1000 Subject: [PATCH] Support dividing lengthes by speed The result has a unit of time. --- CHANGELOG.md | 3 +++ src/units.rs | 30 ++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67d51ca..d84439e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## Next +- Add support for dividing length units by speed units (like 10 km / 100 kph) + ## 1.7.0 - 2021 Jul 14 - Add operator words `plus`, `minus` and `times` - Add operator phrases `multiplied by` and `divided by` diff --git a/src/units.rs b/src/units.rs index 6a92e0c..49cf191 100644 --- a/src/units.rs +++ b/src/units.rs @@ -361,8 +361,9 @@ pub fn subtract(left: Number, right: Number) -> Result { /// /// If you have 1,000,000 millimeters, this will return 1 kilometer. /// -/// This only affects units of `Length`, `Area`, `Volume`, `Energy`, `Power`, -/// `ElectricCurrent`, `Resistance` and `Voltage`. Other units are passed through. +/// This only affects units of `Length`, `Time`, `Area`, `Volume`, +/// `Energy`, `Power`, `ElectricCurrent`, `Resistance`, and `Voltage`. +/// Other units are passed through. pub fn to_ideal_unit(number: Number) -> Number { let value = number.value * number.unit.weight(); if number.unit.category() == Length { @@ -377,6 +378,24 @@ pub fn to_ideal_unit(number: Number) -> Number { } else { return Number::new(value, Millimeter) } + } else if number.unit.category() == Time { + if value >= d128!(31556952000000000) { + return Number::new(value/Year.weight(), Year); + } else if value >= d128!(86400000000000) { + return Number::new(value/Day.weight(), Day); + } else if value >= d128!(3600000000000) { + return Number::new(value/Hour.weight(), Hour); + } else if value >= d128!(60000000000) { + return Number::new(value/Minute.weight(), Minute); + } else if value >= d128!(1000000000) { + return Number::new(value/Second.weight(), Second); + } else if value >= d128!(1000000) { + return Number::new(value/Millisecond.weight(), Millisecond); + } else if value >= d128!(1000) { + return Number::new(value/Microsecond.weight(), Microsecond); + } else { + return Number::new(value, Nanosecond); + } } else if number.unit.category() == Area { if value >= d128!(1000000000000) { // 1 km2 return Number::new(value/SquareKilometer.weight(), SquareKilometer) @@ -562,6 +581,7 @@ fn actual_multiply(left: Number, right: Number, swapped: bool) -> Result Result { let hours = convert(right, Hour)?; let kph = Number::new(kilometers.value / hours.value, KilometersPerHour); Ok(convert(kph, final_unit)?) + } else if lcat == Length && rcat == Speed { + // 12 km / 100 kph + let kilometers = convert(left, Kilometer)?; + let kilometers_per_hour = convert(right, KilometersPerHour)?; + let hour = Number::new(kilometers.value / kilometers_per_hour.value, Hour); + Ok(to_ideal_unit(hour)) } else if lcat == Power && rcat == ElectricCurrent { // 1 watt / 1 ampere = 1 volt let result = (left.value * left.unit.weight()) / (right.value * right.unit.weight());