diff --git a/rmp-serde/src/encode.rs b/rmp-serde/src/encode.rs index f42b20b7..d745b96f 100644 --- a/rmp-serde/src/encode.rs +++ b/rmp-serde/src/encode.rs @@ -604,7 +604,12 @@ where } fn serialize_i128(self, v: i128) -> Result { - self.serialize_bytes(&v.to_be_bytes()) + if let Ok(v_i64) = i64::try_from(v) { + encode::write_sint(&mut self.wr, v_i64)?; + } else { + self.serialize_bytes(&v.to_be_bytes())?; + } + Ok(()) } fn serialize_u8(self, v: u8) -> Result { @@ -625,7 +630,12 @@ where } fn serialize_u128(self, v: u128) -> Result { - self.serialize_bytes(&v.to_be_bytes()) + if let Ok(v_u64) = u64::try_from(v) { + encode::write_uint(&mut self.wr, v_u64)?; + } else { + self.serialize_bytes(&v.to_be_bytes())?; + } + Ok(()) } fn serialize_f32(self, v: f32) -> Result { diff --git a/rmp-serde/tests/round.rs b/rmp-serde/tests/round.rs index 120c2e60..97d10f59 100644 --- a/rmp-serde/tests/round.rs +++ b/rmp-serde/tests/round.rs @@ -666,6 +666,27 @@ fn roundtrip_some_failures() { assert_roundtrips(Some(None::<()>)); } +#[test] +fn roundtrip_i128_and_u128() { + assert_roundtrips(i8::MIN as i128); + assert_roundtrips(i16::MIN as i128); + assert_roundtrips(i32::MIN as i128); + assert_roundtrips(i64::MIN as i128); + assert_roundtrips(i128::MIN); + + assert_roundtrips(i8::MAX as i128); + assert_roundtrips(i16::MAX as i128); + assert_roundtrips(i32::MAX as i128); + assert_roundtrips(i64::MAX as i128); + assert_roundtrips(i128::MAX); + + assert_roundtrips(u8::MAX as u128); + assert_roundtrips(u16::MAX as u128); + assert_roundtrips(u32::MAX as u128); + assert_roundtrips(u64::MAX as u128); + assert_roundtrips(u128::MAX); +} + #[cfg(test)] #[track_caller] fn assert_roundtrips Deserialize<'a>>(val: T) {