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

Touch up borrowed field identifiers PR #1959

Merged
merged 9 commits into from Jan 23, 2021
1 change: 0 additions & 1 deletion serde/src/de/mod.rs
Expand Up @@ -116,7 +116,6 @@ use lib::*;

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
pub mod value;

mod from_primitive;
Expand Down
195 changes: 81 additions & 114 deletions serde/src/de/value.rs
Expand Up @@ -25,15 +25,13 @@ use lib::*;

use self::private::{First, Second};
use __private::de::size_hint;
use de::{self, Expected, IntoDeserializer, SeqAccess};
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
use ser;

////////////////////////////////////////////////////////////////////////////////

/// For structs that contain a PhantomData. We do not want the trait
/// bound `E: Clone` inferred by derive(Clone).
#[doc(hidden)]
#[macro_export]
// For structs that contain a PhantomData. We do not want the trait
// bound `E: Clone` inferred by derive(Clone).
macro_rules! impl_copy_clone {
($ty:ident $(<$lifetime:tt>)*) => {
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
Expand All @@ -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
Expand Down Expand Up @@ -763,19 +665,84 @@ where

////////////////////////////////////////////////////////////////////////////////

forward_deserializer!(
/// A deserializer holding a `&[u8]`. Always call [`Visitor::visit_bytes`]
///
/// [`Visitor::visit_bytes`]: ../struct.Visitor.html#method.visit_bytes
ref BytesDeserializer<'a>(&'a [u8]) => visit_bytes
);
forward_deserializer!(
/// A deserializer holding a `&[u8]` with a lifetime tied to another
/// deserializer. Always call [`Visitor::visit_borrowed_bytes`]
///
/// [`Visitor::visit_borrowed_bytes`]: ../struct.Visitor.html#method.visit_borrowed_bytes
borrowed BorrowedBytesDeserializer(&'de [u8]) => visit_borrowed_bytes
);
/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
#[derive(Debug)]
pub struct BytesDeserializer<'a, E> {
value: &'a [u8],
marker: PhantomData<E>,
}

impl<'a, E> BytesDeserializer<'a, E> {
/// Create a new deserializer from the given bytes.
pub fn new(value: &'a [u8]) -> Self {
BytesDeserializer {
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
}
}

////////////////////////////////////////////////////////////////////////////////

Expand Down
1 change: 0 additions & 1 deletion serde/src/lib.rs
Expand Up @@ -258,7 +258,6 @@ mod macros;
#[macro_use]
mod integer128;

#[macro_use]
pub mod de;
pub mod ser;

Expand Down
63 changes: 58 additions & 5 deletions serde/src/private/de.rs
@@ -1,7 +1,7 @@
use lib::*;

use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
use de::value::{BytesDeserializer, BorrowedBytesDeserializer};

#[cfg(any(feature = "std", feature = "alloc"))]
use de::{MapAccess, Unexpected};
Expand Down Expand Up @@ -2561,8 +2561,55 @@ where
}
}

forward_deserializer!(ref StrDeserializer<'a>(&'a str) => visit_str);
forward_deserializer!(borrowed BorrowedStrDeserializer(&'de str) => visit_borrowed_str);
pub struct StrDeserializer<'a, E> {
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
where
Expand All @@ -2572,11 +2619,17 @@ where
type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>;

fn from(self) -> Self::Deserializer {
StrDeserializer::new(self)
StrDeserializer {
value: self,
marker: PhantomData,
}
}

fn borrowed(self) -> Self::BorrowedDeserializer {
BorrowedStrDeserializer::new(self)
BorrowedStrDeserializer {
value: self,
marker: PhantomData,
}
}
}

Expand Down
38 changes: 14 additions & 24 deletions serde_derive/src/de.rs
Expand Up @@ -1893,23 +1893,20 @@ fn deserialize_generated_identifier(
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
(
Some(ignore_variant),
Some((fallthrough.clone(), fallthrough))
Some((fallthrough.clone(), fallthrough)),
)
} else if let Some(other_idx) = other_idx {
let ignore_variant = fields[other_idx].1.clone();
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() {
(None, None)
} else {
let ignore_variant = quote!(__ignore,);
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
(
Some(ignore_variant),
Some((fallthrough.clone(), fallthrough))
Some((fallthrough.clone(), fallthrough)),
)
};

Expand Down Expand Up @@ -1973,25 +1970,21 @@ fn deserialize_custom_identifier(
if last.attrs.other() {
let ordinary = &variants[..variants.len() - 1];
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 {
let ordinary = &variants[..variants.len() - 1];
let fallthrough = |method| quote! {
_serde::__private::Result::map(
_serde::Deserialize::deserialize(
_serde::__private::de::IdentifierDeserializer::#method(__value)
),
#this::#last_ident)
let fallthrough = |method| {
quote! {
_serde::__private::Result::map(
_serde::Deserialize::deserialize(
_serde::__private::de::IdentifierDeserializer::#method(__value)
),
#this::#last_ident)
}
};
(
ordinary,
Some((
fallthrough(quote!(from)),
fallthrough(quote!(borrowed)),
))
Some((fallthrough(quote!(from)), fallthrough(quote!(borrowed)))),
)
} else {
(variants, None)
Expand Down Expand Up @@ -2128,10 +2121,7 @@ fn deserialize_identifier(
(None, None, None, None)
};

let (
fallthrough_arm,
fallthrough_borrowed_arm,
) = if let Some(fallthrough) = fallthrough.clone() {
let (fallthrough_arm, fallthrough_borrowed_arm) = if let Some(fallthrough) = fallthrough {
fallthrough
} else if is_variant {
let fallthrough = quote! {
Expand Down