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
|
||||
/// field with a particular name but that field was not present in the
|
||||
/// input.
|
||||
|
@ -13,7 +13,6 @@ pub use lib::fmt::{self, Formatter};
|
||||
pub use lib::marker::PhantomData;
|
||||
pub use lib::option::Option::{self, None, Some};
|
||||
pub use lib::result::Result::{self, Err, Ok};
|
||||
pub use lib::iter::once;
|
||||
|
||||
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() {
|
||||
(None, None, false)
|
||||
} else if cattrs.unknown_fields_into().is_some() {
|
||||
} else if cattrs.has_flatten() {
|
||||
let ignore_variant = quote!(__other(String),);
|
||||
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value.to_string())));
|
||||
(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
|
||||
// hold the data we accumulate.
|
||||
let mut let_collect = None;
|
||||
for &(field, _) in fields_names.iter() {
|
||||
if field.attrs.collection_field() {
|
||||
let field_ty = &field.ty;
|
||||
let_collect = Some(quote! {
|
||||
let mut __collect: #field_ty = Default::default();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Collect contents for flatten fields into a buffer
|
||||
let let_collect = if cattrs.has_flatten() {
|
||||
Some(quote! {
|
||||
let mut __collect = Vec::<_serde::private::de::Content>::new();
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Match arms to extract a value for a field.
|
||||
let value_arms = fields_names
|
||||
@ -2073,10 +2069,10 @@ fn deserialize_map(
|
||||
// Visit ignored values to consume them
|
||||
let ignored_arm = if cattrs.deny_unknown_fields() {
|
||||
None
|
||||
} else if cattrs.unknown_fields_into().is_some() {
|
||||
} else if cattrs.has_flatten() {
|
||||
Some(quote! {
|
||||
__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 {
|
||||
@ -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 ident = field.ident.expect("struct contains unnamed fields");
|
||||
if field.attrs.collection_field() {
|
||||
quote_spanned!(Span::def_site()=> #ident: __collect)
|
||||
} else if field.attrs.skip_deserializing() {
|
||||
if field.attrs.skip_deserializing() && !field.attrs.flatten() {
|
||||
let value = Expr(expr_is_missing(field, cattrs));
|
||||
quote_spanned!(Span::call_site()=> #ident: #value)
|
||||
} else {
|
||||
@ -2164,6 +2182,10 @@ fn deserialize_map(
|
||||
|
||||
#(#extract_values)*
|
||||
|
||||
#(#extract_collected)*
|
||||
|
||||
#collected_deny_unknown_fields
|
||||
|
||||
_serde::export::Ok(#result)
|
||||
}
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ fn serialize_struct_visitor(
|
||||
let span = Span::def_site().located_at(field.original.span());
|
||||
let ser = if field.attrs.flatten() {
|
||||
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 {
|
||||
let func = struct_trait.serialize_field(span);
|
||||
|
Loading…
Reference in New Issue
Block a user