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:
John Baublitz
2017-03-18 12:22:27 -04:00
committed by David Tolnay
parent c488cec641
commit bc946e4fd7
8 changed files with 223 additions and 48 deletions
+28 -19
View File
@@ -61,28 +61,37 @@ fn needs_serialize_bound(attrs: &attr::Field) -> bool {
}
fn serialize_body(item: &Item, generics: &syn::Generics) -> Fragment {
match item.body {
Body::Enum(ref variants) => {
serialize_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(in_ty) = item.attrs.into_type() {
serialize_into(in_ty)
} else {
match item.body {
Body::Enum(ref variants) => {
serialize_item_enum(&item.ident, generics, variants, &item.attrs)
}
serialize_struct(&item.ident, generics, fields, &item.attrs)
}
Body::Struct(Style::Tuple, 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");
}
serialize_struct(&item.ident, generics, fields, &item.attrs)
}
Body::Struct(Style::Tuple, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
panic!("tuple struct has named fields");
}
serialize_tuple_struct(&item.ident, generics, fields, &item.attrs)
}
Body::Struct(Style::Newtype, ref fields) => {
serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs)
}
Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs),
}
}
}
serialize_tuple_struct(&item.ident, generics, fields, &item.attrs)
}
Body::Struct(Style::Newtype, ref fields) => {
serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs)
}
Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs),
fn serialize_into(into_type: &syn::Ty) -> Fragment {
quote_block! {
let cloned_val: #into_type = _serde::export::convert::Into::into(_serde::export::clone::Clone::clone(self));
_serde::Serialize::serialize(&cloned_val, _serializer)
}
}