diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 07646c91..a8120fed 100644 --- a/serde/src/de/from_primitive.rs +++ b/serde/src/de/from_primitive.rs @@ -178,3 +178,91 @@ impl_from_primitive_for_uint!(u32); impl_from_primitive_for_uint!(u64); impl_from_primitive_for_float!(f32); impl_from_primitive_for_float!(f64); + +serde_if_integer128! { + impl FromPrimitive for i128 { + #[inline] + fn from_i8(n: i8) -> Option { + Some(n as i128) + } + #[inline] + fn from_i16(n: i16) -> Option { + Some(n as i128) + } + #[inline] + fn from_i32(n: i32) -> Option { + Some(n as i128) + } + #[inline] + fn from_i64(n: i64) -> Option { + Some(n as i128) + } + #[inline] + fn from_u8(n: u8) -> Option { + Some(n as i128) + } + #[inline] + fn from_u16(n: u16) -> Option { + Some(n as i128) + } + #[inline] + fn from_u32(n: u32) -> Option { + Some(n as i128) + } + #[inline] + fn from_u64(n: u64) -> Option { + Some(n as i128) + } + } + + impl FromPrimitive for u128 { + #[inline] + fn from_i8(n: i8) -> Option { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i16(n: i16) -> Option { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i32(n: i32) -> Option { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_i64(n: i64) -> Option { + if n >= 0 { + Some(n as u128) + } else { + None + } + } + #[inline] + fn from_u8(n: u8) -> Option { + Some(n as u128) + } + #[inline] + fn from_u16(n: u16) -> Option { + Some(n as u128) + } + #[inline] + fn from_u32(n: u32) -> Option { + Some(n as u128) + } + #[inline] + fn from_u64(n: u64) -> Option { + Some(n as u128) + } + } +} diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index a29c755c..dca3ce7c 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -166,6 +166,92 @@ impl_deserialize_num!(usize, deserialize_u64, integer); impl_deserialize_num!(f32, deserialize_f32, integer, float); impl_deserialize_num!(f64, deserialize_f64, integer, float); +serde_if_integer128! { + impl<'de> Deserialize<'de> for i128 { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = i128; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("i128") + } + + impl_deserialize_num!(integer i128); + + #[inline] + fn visit_i128(self, v: i128) -> Result + where + E: Error, + { + Ok(v) + } + + #[inline] + fn visit_u128(self, v: u128) -> Result + where + E: Error, + { + if v <= i128::max_value() as u128 { + Ok(v as i128) + } else { + Err(Error::invalid_value(Unexpected::Other("u128"), &self)) + } + } + } + + deserializer.deserialize_i128(PrimitiveVisitor) + } + } + + impl<'de> Deserialize<'de> for u128 { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct PrimitiveVisitor; + + impl<'de> Visitor<'de> for PrimitiveVisitor { + type Value = u128; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("u128") + } + + impl_deserialize_num!(integer u128); + + #[inline] + fn visit_i128(self, v: i128) -> Result + where + E: Error, + { + if v >= 0 { + Ok(v as u128) + } else { + Err(Error::invalid_value(Unexpected::Other("i128"), &self)) + } + } + + #[inline] + fn visit_u128(self, v: u128) -> Result + where + E: Error, + { + Ok(v) + } + } + + deserializer.deserialize_u128(PrimitiveVisitor) + } + } +} + //////////////////////////////////////////////////////////////////////////////// struct CharVisitor; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index aef7f735..c6e1e1bc 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -44,6 +44,11 @@ primitive_impl!(f32, serialize_f32); primitive_impl!(f64, serialize_f64); primitive_impl!(char, serialize_char); +serde_if_integer128! { + primitive_impl!(i128, serialize_i128); + primitive_impl!(u128, serialize_u128); +} + //////////////////////////////////////////////////////////////////////////////// impl Serialize for str {