mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 05:31:02 +00:00
Merge pull request #1124 from serde-rs/in-place
Rename deserialize_from to deserialize_in_place
This commit is contained in:
+21
-21
@@ -15,7 +15,7 @@ use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, Va
|
|||||||
use de::MapAccess;
|
use de::MapAccess;
|
||||||
|
|
||||||
use de::from_primitive::FromPrimitive;
|
use de::from_primitive::FromPrimitive;
|
||||||
use private::de::DeserializeFromSeed;
|
use private::de::InPlaceSeed;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use private::de::size_hint;
|
use private::de::size_hint;
|
||||||
@@ -213,7 +213,7 @@ impl<'de> Deserialize<'de> for char {
|
|||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
struct StringVisitor;
|
struct StringVisitor;
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
struct StringFromVisitor<'a>(&'a mut String);
|
struct StringInPlaceVisitor<'a>(&'a mut String);
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'de> Visitor<'de> for StringVisitor {
|
impl<'de> Visitor<'de> for StringVisitor {
|
||||||
@@ -259,7 +259,7 @@ impl<'de> Visitor<'de> for StringVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, 'de> Visitor<'de> for StringFromVisitor<'a> {
|
impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
@@ -320,11 +320,11 @@ impl<'de> Deserialize<'de> for String {
|
|||||||
deserializer.deserialize_string(StringVisitor)
|
deserializer.deserialize_string(StringVisitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_string(StringFromVisitor(self))
|
deserializer.deserialize_string(StringInPlaceVisitor(place))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,10 +533,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The Some variant's repr is opaque, so we can't play cute tricks with its
|
// The Some variant's repr is opaque, so we can't play cute tricks with its
|
||||||
// tag to have deserialize_from build the content in place unconditionally.
|
// tag to have deserialize_in_place build the content in place unconditionally.
|
||||||
//
|
//
|
||||||
// FIXME: investigate whether branching on the old value being Some to
|
// FIXME: investigate whether branching on the old value being Some to
|
||||||
// deserialize_from the value is profitable (probably data-dependent?)
|
// deserialize_in_place the value is profitable (probably data-dependent?)
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -627,13 +627,13 @@ macro_rules! seq_impl {
|
|||||||
deserializer.deserialize_seq(visitor)
|
deserializer.deserialize_seq(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct SeqVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
|
struct SeqInPlaceVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
|
||||||
|
|
||||||
impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<'a, T $(, $typaram)*>
|
impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqInPlaceVisitor<'a, T $(, $typaram)*>
|
||||||
where
|
where
|
||||||
T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
|
T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
|
||||||
$($typaram: $bound1 $(+ $bound2)*,)*
|
$($typaram: $bound1 $(+ $bound2)*,)*
|
||||||
@@ -661,7 +661,7 @@ macro_rules! seq_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.deserialize_seq(SeqVisitor(self))
|
deserializer.deserialize_seq(SeqInPlaceVisitor(place))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -736,7 +736,7 @@ seq_impl!(
|
|||||||
struct ArrayVisitor<A> {
|
struct ArrayVisitor<A> {
|
||||||
marker: PhantomData<A>,
|
marker: PhantomData<A>,
|
||||||
}
|
}
|
||||||
struct ArrayFromVisitor<'a, A: 'a>(&'a mut A);
|
struct ArrayInPlaceVisitor<'a, A: 'a>(&'a mut A);
|
||||||
|
|
||||||
impl<A> ArrayVisitor<A> {
|
impl<A> ArrayVisitor<A> {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
@@ -799,7 +799,7 @@ macro_rules! array_impls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'de, T> Visitor<'de> for ArrayFromVisitor<'a, [T; $len]>
|
impl<'a, 'de, T> Visitor<'de> for ArrayInPlaceVisitor<'a, [T; $len]>
|
||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
@@ -816,7 +816,7 @@ macro_rules! array_impls {
|
|||||||
{
|
{
|
||||||
let mut fail_idx = None;
|
let mut fail_idx = None;
|
||||||
for (idx, dest) in self.0[..].iter_mut().enumerate() {
|
for (idx, dest) in self.0[..].iter_mut().enumerate() {
|
||||||
if try!(seq.next_element_seed(DeserializeFromSeed(dest))).is_none() {
|
if try!(seq.next_element_seed(InPlaceSeed(dest))).is_none() {
|
||||||
fail_idx = Some(idx);
|
fail_idx = Some(idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -839,11 +839,11 @@ macro_rules! array_impls {
|
|||||||
deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
|
deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_tuple($len, ArrayFromVisitor(self))
|
deserializer.deserialize_tuple($len, ArrayInPlaceVisitor(place))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@@ -928,13 +928,13 @@ macro_rules! tuple_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
struct TupleVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
|
struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
|
||||||
|
|
||||||
impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<'a, $($name,)+> {
|
impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> {
|
||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
@@ -948,7 +948,7 @@ macro_rules! tuple_impls {
|
|||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
$(
|
$(
|
||||||
if try!(seq.next_element_seed(DeserializeFromSeed(&mut (self.0).$n))).is_none() {
|
if try!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
|
||||||
return Err(Error::invalid_length($n, &self));
|
return Err(Error::invalid_length($n, &self));
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@@ -957,7 +957,7 @@ macro_rules! tuple_impls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.deserialize_tuple($len, TupleVisitor(self))
|
deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
|
|||||||
+3
-3
@@ -518,18 +518,18 @@ pub trait Deserialize<'de>: Sized {
|
|||||||
/// when the next deserialization occurs.
|
/// when the next deserialization occurs.
|
||||||
///
|
///
|
||||||
/// If you manually implement this, your recursive deserializations should
|
/// If you manually implement this, your recursive deserializations should
|
||||||
/// use `deserialize_from`.
|
/// use `deserialize_in_place`.
|
||||||
///
|
///
|
||||||
/// This method is stable and an official public API, but hidden from the
|
/// This method is stable and an official public API, but hidden from the
|
||||||
/// documentation because it is almost never what newbies are looking for.
|
/// documentation because it is almost never what newbies are looking for.
|
||||||
/// Showing it in rustdoc would cause it to be featured more prominently
|
/// Showing it in rustdoc would cause it to be featured more prominently
|
||||||
/// than it deserves.
|
/// than it deserves.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
where D: Deserializer<'de>
|
where D: Deserializer<'de>
|
||||||
{
|
{
|
||||||
// Default implementation just delegates to `deserialize` impl.
|
// Default implementation just delegates to `deserialize` impl.
|
||||||
*self = Deserialize::deserialize(deserializer)?;
|
*place = Deserialize::deserialize(deserializer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2010,12 +2010,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A DeserializeSeed helper for implementing deserialize_from Visitors.
|
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
||||||
///
|
///
|
||||||
/// Wraps a mutable reference and calls deserialize_from on it.
|
/// Wraps a mutable reference and calls deserialize_in_place on it.
|
||||||
pub struct DeserializeFromSeed<'a, T: 'a>(pub &'a mut T);
|
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
|
||||||
|
|
||||||
impl<'a, 'de, T> DeserializeSeed<'de> for DeserializeFromSeed<'a, T>
|
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
|
||||||
where T: Deserialize<'de>,
|
where T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
type Value = ();
|
type Value = ();
|
||||||
@@ -2023,6 +2023,6 @@ impl<'a, 'de, T> DeserializeSeed<'de> for DeserializeFromSeed<'a, T>
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
self.0.deserialize_from(deserializer)
|
T::deserialize_in_place(deserializer, self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ travis-ci = { repository = "serde-rs/serde" }
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
deserialize_from = []
|
deserialize_in_place = []
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
|
|||||||
+77
-77
@@ -40,7 +40,7 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let fn_deserialize_from = deserialize_from_body(&cont, ¶ms);
|
let fn_deserialize_in_place = deserialize_in_place_body(&cont, ¶ms);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
@@ -51,7 +51,7 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
|
|||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
|
|
||||||
#fn_deserialize_from
|
#fn_deserialize_in_place
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -249,10 +249,10 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_body(cont: &Container, params: &Parameters) -> Option<Stmts> {
|
fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> {
|
||||||
// Only remote derives have getters, and we do not generate deserialize_from
|
// Only remote derives have getters, and we do not generate
|
||||||
// for remote derives.
|
// deserialize_in_place for remote derives.
|
||||||
assert!(!params.has_getter);
|
assert!(!params.has_getter);
|
||||||
|
|
||||||
if cont.attrs.from_type().is_some()
|
if cont.attrs.from_type().is_some()
|
||||||
@@ -264,11 +264,11 @@ fn deserialize_from_body(cont: &Container, params: &Parameters) -> Option<Stmts>
|
|||||||
|
|
||||||
let code = match cont.body {
|
let code = match cont.body {
|
||||||
Body::Struct(Style::Struct, ref fields) => {
|
Body::Struct(Style::Struct, ref fields) => {
|
||||||
deserialize_from_struct(None, params, fields, &cont.attrs, None, Untagged::No)
|
deserialize_struct_in_place(None, params, fields, &cont.attrs, None, Untagged::No)
|
||||||
}
|
}
|
||||||
Body::Struct(Style::Tuple, ref fields) |
|
Body::Struct(Style::Tuple, ref fields) |
|
||||||
Body::Struct(Style::Newtype, ref fields) => {
|
Body::Struct(Style::Newtype, ref fields) => {
|
||||||
deserialize_from_tuple(None, params, fields, &cont.attrs, None)
|
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
|
||||||
}
|
}
|
||||||
Body::Enum(_) | Body::Struct(Style::Unit, _) => {
|
Body::Enum(_) | Body::Struct(Style::Unit, _) => {
|
||||||
return None;
|
return None;
|
||||||
@@ -278,19 +278,19 @@ fn deserialize_from_body(cont: &Container, params: &Parameters) -> Option<Stmts>
|
|||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
let stmts = Stmts(code);
|
let stmts = Stmts(code);
|
||||||
|
|
||||||
let fn_deserialize_from = quote_block! {
|
let fn_deserialize_in_place = quote_block! {
|
||||||
fn deserialize_from<__D>(&mut self, __deserializer: __D) -> _serde::export::Result<(), __D::Error>
|
fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::export::Result<(), __D::Error>
|
||||||
where __D: _serde::Deserializer<#delife>
|
where __D: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
#stmts
|
#stmts
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Stmts(fn_deserialize_from))
|
Some(Stmts(fn_deserialize_in_place))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "deserialize_from"))]
|
#[cfg(not(feature = "deserialize_in_place"))]
|
||||||
fn deserialize_from_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> {
|
fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,8 +425,8 @@ fn deserialize_tuple(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_tuple(
|
fn deserialize_tuple_in_place(
|
||||||
variant_ident: Option<&syn::Ident>,
|
variant_ident: Option<&syn::Ident>,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
@@ -446,16 +446,16 @@ fn deserialize_from_tuple(
|
|||||||
let nfields = fields.len();
|
let nfields = fields.len();
|
||||||
|
|
||||||
let visit_newtype_struct = if !is_enum && nfields == 1 {
|
let visit_newtype_struct = if !is_enum && nfields == 1 {
|
||||||
Some(deserialize_from_newtype_struct(params, &fields[0]))
|
Some(deserialize_newtype_struct_in_place(params, &fields[0]))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_seq = Stmts(deserialize_from_seq(params, fields, cattrs));
|
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs));
|
||||||
|
|
||||||
let visitor_expr = quote! {
|
let visitor_expr = quote! {
|
||||||
__Visitor {
|
__Visitor {
|
||||||
dest: self,
|
place: __place,
|
||||||
lifetime: _serde::export::PhantomData,
|
lifetime: _serde::export::PhantomData,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -481,17 +481,17 @@ fn deserialize_from_tuple(
|
|||||||
quote!(mut __seq)
|
quote!(mut __seq)
|
||||||
};
|
};
|
||||||
|
|
||||||
let de_from_impl_generics = de_impl_generics.with_dest();
|
let in_place_impl_generics = de_impl_generics.in_place();
|
||||||
let de_from_ty_generics = de_ty_generics.with_dest();
|
let in_place_ty_generics = de_ty_generics.in_place();
|
||||||
let dest_life = dest_lifetime();
|
let place_life = place_lifetime();
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
struct __Visitor #de_from_impl_generics #where_clause {
|
struct __Visitor #in_place_impl_generics #where_clause {
|
||||||
dest: &#dest_life mut #this #ty_generics,
|
place: &#place_life mut #this #ty_generics,
|
||||||
lifetime: _serde::export::PhantomData<&#delife ()>,
|
lifetime: _serde::export::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
|
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
|
||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
|
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
|
||||||
@@ -612,8 +612,8 @@ fn deserialize_seq(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_seq(
|
fn deserialize_seq_in_place(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
@@ -636,7 +636,7 @@ fn deserialize_from_seq(
|
|||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let default = Expr(expr_is_missing(&field, cattrs));
|
let default = Expr(expr_is_missing(&field, cattrs));
|
||||||
quote! {
|
quote! {
|
||||||
self.dest.#field_name = #default;
|
self.place.#field_name = #default;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let return_invalid_length = quote! {
|
let return_invalid_length = quote! {
|
||||||
@@ -646,7 +646,7 @@ fn deserialize_from_seq(
|
|||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
|
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
|
||||||
_serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)))
|
_serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
|
||||||
{
|
{
|
||||||
#return_invalid_length
|
#return_invalid_length
|
||||||
}
|
}
|
||||||
@@ -659,7 +659,7 @@ fn deserialize_from_seq(
|
|||||||
#wrapper
|
#wrapper
|
||||||
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
|
||||||
_serde::export::Some(__wrap) => {
|
_serde::export::Some(__wrap) => {
|
||||||
self.dest.#field_name = __wrap.value;
|
self.place.#field_name = __wrap.value;
|
||||||
}
|
}
|
||||||
_serde::export::None => {
|
_serde::export::None => {
|
||||||
#return_invalid_length
|
#return_invalid_length
|
||||||
@@ -741,12 +741,12 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_newtype_struct(
|
fn deserialize_newtype_struct_in_place(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
field: &Field
|
field: &Field
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
// We do not generate deserialize_from if every field has a deserialize_with.
|
// We do not generate deserialize_in_place if every field has a deserialize_with.
|
||||||
assert!(field.attrs.deserialize_with().is_none());
|
assert!(field.attrs.deserialize_with().is_none());
|
||||||
|
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -756,7 +756,7 @@ fn deserialize_from_newtype_struct(
|
|||||||
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
|
||||||
where __E: _serde::Deserializer<#delife>
|
where __E: _serde::Deserializer<#delife>
|
||||||
{
|
{
|
||||||
_serde::Deserialize::deserialize_from(&mut self.dest.0, __e)
|
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -883,8 +883,8 @@ fn deserialize_struct(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_struct(
|
fn deserialize_struct_in_place(
|
||||||
variant_ident: Option<&syn::Ident>,
|
variant_ident: Option<&syn::Ident>,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
@@ -903,17 +903,17 @@ fn deserialize_from_struct(
|
|||||||
None => format!("struct {}", params.type_name()),
|
None => format!("struct {}", params.type_name()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_seq = Stmts(deserialize_from_seq(params, fields, cattrs));
|
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs));
|
||||||
|
|
||||||
let (field_visitor, fields_stmt, visit_map) =
|
let (field_visitor, fields_stmt, visit_map) =
|
||||||
deserialize_from_struct_visitor(params, fields, cattrs);
|
deserialize_struct_in_place_visitor(params, fields, cattrs);
|
||||||
let field_visitor = Stmts(field_visitor);
|
let field_visitor = Stmts(field_visitor);
|
||||||
let fields_stmt = Stmts(fields_stmt);
|
let fields_stmt = Stmts(fields_stmt);
|
||||||
let visit_map = Stmts(visit_map);
|
let visit_map = Stmts(visit_map);
|
||||||
|
|
||||||
let visitor_expr = quote! {
|
let visitor_expr = quote! {
|
||||||
__Visitor {
|
__Visitor {
|
||||||
dest: self,
|
place: __place,
|
||||||
lifetime: _serde::export::PhantomData,
|
lifetime: _serde::export::PhantomData,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -958,19 +958,19 @@ fn deserialize_from_struct(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let de_from_impl_generics = de_impl_generics.with_dest();
|
let in_place_impl_generics = de_impl_generics.in_place();
|
||||||
let de_from_ty_generics = de_ty_generics.with_dest();
|
let in_place_ty_generics = de_ty_generics.in_place();
|
||||||
let dest_life = dest_lifetime();
|
let place_life = place_lifetime();
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
#field_visitor
|
#field_visitor
|
||||||
|
|
||||||
struct __Visitor #de_from_impl_generics #where_clause {
|
struct __Visitor #in_place_impl_generics #where_clause {
|
||||||
dest: &#dest_life mut #this #ty_generics,
|
place: &#place_life mut #this #ty_generics,
|
||||||
lifetime: _serde::export::PhantomData<&#delife ()>,
|
lifetime: _serde::export::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
|
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
|
||||||
type Value = ();
|
type Value = ();
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
|
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
|
||||||
@@ -2121,8 +2121,8 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_struct_visitor(
|
fn deserialize_struct_in_place_visitor(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
@@ -2143,13 +2143,13 @@ fn deserialize_from_struct_visitor(
|
|||||||
|
|
||||||
let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
|
let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
|
||||||
|
|
||||||
let visit_map = deserialize_from_map(params, fields, cattrs);
|
let visit_map = deserialize_map_in_place(params, fields, cattrs);
|
||||||
|
|
||||||
(field_visitor, fields_stmt, visit_map)
|
(field_visitor, fields_stmt, visit_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_from_map(
|
fn deserialize_map_in_place(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
@@ -2161,7 +2161,7 @@ fn deserialize_from_map(
|
|||||||
.map(|(i, field)| (field, field_i(i)))
|
.map(|(i, field)| (field, field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// For deserialize_from, declare booleans for each field that will be deserialized.
|
// For deserialize_in_place, declare booleans for each field that will be deserialized.
|
||||||
let let_flags = fields_names
|
let let_flags = fields_names
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
@@ -2183,7 +2183,7 @@ fn deserialize_from_map(
|
|||||||
let visit = match field.attrs.deserialize_with() {
|
let visit = match field.attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)))
|
try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
@@ -2191,7 +2191,7 @@ fn deserialize_from_map(
|
|||||||
params, field.ty, path);
|
params, field.ty, path);
|
||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
self.dest.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
self.place.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2245,7 +2245,7 @@ fn deserialize_from_map(
|
|||||||
|&(field, ref name)| {
|
|&(field, ref name)| {
|
||||||
let missing_expr = expr_is_missing(&field, cattrs);
|
let missing_expr = expr_is_missing(&field, cattrs);
|
||||||
// If missing_expr unconditionally returns an error, don't try
|
// If missing_expr unconditionally returns an error, don't try
|
||||||
// to assign its value to self.dest. Maybe this could be handled
|
// to assign its value to self.place. Maybe this could be handled
|
||||||
// more elegantly.
|
// more elegantly.
|
||||||
if missing_expr.as_ref().as_str().starts_with("return ") {
|
if missing_expr.as_ref().as_str().starts_with("return ") {
|
||||||
let missing_expr = Stmts(missing_expr);
|
let missing_expr = Stmts(missing_expr);
|
||||||
@@ -2259,7 +2259,7 @@ fn deserialize_from_map(
|
|||||||
let missing_expr = Expr(missing_expr);
|
let missing_expr = Expr(missing_expr);
|
||||||
quote! {
|
quote! {
|
||||||
if !#name {
|
if !#name {
|
||||||
self.dest.#field_name = #missing_expr;
|
self.place.#field_name = #missing_expr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2442,8 +2442,8 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct DeImplGenerics<'a>(&'a Parameters);
|
struct DeImplGenerics<'a>(&'a Parameters);
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
struct DeFromImplGenerics<'a>(&'a Parameters);
|
struct InPlaceImplGenerics<'a>(&'a Parameters);
|
||||||
|
|
||||||
impl<'a> ToTokens for DeImplGenerics<'a> {
|
impl<'a> ToTokens for DeImplGenerics<'a> {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
@@ -2456,20 +2456,20 @@ impl<'a> ToTokens for DeImplGenerics<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
impl<'a> ToTokens for DeFromImplGenerics<'a> {
|
impl<'a> ToTokens for InPlaceImplGenerics<'a> {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
let dest_lifetime = dest_lifetime();
|
let place_lifetime = place_lifetime();
|
||||||
let mut generics = self.0.generics.clone();
|
let mut generics = self.0.generics.clone();
|
||||||
|
|
||||||
// Add lifetime for `&'dest mut Self, and `'a: 'dest`
|
// Add lifetime for `&'place mut Self, and `'a: 'place`
|
||||||
for lifetime in &mut generics.lifetimes {
|
for lifetime in &mut generics.lifetimes {
|
||||||
lifetime.bounds.push(dest_lifetime.lifetime.clone());
|
lifetime.bounds.push(place_lifetime.lifetime.clone());
|
||||||
}
|
}
|
||||||
for generic in &mut generics.ty_params {
|
for generic in &mut generics.ty_params {
|
||||||
generic.bounds.push(syn::TyParamBound::Region(dest_lifetime.lifetime.clone()));
|
generic.bounds.push(syn::TyParamBound::Region(place_lifetime.lifetime.clone()));
|
||||||
}
|
}
|
||||||
generics.lifetimes.insert(0, dest_lifetime);
|
generics.lifetimes.insert(0, place_lifetime);
|
||||||
if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
|
if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
|
||||||
generics.lifetimes.insert(0, de_lifetime);
|
generics.lifetimes.insert(0, de_lifetime);
|
||||||
}
|
}
|
||||||
@@ -2478,16 +2478,16 @@ impl<'a> ToTokens for DeFromImplGenerics<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
impl<'a> DeImplGenerics<'a> {
|
impl<'a> DeImplGenerics<'a> {
|
||||||
fn with_dest(self) -> DeFromImplGenerics<'a> {
|
fn in_place(self) -> InPlaceImplGenerics<'a> {
|
||||||
DeFromImplGenerics(self.0)
|
InPlaceImplGenerics(self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeTyGenerics<'a>(&'a Parameters);
|
struct DeTyGenerics<'a>(&'a Parameters);
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
struct DeFromTyGenerics<'a>(&'a Parameters);
|
struct InPlaceTyGenerics<'a>(&'a Parameters);
|
||||||
|
|
||||||
impl<'a> ToTokens for DeTyGenerics<'a> {
|
impl<'a> ToTokens for DeTyGenerics<'a> {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
@@ -2502,11 +2502,11 @@ impl<'a> ToTokens for DeTyGenerics<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
impl<'a> ToTokens for DeFromTyGenerics<'a> {
|
impl<'a> ToTokens for InPlaceTyGenerics<'a> {
|
||||||
fn to_tokens(&self, tokens: &mut Tokens) {
|
fn to_tokens(&self, tokens: &mut Tokens) {
|
||||||
let mut generics = self.0.generics.clone();
|
let mut generics = self.0.generics.clone();
|
||||||
generics.lifetimes.insert(0, dest_lifetime());
|
generics.lifetimes.insert(0, place_lifetime());
|
||||||
|
|
||||||
if self.0.borrowed.de_lifetime_def().is_some() {
|
if self.0.borrowed.de_lifetime_def().is_some() {
|
||||||
generics
|
generics
|
||||||
@@ -2518,16 +2518,16 @@ impl<'a> ToTokens for DeFromTyGenerics<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
impl<'a> DeTyGenerics<'a> {
|
impl<'a> DeTyGenerics<'a> {
|
||||||
fn with_dest(self) -> DeFromTyGenerics<'a> {
|
fn in_place(self) -> InPlaceTyGenerics<'a> {
|
||||||
DeFromTyGenerics(self.0)
|
InPlaceTyGenerics(self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_from")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn dest_lifetime() -> syn::LifetimeDef {
|
fn place_lifetime() -> syn::LifetimeDef {
|
||||||
syn::LifetimeDef::new("'dest")
|
syn::LifetimeDef::new("'place")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_with_de_lifetime(params: &Parameters,)
|
fn split_with_de_lifetime(params: &Parameters,)
|
||||||
|
|||||||
@@ -195,15 +195,15 @@ where
|
|||||||
panic!("{} remaining tokens", de.remaining());
|
panic!("{} remaining tokens", de.remaining());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the same thing for deserialize_from. This isn't *great* because a no-op
|
// Do the same thing for deserialize_in_place. This isn't *great* because a
|
||||||
// impl of deserialize_from can technically succeed here. Still, this should
|
// no-op impl of deserialize_in_place can technically succeed here. Still,
|
||||||
// catch a lot of junk.
|
// this should catch a lot of junk.
|
||||||
let mut de = Deserializer::new(tokens);
|
let mut de = Deserializer::new(tokens);
|
||||||
match deserialized_val.deserialize_from(&mut de) {
|
match T::deserialize_in_place(&mut de, &mut deserialized_val) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
assert_eq!(deserialized_val, *value);
|
assert_eq!(deserialized_val, *value);
|
||||||
}
|
}
|
||||||
Err(e) => panic!("tokens failed to deserialize_from: {}", e),
|
Err(e) => panic!("tokens failed to deserialize_in_place: {}", e),
|
||||||
}
|
}
|
||||||
if de.remaining() > 0 {
|
if de.remaining() > 0 {
|
||||||
panic!("{} remaining tokens", de.remaining());
|
panic!("{} remaining tokens", de.remaining());
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ unstable = ["serde/unstable", "compiletest_rs"]
|
|||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
rustc-serialize = "0.3.16"
|
rustc-serialize = "0.3.16"
|
||||||
serde = { path = "../serde", features = ["rc"] }
|
serde = { path = "../serde", features = ["rc"] }
|
||||||
serde_derive = { path = "../serde_derive", features = ["deserialize_from"] }
|
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
||||||
serde_test = { path = "../serde_test" }
|
serde_test = { path = "../serde_test" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
Reference in New Issue
Block a user