diff --git a/src/quantity/quantity.rs b/src/quantity/quantity.rs index 1c2ec2d..2df2d11 100644 --- a/src/quantity/quantity.rs +++ b/src/quantity/quantity.rs @@ -111,6 +111,37 @@ impl Quantity { return Some(n.mul_no_convert(fa).div_no_convert(fb)) } + + pub fn match_units(&mut self, other: &Quantity) { + + let mut new_units = Quantity::new_rational_from_string("1").unwrap(); + let mut flag; + + // Check every unit in `self` + for (us, ps) in self.unit.get_val() { + flag = false; + + // Check if `us` matches some unit in `other` + for (uo, _) in other.unit.get_val() { + if { + uo.to_base().unit.compatible_with(&us.to_base().unit) + } { + // If it does, convert `us` to `uo` + new_units.insert_unit(uo.clone(), ps.clone()); + flag = true; + break; + } + } + if !flag { + // If no unit in `other` matches `us`, don't convert `us` + new_units.insert_unit(us.clone(), ps.clone()); + } + } + + // Convert self to new units + *self = self.convert_to(new_units).unwrap(); + } + pub fn convert_to_base(&self) -> Quantity { self.convert_to(self.unit.to_base()).unwrap() } } @@ -282,24 +313,13 @@ impl SubAssign for Quantity where { } } - impl Mul for Quantity { type Output = Self; fn mul(self, other: Self) -> Self::Output { - let mut o = other; - if self.unit != o.unit { - if o.unit.compatible_with(&self.unit) { - o = o.convert_to(self.clone()).unwrap() - } else { - let cf = self.unit.common_factor(&o.unit); - if let Some(f) = cf { - o = o.convert_to(f).unwrap(); - } - } - } + o.match_units(&self); Quantity { scalar: self.scalar * o.scalar, @@ -311,18 +331,8 @@ impl Mul for Quantity { impl MulAssign for Quantity where { fn mul_assign(&mut self, other: Self) { - let mut o = other; - if self.unit != o.unit { - if o.unit.compatible_with(&self.unit) { - o = o.convert_to(self.clone()).unwrap() - } else { - let cf = self.unit.common_factor(&o.unit); - if let Some(f) = cf { - o = o.convert_to(f).unwrap(); - } - } - } + o.match_units(&self); self.scalar *= o.scalar; self.unit *= o.unit; @@ -335,16 +345,7 @@ impl Div for Quantity { fn div(self, other: Self) -> Self::Output { let mut o = other; - if self.unit != o.unit { - if o.unit.compatible_with(&self.unit) { - o = o.convert_to(self.clone()).unwrap() - } else { - let cf = self.unit.common_factor(&o.unit); - if let Some(f) = cf { - o = o.convert_to(f).unwrap(); - } - } - } + o.match_units(&self); Quantity { scalar: self.scalar / o.scalar, @@ -357,16 +358,7 @@ impl DivAssign for Quantity where { fn div_assign(&mut self, other: Self) { let mut o = other; - if self.unit != o.unit { - if o.unit.compatible_with(&self.unit) { - o = o.convert_to(self.clone()).unwrap() - } else { - let cf = self.unit.common_factor(&o.unit); - if let Some(f) = cf { - o = o.convert_to(f).unwrap(); - } - } - } + o.match_units(&self); self.scalar /= o.scalar; self.unit /= o.unit; diff --git a/src/quantity/unit/unit.rs b/src/quantity/unit/unit.rs index 6faa62a..ef06faa 100644 --- a/src/quantity/unit/unit.rs +++ b/src/quantity/unit/unit.rs @@ -161,52 +161,6 @@ impl Unit { return o == s; } - // True if these two units have a common factor - pub fn common_factor(&self, other: &Unit) -> Option { - - if self.unitless() || other.unitless() { return None; } - - - let mut failed = false; - - // What to convert `other` to before multiplying - let mut factor = Quantity::new_rational_from_string("1").unwrap(); - let mut flag; - for (us, _) in self.get_val() { - flag = false; - for (uo, po) in other.get_val() { - if { - us.to_base().unit.compatible_with(&uo.to_base().unit) - } { - factor.insert_unit(us.clone(), po.clone()); - flag = true; - break; - } - } - if !flag { failed = true } - } - - if !failed { return Some(factor);} - - - let mut factor = Quantity::new_rational_from_string("1").unwrap(); - for (uo, po) in other.get_val() { - flag = false; - for (us, _) in self.get_val() { - if { - us.to_base().unit.compatible_with(&uo.to_base().unit) - } { - factor.insert_unit(us.clone(), po.clone()); - flag = true; - break; - } - } - if !flag { return None; } - } - - return Some(factor); - } - pub fn insert(&mut self, u: FreeUnit, p: Scalar) { let v = self.get_val_mut(); match v.get_mut(&u) {