Skip to content
Snippets Groups Projects
Unverified Commit bacd7b80 authored by Shaopeng Wang's avatar Shaopeng Wang Committed by GitHub
Browse files

Update fixedu128 serde impl. (#87)

parent 2f70d290
No related branches found
No related tags found
No related merge requests found
...@@ -212,30 +212,12 @@ impl_perthing_into_fixed_u128!(Perquintill); ...@@ -212,30 +212,12 @@ impl_perthing_into_fixed_u128!(Perquintill);
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl FixedU128 { impl FixedU128 {
fn str_with_precision(&self) -> String { fn u128_str(&self) -> String {
format!("{}.{}", &self.0 / DIV, &self.0 % DIV) format!("{}", &self.0)
} }
fn from_str_with_precision(s: &str) -> Result<Self, &'static str> { fn try_from_u128_str(s: &str) -> Result<Self, &'static str> {
let err = "invalid string input"; let parts: u128 = s.parse().map_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)?;
Ok(Self::from_parts(parts)) Ok(Self::from_parts(parts))
} }
} }
...@@ -248,7 +230,7 @@ impl Serialize for FixedU128 { ...@@ -248,7 +230,7 @@ impl Serialize for FixedU128 {
where where
S: Serializer, 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 { ...@@ -261,7 +243,7 @@ impl<'de> Deserialize<'de> for FixedU128 {
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let s = String::deserialize(deserializer)?; 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 { ...@@ -416,43 +398,11 @@ mod tests {
assert_eq!(a.recip(), None); 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] #[test]
fn serialize_deserialize_should_work() { fn serialize_deserialize_should_work() {
let two_point_five = FixedU128::from_rational(5, 2); let two_point_five = FixedU128::from_rational(5, 2);
let serialized = serde_json::to_string(&two_point_five).unwrap(); 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(); let deserialized: FixedU128 = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized, two_point_five); assert_eq!(deserialized, two_point_five);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment