message: Test Uint128.multiply_ratio
diff: @@ -157,13 +157,15 @@ impl ops::Mul<Uint128> for Decimal {
  }
  impl Uint128 {
  - /// returns self * num / denom
  - pub fn multiply_ratio(&self, num: Uint128, denom: Uint128) -> Uint128 {
  - if denom.0 == 0 {
  + /// returns self * nom / denom
  + pub fn multiply_ratio<A: Into<u128>, B: Into<u128>>(&self, nom: A, denom: B) -> Uint128 {
  + let nominator: u128 = nom.into();
  + let denominator: u128 = denom.into();
  + if denominator == 0 {
  panic!("Denominator must not be zero");
  }
  // TODO: minimize rounding that takes place (using gcd algorithm)
  - let val = self.u128() * num.u128() / denom.u128();
  + let val = self.u128() * nominator / denominator;
  Uint128::from(val)
  }
  @@ -367,6 +369,34 @@ mod test {
  assert_eq!(left * right, Uint128(0));
  }
  + #[test]
  + fn u128_multiply_ratio_works() {
  + let base = Uint128(500);
  +
  + // factor 1/1
  + assert_eq!(base.multiply_ratio(1u128, 1u128), Uint128(500));
  + assert_eq!(base.multiply_ratio(3u128, 3u128), Uint128(500));
  + assert_eq!(base.multiply_ratio(654321u128, 654321u128), Uint128(500));
  +
  + // factor 3/2
  + assert_eq!(base.multiply_ratio(3u128, 2u128), Uint128(750));
  + assert_eq!(base.multiply_ratio(333333u128, 222222u128), Uint128(750));
  +
  + // factor 2/3 (integer devision always floors the result)
  + assert_eq!(base.multiply_ratio(2u128, 3u128), Uint128(333));
  + assert_eq!(base.multiply_ratio(222222u128, 333333u128), Uint128(333));
  +
  + // factor 5/6 (integer devision always floors the result)
  + assert_eq!(base.multiply_ratio(5u128, 6u128), Uint128(416));
  + assert_eq!(base.multiply_ratio(100u128, 120u128), Uint128(416));
  + }
  +
  + #[test]
  + #[should_panic(expected = "Denominator must not be zero")]
  + fn u128_multiply_ratio_panics_for_zero_denominator() {
  + Uint128(500).multiply_ratio(1u128, 0u128);
  + }
  +
  #[test]
  // in this test the Decimal is on the left
  fn decimal_uint128_multiply() {
  