mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 19:47:55 +00:00
Macro attributes to specify From and Into trait types for structs and enums (#817)
* serde macro support for type conversions through From and Into trait * Revisions requested by dtolnay * Additional changes requested by dtolnay
This commit is contained in:
committed by
David Tolnay
parent
c488cec641
commit
bc946e4fd7
+39
-27
@@ -85,36 +85,48 @@ fn requires_default(attrs: &attr::Field) -> bool {
|
||||
}
|
||||
|
||||
fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment {
|
||||
match item.body {
|
||||
Body::Enum(ref variants) => {
|
||||
deserialize_item_enum(&item.ident, generics, variants, &item.attrs)
|
||||
}
|
||||
Body::Struct(Style::Struct, ref fields) => {
|
||||
if fields.iter().any(|field| field.ident.is_none()) {
|
||||
panic!("struct has unnamed fields");
|
||||
if let Some(fr_ty) = item.attrs.from_type() {
|
||||
deserialize_from(fr_ty)
|
||||
} else {
|
||||
match item.body {
|
||||
Body::Enum(ref variants) => {
|
||||
deserialize_item_enum(&item.ident, generics, variants, &item.attrs)
|
||||
}
|
||||
|
||||
deserialize_struct(&item.ident,
|
||||
None,
|
||||
generics,
|
||||
fields,
|
||||
&item.attrs,
|
||||
None)
|
||||
}
|
||||
Body::Struct(Style::Tuple, ref fields) |
|
||||
Body::Struct(Style::Newtype, ref fields) => {
|
||||
if fields.iter().any(|field| field.ident.is_some()) {
|
||||
panic!("tuple struct has named fields");
|
||||
Body::Struct(Style::Struct, ref fields) => {
|
||||
if fields.iter().any(|field| field.ident.is_none()) {
|
||||
panic!("struct has unnamed fields");
|
||||
}
|
||||
deserialize_struct(&item.ident,
|
||||
None,
|
||||
generics,
|
||||
fields,
|
||||
&item.attrs,
|
||||
None)
|
||||
}
|
||||
|
||||
deserialize_tuple(&item.ident,
|
||||
None,
|
||||
generics,
|
||||
fields,
|
||||
&item.attrs,
|
||||
None)
|
||||
Body::Struct(Style::Tuple, ref fields) |
|
||||
Body::Struct(Style::Newtype, ref fields) => {
|
||||
if fields.iter().any(|field| field.ident.is_some()) {
|
||||
panic!("tuple struct has named fields");
|
||||
}
|
||||
deserialize_tuple(&item.ident,
|
||||
None,
|
||||
generics,
|
||||
fields,
|
||||
&item.attrs,
|
||||
None)
|
||||
}
|
||||
Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_from(from_type: &syn::Ty) -> Fragment {
|
||||
quote_block! {
|
||||
let de_val = <#from_type as _serde::Deserialize>::deserialize(deserializer);
|
||||
match de_val {
|
||||
_serde::export::Result::Ok(from_in) => _serde::export::Result::Ok(_serde::export::convert::From::from(from_in)),
|
||||
_serde::export::Result::Err(e) => _serde::export::Result::Err(e)
|
||||
}
|
||||
Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user