From 8126c2c892d701809329fa7bdbd2dcbf4f55605e Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 5 Aug 2023 23:11:51 +0500 Subject: [PATCH] Support deserialization of i128/u128 in flatten structs and internally tagged enums Fixed (6): newtype::enum_::newtype newtype::enum_::struct_ newtype::enum_::tuple newtype::newtype_struct newtype::struct_ struct_ --- serde/src/de/impls.rs | 37 ++++++++++++++- serde/src/private/de.rs | 100 ++++++++++++++++++++++++++++++++++++++++ serde_derive/src/de.rs | 42 ++++++++++++++++- 3 files changed, 177 insertions(+), 2 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 2d8c99030..f90a9be59 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -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(self, value: u128) -> Result + where + E: Error, + { + match value { + $( + $index => Ok($name_kind :: $variant), + )* + _ => Err(Unexpected::invalid_u128(value, &self)), } } @@ -2923,6 +2935,18 @@ where } } + fn visit_u128(self, value: u128) -> Result + 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(self, value: &str) -> Result where E: Error, @@ -3033,6 +3057,17 @@ where } } + fn visit_u128(self, value: u128) -> Result + where + E: Error, + { + match value { + 0 => Ok(Field::Ok), + 1 => Ok(Field::Err), + _ => Err(Unexpected::invalid_u128(value, &self)), + } + } + fn visit_str(self, value: &str) -> Result where E: Error, diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 50ae6ed15..39af9ebf3 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -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), @@ -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), @@ -406,6 +410,20 @@ mod content { Ok(Content::U64(value)) } + fn visit_i128(self, value: i128) -> Result + where + F: de::Error, + { + Ok(Content::I128(value)) + } + + fn visit_u128(self, value: u128) -> Result + where + F: de::Error, + { + Ok(Content::U128(value)) + } + fn visit_f32(self, value: f32) -> Result where F: de::Error, @@ -660,6 +678,24 @@ mod content { .map(TagOrContent::Content) } + fn visit_i128(self, value: i128) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_i128(value) + .map(TagOrContent::Content) + } + + fn visit_u128(self, value: u128) -> Result + where + F: de::Error, + { + ContentVisitor::new() + .visit_u128(value) + .map(TagOrContent::Content) + } + fn visit_f32(self, value: f32) -> Result where F: de::Error, @@ -955,6 +991,17 @@ mod content { } } + fn visit_u128(self, field_index: u128) -> Result + 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(self, field: &str) -> Result where E: de::Error, @@ -1078,10 +1125,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)), } } @@ -1097,10 +1146,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)), } } @@ -1149,10 +1200,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), @@ -1207,6 +1260,13 @@ mod content { self.deserialize_integer(visitor) } + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, @@ -1235,6 +1295,13 @@ mod content { self.deserialize_integer(visitor) } + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, @@ -1486,6 +1553,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)), } } @@ -1667,10 +1735,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)), } } @@ -1686,10 +1756,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)), } } @@ -1748,10 +1820,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), @@ -1808,6 +1882,13 @@ mod content { self.deserialize_integer(visitor) } + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, @@ -1836,6 +1917,13 @@ mod content { self.deserialize_integer(visitor) } + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_integer(visitor) + } + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, @@ -2080,6 +2168,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)), } } @@ -2388,6 +2477,17 @@ where } } +impl<'de, E> IdentifierDeserializer<'de, E> for u128 +where + E: Error, +{ + type Deserializer = >::Deserializer; + + fn from(self) -> Self::Deserializer { + self.into_deserializer() + } +} + pub struct StrDeserializer<'a, E> { value: &'a str, marker: PhantomData, diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index f94097cd8..fb1c04aff 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -2293,6 +2293,13 @@ fn deserialize_identifier( _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I64(__value))) } + fn visit_i128<__E>(self, __value: i128) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I128(__value))) + } + fn visit_u8<__E>(self, __value: u8) -> _serde::__private::Result where __E: _serde::de::Error, @@ -2321,6 +2328,13 @@ fn deserialize_identifier( _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U64(__value))) } + fn visit_u128<__E>(self, __value: u128) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U128(__value))) + } + fn visit_f32<__E>(self, __value: f32) -> _serde::__private::Result where __E: _serde::de::Error, @@ -2350,6 +2364,7 @@ fn deserialize_identifier( } } } else { + let index_expecting = if is_variant { "variant" } else { "field" }; let u64_mapping = fields.iter().enumerate().map(|(i, (ident, _))| { let i = i as u64; quote!(#i => _serde::__private::Ok(#this_value::#ident)) @@ -2359,7 +2374,6 @@ fn deserialize_identifier( let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough { fallthrough } else { - let index_expecting = if is_variant { "variant" } else { "field" }; let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); u64_fallthrough_arm_tokens = quote! { _serde::__private::Err(_serde::de::Error::invalid_value( @@ -2370,6 +2384,22 @@ fn deserialize_identifier( &u64_fallthrough_arm_tokens }; + let u128_mapping = fields.iter().enumerate().map(|(i, (ident, _))| { + let i = i as u128; + quote!(#i => _serde::__private::Ok(#this_value::#ident)) + }); + + let u128_fallthrough_arm_tokens; + let u128_fallthrough_arm = if let Some(fallthrough) = &fallthrough { + fallthrough + } else { + let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len()); + u128_fallthrough_arm_tokens = quote! { + _serde::__private::Err(_serde::de::Unexpected::invalid_u128(__value, &#fallthrough_msg)) + }; + &u128_fallthrough_arm_tokens + }; + quote! { fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result where @@ -2380,6 +2410,16 @@ fn deserialize_identifier( _ => #u64_fallthrough_arm, } } + + fn visit_u128<__E>(self, __value: u128) -> _serde::__private::Result + where + __E: _serde::de::Error, + { + match __value { + #(#u128_mapping,)* + _ => #u128_fallthrough_arm, + } + } } };