diff --git a/utilities/src/fixed128.rs b/utilities/src/fixed128.rs index 4e9d7db8669cbbc63da23b70b49aa4323a1ea354..a09efe21feb0f3a687d7e19ef4050354b46129c1 100644 --- a/utilities/src/fixed128.rs +++ b/utilities/src/fixed128.rs @@ -212,30 +212,12 @@ impl_perthing_into_fixed_u128!(Perquintill); #[cfg(feature = "std")] impl FixedU128 { - fn str_with_precision(&self) -> String { - format!("{}.{}", &self.0 / DIV, &self.0 % DIV) - } - - fn from_str_with_precision(s: &str) -> Result<Self, &'static str> { - let err = "invalid string input"; - let vec_str: Vec<&str> = s.split(".").collect(); - - // parsing to decimal and fractional parts - let (decimal_str, fractional_str) = match vec_str.as_slice() { - &[d] => (d, "0"), - &[d, f] => (d, f), - _ => return Err(err), - }; - - let decimal: u128 = decimal_str.parse().map_err(|_| err)?; - let decimal_with_precision = decimal.checked_mul(DIV).ok_or(err)?; - // width = 18; precision = 18 - let padded_fractional_string = format!("{:0<18.18}", fractional_str); - let fractional_with_precision: u128 = padded_fractional_string.parse().map_err(|_| err)?; - - let parts = decimal_with_precision - .checked_add(fractional_with_precision) - .ok_or(err)?; + fn u128_str(&self) -> String { + format!("{}", &self.0) + } + + fn try_from_u128_str(s: &str) -> Result<Self, &'static str> { + let parts: u128 = s.parse().map_err(|_| "invalid string input")?; Ok(Self::from_parts(parts)) } } @@ -248,7 +230,7 @@ impl Serialize for FixedU128 { where S: Serializer, { - serializer.serialize_str(&self.str_with_precision()) + serializer.serialize_str(&self.u128_str()) } } @@ -261,7 +243,7 @@ impl<'de> Deserialize<'de> for FixedU128 { D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; - FixedU128::from_str_with_precision(&s).map_err(|err_str| de::Error::custom(err_str)) + FixedU128::try_from_u128_str(&s).map_err(|err_str| de::Error::custom(err_str)) } } @@ -416,43 +398,11 @@ mod tests { assert_eq!(a.recip(), None); } - #[test] - fn from_str_with_precision_should_work() { - assert_eq!( - FixedU128::from_str_with_precision("1").unwrap(), - FixedU128::from_natural(1) - ); - assert_eq!( - FixedU128::from_str_with_precision("1.0").unwrap(), - FixedU128::from_natural(1) - ); - assert_eq!( - FixedU128::from_str_with_precision("0.1").unwrap(), - FixedU128::from_rational(1, 10) - ); - assert_eq!( - FixedU128::from_str_with_precision("2.5").unwrap(), - FixedU128::from_rational(5, 2) - ); - assert_eq!( - FixedU128::from_str_with_precision("0.1000000000000000111").unwrap(), - FixedU128::from_rational(100000000000000011u128, 1000000000000000000u128) - ); - - assert!(FixedU128::from_str_with_precision(".").is_err()); - assert!(FixedU128::from_str_with_precision("").is_err()); - assert!(FixedU128::from_str_with_precision("1.1.1").is_err()); - assert!(FixedU128::from_str_with_precision("a.1").is_err()); - assert!(FixedU128::from_str_with_precision("1.a").is_err()); - // 340282366920938463464 == u128::max_value() / DIV + 1; overflows - assert!(FixedU128::from_str_with_precision("340282366920938463464").is_err()); - } - #[test] fn serialize_deserialize_should_work() { let two_point_five = FixedU128::from_rational(5, 2); let serialized = serde_json::to_string(&two_point_five).unwrap(); - assert_eq!(serialized, "\"2.500000000000000000\""); + assert_eq!(serialized, "\"2500000000000000000\""); let deserialized: FixedU128 = serde_json::from_str(&serialized).unwrap(); assert_eq!(deserialized, two_point_five); }