Skip to content

Commit

Permalink
Merge pull request #1959 from serde-rs/1917
Browse files Browse the repository at this point in the history
Touch up borrowed field identifiers PR
  • Loading branch information
dtolnay committed Jan 23, 2021
2 parents ba46f45 + 0b5c56b commit 8f09aea
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 154 deletions.
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

0 comments on commit 8f09aea

Please sign in to comment.