Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 128-bit integers in flatten structs and internally tagged enums #2781

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
37 changes: 36 additions & 1 deletion serde/src/de/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1636,7 +1636,19 @@ macro_rules! variant_identifier {
$(
$index => Ok($name_kind :: $variant),
)*
_ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self),),
_ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self)),
}
}

fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
where
E: Error,
{
match value {
$(
$index => Ok($name_kind :: $variant),
)*
_ => Err(Unexpected::invalid_u128(value, &self)),
}
}

Expand Down Expand Up @@ -2923,6 +2935,18 @@ where
}
}

fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
where
E: Error,
{
match value {
0 => Ok(Field::Unbounded),
1 => Ok(Field::Included),
2 => Ok(Field::Excluded),
_ => Err(Unexpected::invalid_u128(value, &self)),
}
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
Expand Down Expand Up @@ -3033,6 +3057,17 @@ where
}
}

fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
where
E: Error,
{
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Unexpected::invalid_u128(value, &self)),
}
}

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
Expand Down
40 changes: 26 additions & 14 deletions serde/src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,30 @@ pub enum Unexpected<'a> {
Other(&'a str),
}

impl<'a> Unexpected<'a> {
/// The input contained a signed integer `i128` that was not expected.
pub fn invalid_i128<E>(v: i128, expected: &Expected) -> E
where
E: Error,
{
let mut buf = [0u8; 58];
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Error::invalid_type(Unexpected::Other(writer.as_str()), expected)
}

/// The input contained an unsigned integer `u128` that was not expected.
pub fn invalid_u128<E>(v: u128, expected: &Expected) -> E
where
E: Error,
{
let mut buf = [0u8; 57];
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Error::invalid_type(Unexpected::Other(writer.as_str()), expected)
}
}

impl<'a> fmt::Display for Unexpected<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use self::Unexpected::*;
Expand Down Expand Up @@ -1372,13 +1396,7 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let mut buf = [0u8; 58];
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
&self,
))
Err(Unexpected::invalid_i128(v, &self))
}

/// The input contains a `u8`.
Expand Down Expand Up @@ -1434,13 +1452,7 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let mut buf = [0u8; 57];
let mut writer = crate::format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
&self,
))
Err(Unexpected::invalid_u128(v, &self))
}

/// The input contains an `f32`.
Expand Down
100 changes: 100 additions & 0 deletions serde/src/private/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,13 @@ mod content {
U16(u16),
U32(u32),
U64(u64),
U128(u128),

I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),

F32(f32),
F64(f64),
Expand Down Expand Up @@ -270,10 +272,12 @@ mod content {
Content::U16(n) => Unexpected::Unsigned(n as u64),
Content::U32(n) => Unexpected::Unsigned(n as u64),
Content::U64(n) => Unexpected::Unsigned(n),
Content::U128(_) => Unexpected::Other("an u128"),
Content::I8(n) => Unexpected::Signed(n as i64),
Content::I16(n) => Unexpected::Signed(n as i64),
Content::I32(n) => Unexpected::Signed(n as i64),
Content::I64(n) => Unexpected::Signed(n),
Content::I128(_) => Unexpected::Other("an i128"),
Content::F32(f) => Unexpected::Float(f as f64),
Content::F64(f) => Unexpected::Float(f),
Content::Char(c) => Unexpected::Char(c),
Expand Down Expand Up @@ -395,6 +399,20 @@ mod content {
Ok(Content::U64(value))
}

fn visit_i128<F>(self, value: i128) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I128(value))
}

fn visit_u128<F>(self, value: u128) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U128(value))
}

fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
where
F: de::Error,
Expand Down Expand Up @@ -649,6 +667,24 @@ mod content {
.map(TagOrContent::Content)
}

fn visit_i128<F>(self, value: i128) -> Result<Self::Value, F>
where
F: de::Error,
{
ContentVisitor::new()
.visit_i128(value)
.map(TagOrContent::Content)
}

fn visit_u128<F>(self, value: u128) -> Result<Self::Value, F>
where
F: de::Error,
{
ContentVisitor::new()
.visit_u128(value)
.map(TagOrContent::Content)
}

fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
where
F: de::Error,
Expand Down Expand Up @@ -944,6 +980,17 @@ mod content {
}
}

fn visit_u128<E>(self, field_index: u128) -> Result<Self::Value, E>
where
E: de::Error,
{
match field_index {
0 => Ok(TagOrContentField::Tag),
1 => Ok(TagOrContentField::Content),
_ => Err(Unexpected::invalid_u128(field_index, &self)),
}
}

fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
where
E: de::Error,
Expand Down Expand Up @@ -1067,10 +1114,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand All @@ -1086,10 +1135,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down Expand Up @@ -1146,10 +1197,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::Char(v) => visitor.visit_char(v),
Expand Down Expand Up @@ -1204,6 +1257,13 @@ mod content {
self.deserialize_integer(visitor)
}

fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -1232,6 +1292,13 @@ mod content {
self.deserialize_integer(visitor)
}

fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -1483,6 +1550,7 @@ mod content {
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down Expand Up @@ -1664,10 +1732,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand All @@ -1683,10 +1753,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down Expand Up @@ -1752,10 +1824,12 @@ mod content {
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
Content::I128(v) => visitor.visit_i128(v),
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::Char(v) => visitor.visit_char(v),
Expand Down Expand Up @@ -1812,6 +1886,13 @@ mod content {
self.deserialize_integer(visitor)
}

fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -1840,6 +1921,13 @@ mod content {
self.deserialize_integer(visitor)
}

fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
Expand Down Expand Up @@ -2084,6 +2172,7 @@ mod content {
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
Content::U64(v) => visitor.visit_u64(v),
Content::U128(v) => visitor.visit_u128(v),
_ => Err(self.invalid_type(&visitor)),
}
}
Expand Down Expand Up @@ -2392,6 +2481,17 @@ where
}
}

impl<'de, E> IdentifierDeserializer<'de, E> for u128
where
E: Error,
{
type Deserializer = <u128 as IntoDeserializer<'de, E>>::Deserializer;

fn from(self) -> Self::Deserializer {
self.into_deserializer()
}
}

pub struct StrDeserializer<'a, E> {
value: &'a str,
marker: PhantomData<E>,
Expand Down
Loading