mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-21 05:01:04 +00:00
Merge pull request #1959 from serde-rs/1917
Touch up borrowed field identifiers PR
This commit is contained in:
@@ -116,7 +116,6 @@ use lib::*;
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
mod from_primitive;
|
mod from_primitive;
|
||||||
|
|||||||
+81
-114
@@ -25,15 +25,13 @@ use lib::*;
|
|||||||
|
|
||||||
use self::private::{First, Second};
|
use self::private::{First, Second};
|
||||||
use __private::de::size_hint;
|
use __private::de::size_hint;
|
||||||
use de::{self, Expected, IntoDeserializer, SeqAccess};
|
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
|
||||||
use ser;
|
use ser;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// For structs that contain a PhantomData. We do not want the trait
|
// For structs that contain a PhantomData. We do not want the trait
|
||||||
/// bound `E: Clone` inferred by derive(Clone).
|
// bound `E: Clone` inferred by derive(Clone).
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! impl_copy_clone {
|
macro_rules! impl_copy_clone {
|
||||||
($ty:ident $(<$lifetime:tt>)*) => {
|
($ty:ident $(<$lifetime:tt>)*) => {
|
||||||
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
|
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
|
||||||
@@ -46,102 +44,6 @@ macro_rules! impl_copy_clone {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a deserializer any method of which forwards to the specified visitor method
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export(local_inner_macros)]
|
|
||||||
macro_rules! forward_deserializer {
|
|
||||||
// Non-borrowed references
|
|
||||||
(
|
|
||||||
$(#[$doc:meta])*
|
|
||||||
// Actually, * in lifetime should be ?, but that syntax is not supported
|
|
||||||
// on old Rust versions (<= 1.28) or in 2015 edition
|
|
||||||
ref $deserializer:ident $(<$lifetime:tt>)* ($ty:ty) => $visit:ident
|
|
||||||
) => {
|
|
||||||
$(#[$doc])*
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct $deserializer<$($lifetime,)* E> {
|
|
||||||
value: $ty,
|
|
||||||
marker: PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<$($lifetime,)* E> $deserializer<$($lifetime,)* E> {
|
|
||||||
/// Create a new deserializer from the given value.
|
|
||||||
pub fn new(value: $ty) -> Self {
|
|
||||||
$deserializer {
|
|
||||||
value: value,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_copy_clone!($deserializer $(<$lifetime>)*);
|
|
||||||
|
|
||||||
impl<'de, $($lifetime,)* E> $crate::de::Deserializer<'de> for $deserializer<$($lifetime,)* E>
|
|
||||||
where
|
|
||||||
E: $crate::de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> $crate::export::Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: $crate::de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
visitor.$visit(self.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize_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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Borrowed references
|
|
||||||
(
|
|
||||||
$(#[$doc:meta])*
|
|
||||||
borrowed $deserializer:ident($ty:ty) => $visit:ident
|
|
||||||
) => {
|
|
||||||
$(#[$doc])*
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct $deserializer<'de, E> {
|
|
||||||
value: $ty,
|
|
||||||
marker: PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> $deserializer<'de, E> {
|
|
||||||
/// Create a new borrowed deserializer from the given value.
|
|
||||||
pub fn new(value: $ty) -> Self {
|
|
||||||
$deserializer {
|
|
||||||
value: value,
|
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_copy_clone!($deserializer<'de>);
|
|
||||||
|
|
||||||
impl<'de, E> $crate::de::Deserializer<'de> for $deserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: $crate::de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> $crate::export::Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: $crate::de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
visitor.$visit(self.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize_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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// A minimal representation of all possible errors that can occur using the
|
/// A minimal representation of all possible errors that can occur using the
|
||||||
@@ -763,19 +665,84 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
forward_deserializer!(
|
/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
|
||||||
/// A deserializer holding a `&[u8]`. Always call [`Visitor::visit_bytes`]
|
#[derive(Debug)]
|
||||||
///
|
pub struct BytesDeserializer<'a, E> {
|
||||||
/// [`Visitor::visit_bytes`]: ../struct.Visitor.html#method.visit_bytes
|
value: &'a [u8],
|
||||||
ref BytesDeserializer<'a>(&'a [u8]) => visit_bytes
|
marker: PhantomData<E>,
|
||||||
);
|
}
|
||||||
forward_deserializer!(
|
|
||||||
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
impl<'a, E> BytesDeserializer<'a, E> {
|
||||||
/// deserializer. Always call [`Visitor::visit_borrowed_bytes`]
|
/// Create a new deserializer from the given bytes.
|
||||||
///
|
pub fn new(value: &'a [u8]) -> Self {
|
||||||
/// [`Visitor::visit_borrowed_bytes`]: ../struct.Visitor.html#method.visit_borrowed_bytes
|
BytesDeserializer {
|
||||||
borrowed BorrowedBytesDeserializer(&'de [u8]) => visit_borrowed_bytes
|
value: value,
|
||||||
);
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_copy_clone!(BytesDeserializer<'a>);
|
||||||
|
|
||||||
|
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_bytes(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A deserializer holding a `&[u8]` with a lifetime tied to another
|
||||||
|
/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`].
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BorrowedBytesDeserializer<'de, E> {
|
||||||
|
value: &'de [u8],
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
|
||||||
|
/// Create a new borrowed deserializer from the given borrowed bytes.
|
||||||
|
pub fn new(value: &'de [u8]) -> Self {
|
||||||
|
BorrowedBytesDeserializer {
|
||||||
|
value: value,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
|
||||||
|
|
||||||
|
impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_borrowed_bytes(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -258,7 +258,6 @@ mod macros;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod integer128;
|
mod integer128;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
|
||||||
|
|||||||
+58
-5
@@ -1,7 +1,7 @@
|
|||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
|
use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
|
||||||
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
|
||||||
use de::value::{BytesDeserializer, BorrowedBytesDeserializer};
|
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use de::{MapAccess, Unexpected};
|
use de::{MapAccess, Unexpected};
|
||||||
@@ -2561,8 +2561,55 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_deserializer!(ref StrDeserializer<'a>(&'a str) => visit_str);
|
pub struct StrDeserializer<'a, E> {
|
||||||
forward_deserializer!(borrowed BorrowedStrDeserializer(&'de str) => visit_borrowed_str);
|
value: &'a str,
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_str(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct BorrowedStrDeserializer<'de, E> {
|
||||||
|
value: &'de str,
|
||||||
|
marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_borrowed_str(self.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
|
||||||
where
|
where
|
||||||
@@ -2572,11 +2619,17 @@ where
|
|||||||
type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>;
|
type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>;
|
||||||
|
|
||||||
fn from(self) -> Self::Deserializer {
|
fn from(self) -> Self::Deserializer {
|
||||||
StrDeserializer::new(self)
|
StrDeserializer {
|
||||||
|
value: self,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn borrowed(self) -> Self::BorrowedDeserializer {
|
fn borrowed(self) -> Self::BorrowedDeserializer {
|
||||||
BorrowedStrDeserializer::new(self)
|
BorrowedStrDeserializer {
|
||||||
|
value: self,
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-24
@@ -1893,15 +1893,12 @@ fn deserialize_generated_identifier(
|
|||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
||||||
(
|
(
|
||||||
Some(ignore_variant),
|
Some(ignore_variant),
|
||||||
Some((fallthrough.clone(), fallthrough))
|
Some((fallthrough.clone(), fallthrough)),
|
||||||
)
|
)
|
||||||
} else if let Some(other_idx) = other_idx {
|
} else if let Some(other_idx) = other_idx {
|
||||||
let ignore_variant = fields[other_idx].1.clone();
|
let ignore_variant = fields[other_idx].1.clone();
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
|
||||||
(
|
(None, Some((fallthrough.clone(), fallthrough)))
|
||||||
None,
|
|
||||||
Some((fallthrough.clone(), fallthrough))
|
|
||||||
)
|
|
||||||
} else if is_variant || cattrs.deny_unknown_fields() {
|
} else if is_variant || cattrs.deny_unknown_fields() {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
@@ -1909,7 +1906,7 @@ fn deserialize_generated_identifier(
|
|||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
||||||
(
|
(
|
||||||
Some(ignore_variant),
|
Some(ignore_variant),
|
||||||
Some((fallthrough.clone(), fallthrough))
|
Some((fallthrough.clone(), fallthrough)),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1973,25 +1970,21 @@ fn deserialize_custom_identifier(
|
|||||||
if last.attrs.other() {
|
if last.attrs.other() {
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
|
let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
|
||||||
(
|
(ordinary, Some((fallthrough.clone(), fallthrough)))
|
||||||
ordinary,
|
|
||||||
Some((fallthrough.clone(), fallthrough))
|
|
||||||
)
|
|
||||||
} else if let Style::Newtype = last.style {
|
} else if let Style::Newtype = last.style {
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
let fallthrough = |method| quote! {
|
let fallthrough = |method| {
|
||||||
_serde::__private::Result::map(
|
quote! {
|
||||||
_serde::Deserialize::deserialize(
|
_serde::__private::Result::map(
|
||||||
_serde::__private::de::IdentifierDeserializer::#method(__value)
|
_serde::Deserialize::deserialize(
|
||||||
),
|
_serde::__private::de::IdentifierDeserializer::#method(__value)
|
||||||
#this::#last_ident)
|
),
|
||||||
|
#this::#last_ident)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
ordinary,
|
ordinary,
|
||||||
Some((
|
Some((fallthrough(quote!(from)), fallthrough(quote!(borrowed)))),
|
||||||
fallthrough(quote!(from)),
|
|
||||||
fallthrough(quote!(borrowed)),
|
|
||||||
))
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(variants, None)
|
(variants, None)
|
||||||
@@ -2128,10 +2121,7 @@ fn deserialize_identifier(
|
|||||||
(None, None, None, None)
|
(None, None, None, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (
|
let (fallthrough_arm, fallthrough_borrowed_arm) = if let Some(fallthrough) = fallthrough {
|
||||||
fallthrough_arm,
|
|
||||||
fallthrough_borrowed_arm,
|
|
||||||
) = if let Some(fallthrough) = fallthrough.clone() {
|
|
||||||
fallthrough
|
fallthrough
|
||||||
} else if is_variant {
|
} else if is_variant {
|
||||||
let fallthrough = quote! {
|
let fallthrough = quote! {
|
||||||
|
|||||||
@@ -99,12 +99,7 @@ fn test_field_identifier() {
|
|||||||
Str(&'a str),
|
Str(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(&FieldStr::Str("value"), &[Token::BorrowedStr("value")]);
|
||||||
&FieldStr::Str("value"),
|
|
||||||
&[
|
|
||||||
Token::BorrowedStr("value"),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
#[serde(field_identifier)]
|
#[serde(field_identifier)]
|
||||||
@@ -115,9 +110,7 @@ fn test_field_identifier() {
|
|||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&FieldBytes::Bytes(b"value"),
|
&FieldBytes::Bytes(b"value"),
|
||||||
&[
|
&[Token::BorrowedBytes(b"value")],
|
||||||
Token::BorrowedBytes(b"value"),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user