diff --git a/serde/src/de/from_primitive.rs b/serde/src/de/from_primitive.rs index 07646c91e..a8120fed3 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 a29c755c2..dca3ce7cb 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/de/mod.rs b/serde/src/de/mod.rs index 4f179b3e5..64f6c51b4 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -52,8 +52,8 @@ //! //! - **Primitive types**: //! - bool -//! - i8, i16, i32, i64, isize -//! - u8, u16, u32, u64, usize +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize //! - f32, f64 //! - char //! - **Compound types**: @@ -757,7 +757,7 @@ where /// Serde. /// /// The role of this trait is to define the deserialization half of the Serde -/// data model, which is a way to categorize every Rust data type into one of 27 +/// data model, which is a way to categorize every Rust data type into one of 29 /// possible types. Each method of the `Serializer` trait corresponds to one of /// the types of the data model. /// @@ -767,10 +767,10 @@ where /// /// The types that make up the Serde data model are: /// -/// - **12 primitive types** +/// - **14 primitive types** /// - bool -/// - i8, i16, i32, i64 -/// - u8, u16, u32, u64 +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 /// - f32, f64 /// - char /// - **string** @@ -884,6 +884,20 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; + serde_if_integer128! { + /// Hint that the `Deserialize` type is expecting an `i128` value. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de> + { + let _ = visitor; + Err(Error::custom("i128 is not supported")) + } + } + /// Hint that the `Deserialize` type is expecting a `u8` value. fn deserialize_u8(self, visitor: V) -> Result where @@ -904,6 +918,20 @@ pub trait Deserializer<'de>: Sized { where V: Visitor<'de>; + serde_if_integer128! { + /// Hint that the `Deserialize` type is expecting an `u128` value. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de> + { + let _ = visitor; + Err(Error::custom("u128 is not supported")) + } + } + /// Hint that the `Deserialize` type is expecting a `f32` value. fn deserialize_f32(self, visitor: V) -> Result where @@ -1250,6 +1278,20 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Signed(v), &self)) } + serde_if_integer128! { + /// The input contains a `i128`. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default implementation fails with a type error. + fn visit_i128(self, v: i128) -> Result + where + E: Error, + { + let _ = v; + Err(Error::invalid_type(Unexpected::Other("i128"), &self)) + } + } + /// The input contains a `u8`. /// /// The default implementation forwards to [`visit_u64`]. @@ -1296,6 +1338,20 @@ pub trait Visitor<'de>: Sized { Err(Error::invalid_type(Unexpected::Unsigned(v), &self)) } + serde_if_integer128! { + /// The input contains a `u128`. + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default implementation fails with a type error. + fn visit_u128(self, v: u128) -> Result + where + E: Error, + { + let _ = v; + Err(Error::invalid_type(Unexpected::Other("u128"), &self)) + } + } + /// The input contains an `f32`. /// /// The default implementation forwards to [`visit_f64`]. diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index fee07db1a..101531b3d 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -136,9 +136,9 @@ where type Error = E; forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct newtype_struct seq tuple tuple_struct map - struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct + map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -189,9 +189,9 @@ macro_rules! primitive_deserializer { type Error = E; forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str + string bytes byte_buf option unit unit_struct newtype_struct seq + tuple tuple_struct map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -246,9 +246,9 @@ where type Error = E; forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -339,9 +339,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any } } @@ -408,9 +408,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any } } @@ -483,9 +483,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any } } @@ -562,9 +562,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any } } @@ -618,9 +618,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct identifier ignored_any enum + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any enum } } @@ -688,9 +688,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -803,9 +803,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -917,9 +917,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct tuple_struct map struct - enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct tuple_struct map + struct enum identifier ignored_any } } @@ -1059,9 +1059,9 @@ where type Error = E; forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct tuple_struct map struct - enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct tuple_struct map + struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -1207,9 +1207,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } diff --git a/serde/src/integer128.rs b/serde/src/integer128.rs new file mode 100644 index 000000000..71db24655 --- /dev/null +++ b/serde/src/integer128.rs @@ -0,0 +1,86 @@ +/// Conditional compilation depending on whether Serde is built with support for +/// 128-bit integers. +/// +/// Data formats that wish to support Rust compiler versions older than 1.26 may +/// place the i128 / u128 methods of their Serializer and Deserializer behind +/// this macro. +/// +/// Data formats that require a minimum Rust compiler version of at least 1.26 +/// do not need to bother with this macro and may assume support for 128-bit +/// integers. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde; +/// +/// use serde::Serializer; +/// # use serde::private::ser::Error; +/// # +/// # struct MySerializer; +/// +/// impl Serializer for MySerializer { +/// type Ok = (); +/// type Error = Error; +/// +/// fn serialize_i64(self, v: i64) -> Result { +/// /* ... */ +/// # unimplemented!() +/// } +/// +/// /* ... */ +/// +/// serde_if_integer128! { +/// fn serialize_i128(self, v: i128) -> Result { +/// /* ... */ +/// # unimplemented!() +/// } +/// +/// fn serialize_u128(self, v: u128) -> Result { +/// /* ... */ +/// # unimplemented!() +/// } +/// } +/// # +/// # __serialize_unimplemented! { +/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some +/// # unit unit_struct unit_variant newtype_struct newtype_variant seq +/// # tuple tuple_struct tuple_variant map struct struct_variant +/// # } +/// } +/// # +/// # fn main() {} +/// ``` +/// +/// When Serde is built with support for 128-bit integers, this macro expands +/// transparently into just the input tokens. +/// +/// ```rust +/// macro_rules! serde_if_integer128 { +/// ($($tt:tt)*) => { +/// $($tt)* +/// }; +/// } +/// ``` +/// +/// When built without support for 128-bit integers, this macro expands to +/// nothing. +/// +/// ```rust +/// macro_rules! serde_if_integer128 { +/// ($($tt:tt)*) => {}; +/// } +/// ``` +#[cfg(integer128)] +#[macro_export] +macro_rules! serde_if_integer128 { + ($($tt:tt)*) => { + $($tt)* + }; +} + +#[cfg(not(integer128))] +#[macro_export] +#[doc(hidden)] +macro_rules! serde_if_integer128 { + ($($tt:tt)*) => {}; +} diff --git a/serde/src/lib.rs b/serde/src/lib.rs index a304fd743..ccd709294 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -222,6 +222,9 @@ mod lib { #[macro_use] mod macros; +#[macro_use] +mod integer128; + pub mod de; pub mod ser; diff --git a/serde/src/macros.rs b/serde/src/macros.rs index 20d10bf18..3e81d8f03 100644 --- a/serde/src/macros.rs +++ b/serde/src/macros.rs @@ -46,8 +46,8 @@ /// } /// # /// # forward_to_deserialize_any! { -/// # i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes -/// # byte_buf option unit unit_struct newtype_struct seq tuple +/// # i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// # bytes byte_buf option unit unit_struct newtype_struct seq tuple /// # tuple_struct map struct enum identifier ignored_any /// # } /// # } @@ -80,8 +80,8 @@ /// } /// /// forward_to_deserialize_any! { -/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes -/// byte_buf option unit unit_struct newtype_struct seq tuple +/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// bytes byte_buf option unit unit_struct newtype_struct seq tuple /// tuple_struct map struct enum identifier ignored_any /// } /// } @@ -116,9 +116,9 @@ /// # /// forward_to_deserialize_any! { /// > -/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes -/// byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct -/// map struct enum identifier ignored_any +/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string +/// bytes byte_buf option unit unit_struct newtype_struct seq tuple +/// tuple_struct map struct enum identifier ignored_any /// } /// # } /// # @@ -174,6 +174,11 @@ macro_rules! forward_to_deserialize_any_helper { (i64<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()} }; + (i128<$l:tt, $v:ident>) => { + serde_if_integer128! { + forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()} + } + }; (u8<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()} }; @@ -186,6 +191,11 @@ macro_rules! forward_to_deserialize_any_helper { (u64<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()} }; + (u128<$l:tt, $v:ident>) => { + serde_if_integer128! { + forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()} + } + }; (f32<$l:tt, $v:ident>) => { forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()} }; diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index eb683ef97..3c56e2f9c 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -50,9 +50,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit unit_struct newtype_struct seq tuple tuple_struct map - struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -1618,8 +1618,8 @@ mod content { } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } } @@ -1716,8 +1716,8 @@ mod content { } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } } @@ -2306,8 +2306,8 @@ mod content { } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } } @@ -2406,8 +2406,8 @@ mod content { } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } } @@ -2578,9 +2578,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } @@ -2617,9 +2617,9 @@ where } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index aef7f7359..c6e1e1bc2 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 { diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e4fd24052..a5538d31a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -48,8 +48,8 @@ //! //! - **Primitive types**: //! - bool -//! - i8, i16, i32, i64, isize -//! - u8, u16, u32, u64, usize +//! - i8, i16, i32, i64, i128, isize +//! - u8, u16, u32, u64, u128, usize //! - f32, f64 //! - char //! - str @@ -245,7 +245,7 @@ pub trait Serialize { /// A **data format** that can serialize any data structure supported by Serde. /// /// The role of this trait is to define the serialization half of the Serde data -/// model, which is a way to categorize every Rust data structure into one of 27 +/// model, which is a way to categorize every Rust data structure into one of 29 /// possible types. Each method of the `Serializer` trait corresponds to one of /// the types of the data model. /// @@ -254,10 +254,10 @@ pub trait Serialize { /// /// The types that make up the Serde data model are: /// -/// - **12 primitive types** +/// - **14 primitive types** /// - bool -/// - i8, i16, i32, i64 -/// - u8, u16, u32, u64 +/// - i8, i16, i32, i64, i128 +/// - u8, u16, u32, u64, u128 /// - f32, f64 /// - char /// - **string** @@ -492,6 +492,37 @@ pub trait Serializer: Sized { /// ``` fn serialize_i64(self, v: i64) -> Result; + serde_if_integer128! { + /// Serialize an `i128` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for i128 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_i128(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn serialize_i128(self, v: i128) -> Result { + let _ = v; + Err(Error::custom("i128 is not supported")) + } + } + /// Serialize a `u8` value. /// /// If the format does not differentiate between `u8` and `u64`, a @@ -596,6 +627,37 @@ pub trait Serializer: Sized { /// ``` fn serialize_u64(self, v: u64) -> Result; + serde_if_integer128! { + /// Serialize a `u128` value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde; + /// # + /// # use serde::Serializer; + /// # + /// # __private_serialize!(); + /// # + /// impl Serialize for u128 { + /// fn serialize(&self, serializer: S) -> Result + /// where + /// S: Serializer, + /// { + /// serializer.serialize_u128(*self) + /// } + /// } + /// # + /// # fn main() {} + /// ``` + /// + /// This method is available only on Rust compiler versions >=1.26. The + /// default behavior unconditionally returns an error. + fn serialize_u128(self, v: u128) -> Result { + let _ = v; + Err(Error::custom("u128 is not supported")) + } + } + /// Serialize an `f32` value. /// /// If the format does not differentiate between `f32` and `f64`, a diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 0de177101..3b8f28d8d 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -129,8 +129,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { type Error = Error; forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf unit seq map identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf unit seq map identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result @@ -657,8 +657,8 @@ impl<'de> de::Deserializer<'de> for BytesDeserializer { } forward_to_deserialize_any! { - bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes - byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct - map struct enum identifier ignored_any + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index a7eedba3f..6c1f3d82f 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -259,6 +259,27 @@ declare_tests! { 0f32 => &[Token::F32(0.)], 0f64 => &[Token::F64(0.)], } + test_small_int_to_128 { + 1i128 => &[Token::I8(1)], + 1i128 => &[Token::I16(1)], + 1i128 => &[Token::I32(1)], + 1i128 => &[Token::I64(1)], + + 1i128 => &[Token::U8(1)], + 1i128 => &[Token::U16(1)], + 1i128 => &[Token::U32(1)], + 1i128 => &[Token::U64(1)], + + 1u128 => &[Token::I8(1)], + 1u128 => &[Token::I16(1)], + 1u128 => &[Token::I32(1)], + 1u128 => &[Token::I64(1)], + + 1u128 => &[Token::U8(1)], + 1u128 => &[Token::U16(1)], + 1u128 => &[Token::U32(1)], + 1u128 => &[Token::U64(1)], + } test_char { 'a' => &[Token::Char('a')], 'a' => &[Token::Str("a")], diff --git a/test_suite/tests/test_ser.rs b/test_suite/tests/test_ser.rs index d677fe351..795d65f61 100644 --- a/test_suite/tests/test_ser.rs +++ b/test_suite/tests/test_ser.rs @@ -586,3 +586,10 @@ fn test_enum_skipped() { "the enum variant Enum::SkippedMap cannot be serialized", ); } + +#[test] +fn test_integer128() { + assert_ser_tokens_error(&1i128, &[], "i128 is not supported"); + + assert_ser_tokens_error(&1u128, &[], "u128 is not supported"); +}