Added support basic deserialization in derive
This commit is contained in:
parent
5ae06bba49
commit
6627540dd6
@ -255,6 +255,13 @@ macro_rules! declare_error_trait {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Raised when a `Deserialize` struct type recieved a field with an
|
||||||
|
/// unrecognized name but the names are not actually known because of
|
||||||
|
/// flattening.
|
||||||
|
fn unknow_field_in_flattened_structure(field: &str) -> Self {
|
||||||
|
Error::custom(format_args!("unknown field `{}`", field))
|
||||||
|
}
|
||||||
|
|
||||||
/// Raised when a `Deserialize` struct type expected to receive a required
|
/// Raised when a `Deserialize` struct type expected to receive a required
|
||||||
/// field with a particular name but that field was not present in the
|
/// field with a particular name but that field was not present in the
|
||||||
/// input.
|
/// input.
|
||||||
|
@ -13,7 +13,6 @@ pub use lib::fmt::{self, Formatter};
|
|||||||
pub use lib::marker::PhantomData;
|
pub use lib::marker::PhantomData;
|
||||||
pub use lib::option::Option::{self, None, Some};
|
pub use lib::option::Option::{self, None, Some};
|
||||||
pub use lib::result::Result::{self, Err, Ok};
|
pub use lib::result::Result::{self, Err, Ok};
|
||||||
pub use lib::iter::once;
|
|
||||||
|
|
||||||
pub use self::string::from_utf8_lossy;
|
pub use self::string::from_utf8_lossy;
|
||||||
|
|
||||||
|
@ -1711,7 +1711,7 @@ fn deserialize_generated_identifier(
|
|||||||
|
|
||||||
let (ignore_variant, fallthrough, want_value) = if is_variant || cattrs.deny_unknown_fields() {
|
let (ignore_variant, fallthrough, want_value) = if is_variant || cattrs.deny_unknown_fields() {
|
||||||
(None, None, false)
|
(None, None, false)
|
||||||
} else if cattrs.unknown_fields_into().is_some() {
|
} else if cattrs.has_flatten() {
|
||||||
let ignore_variant = quote!(__other(String),);
|
let ignore_variant = quote!(__other(String),);
|
||||||
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value.to_string())));
|
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value.to_string())));
|
||||||
(Some(ignore_variant), Some(fallthrough), true)
|
(Some(ignore_variant), Some(fallthrough), true)
|
||||||
@ -2023,18 +2023,14 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we have a collect into, we also need a container that can
|
// Collect contents for flatten fields into a buffer
|
||||||
// hold the data we accumulate.
|
let let_collect = if cattrs.has_flatten() {
|
||||||
let mut let_collect = None;
|
Some(quote! {
|
||||||
for &(field, _) in fields_names.iter() {
|
let mut __collect = Vec::<_serde::private::de::Content>::new();
|
||||||
if field.attrs.collection_field() {
|
})
|
||||||
let field_ty = &field.ty;
|
} else {
|
||||||
let_collect = Some(quote! {
|
None
|
||||||
let mut __collect: #field_ty = Default::default();
|
};
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Match arms to extract a value for a field.
|
// Match arms to extract a value for a field.
|
||||||
let value_arms = fields_names
|
let value_arms = fields_names
|
||||||
@ -2073,10 +2069,10 @@ fn deserialize_map(
|
|||||||
// Visit ignored values to consume them
|
// Visit ignored values to consume them
|
||||||
let ignored_arm = if cattrs.deny_unknown_fields() {
|
let ignored_arm = if cattrs.deny_unknown_fields() {
|
||||||
None
|
None
|
||||||
} else if cattrs.unknown_fields_into().is_some() {
|
} else if cattrs.has_flatten() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
__Field::__other(__name) => {
|
__Field::__other(__name) => {
|
||||||
__collect.extend(_serde::export::once((__name, try!(_serde::de::MapAccess::next_value(&mut __map)))));
|
__collect.push((__name, try!(_serde::de::MapAccess::next_value(&mut __map))));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -2119,11 +2115,33 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let extract_collected = fields_names
|
||||||
|
.iter()
|
||||||
|
.filter(|&&(field, _)| field.attrs.flatten())
|
||||||
|
.map(|&(field, ref name)| {
|
||||||
|
let field_ty = field.ty;
|
||||||
|
quote! {
|
||||||
|
let #name: #field_ty = try!(_serde::de::Deserialize::deserialize(
|
||||||
|
_serde::private::de::FlatMapDeserializer::new(
|
||||||
|
&mut __collect,
|
||||||
|
_serde::export::PhantomData)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let collected_deny_unknown_fields = if cattrs.deny_unknown_fields() {
|
||||||
|
Some(quote! {
|
||||||
|
if let Some((__key, _)) = __collect.into_iter().next() {
|
||||||
|
return _serde::export::Err(
|
||||||
|
_serde::de::Error::unknown_field_in_flattened_structure(__key));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let result = fields_names.iter().map(|&(field, ref name)| {
|
let result = fields_names.iter().map(|&(field, ref name)| {
|
||||||
let ident = field.ident.expect("struct contains unnamed fields");
|
let ident = field.ident.expect("struct contains unnamed fields");
|
||||||
if field.attrs.collection_field() {
|
if field.attrs.skip_deserializing() && !field.attrs.flatten() {
|
||||||
quote_spanned!(Span::def_site()=> #ident: __collect)
|
|
||||||
} else if field.attrs.skip_deserializing() {
|
|
||||||
let value = Expr(expr_is_missing(field, cattrs));
|
let value = Expr(expr_is_missing(field, cattrs));
|
||||||
quote_spanned!(Span::call_site()=> #ident: #value)
|
quote_spanned!(Span::call_site()=> #ident: #value)
|
||||||
} else {
|
} else {
|
||||||
@ -2164,6 +2182,10 @@ fn deserialize_map(
|
|||||||
|
|
||||||
#(#extract_values)*
|
#(#extract_values)*
|
||||||
|
|
||||||
|
#(#extract_collected)*
|
||||||
|
|
||||||
|
#collected_deny_unknown_fields
|
||||||
|
|
||||||
_serde::export::Ok(#result)
|
_serde::export::Ok(#result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -925,7 +925,7 @@ fn serialize_struct_visitor(
|
|||||||
let span = Span::def_site().located_at(field.original.span());
|
let span = Span::def_site().located_at(field.original.span());
|
||||||
let ser = if field.attrs.flatten() {
|
let ser = if field.attrs.flatten() {
|
||||||
quote! {
|
quote! {
|
||||||
try!((#field_expr).serialize(_serde::private::ser::FlatSerializer(&mut __serde_state)));
|
try!((#field_expr).serialize(_serde::private::ser::FlatSerializer::new(&mut __serde_state)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let func = struct_trait.serialize_field(span);
|
let func = struct_trait.serialize_field(span);
|
||||||
|
Loading…
Reference in New Issue
Block a user