From cfd5d488410d980f7e8311ac4e79f81f39b15102 Mon Sep 17 00:00:00 2001 From: rsdy Date: Thu, 22 Sep 2022 10:55:38 +0100 Subject: [PATCH] Extract struct handling for ser/de macros --- instant-xml-macros/src/de.rs | 61 ++++++++++++++++++++--------------- instant-xml-macros/src/ser.rs | 33 +++++++++++-------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/instant-xml-macros/src/de.rs b/instant-xml-macros/src/de.rs index 15d1843..924f4a0 100644 --- a/instant-xml-macros/src/de.rs +++ b/instant-xml-macros/src/de.rs @@ -5,7 +5,20 @@ use super::{discard_lifetimes, ContainerMeta, FieldMeta, Namespace}; pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream { let ident = &input.ident; - let container_meta = ContainerMeta::from_derive(input); + let meta = ContainerMeta::from_derive(input); + + match &input.data { + syn::Data::Struct(ref data) => deserialize_struct(input, data, meta, ident), + _ => todo!(), + } +} + +fn deserialize_struct( + input: &syn::DeriveInput, + data: &syn::DataStruct, + container_meta: ContainerMeta, + ident: &Ident, +) -> TokenStream { let default_namespace = match &container_meta.ns.uri { Some(ns) => quote!(#ns), None => quote!(""), @@ -35,33 +48,28 @@ pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream { let mut declare_values = TokenStream::new(); let mut return_val = TokenStream::new(); - match &input.data { - syn::Data::Struct(ref data) => { - match data.fields { - syn::Fields::Named(ref fields) => { - fields.named.iter().enumerate().for_each(|(index, field)| { - let field_meta = FieldMeta::from_field(field); - let tokens = match field_meta.attribute { - true => &mut attributes_tokens, - false => &mut elements_tokens, - }; + match data.fields { + syn::Fields::Named(ref fields) => { + fields.named.iter().enumerate().for_each(|(index, field)| { + let field_meta = FieldMeta::from_field(field); + let tokens = match field_meta.attribute { + true => &mut attributes_tokens, + false => &mut elements_tokens, + }; - process_field( - field, - index, - &mut declare_values, - &mut return_val, - tokens, - field_meta, - &container_meta, - ); - }); - } - syn::Fields::Unnamed(_) => panic!("unamed"), - syn::Fields::Unit => {} - }; + process_field( + field, + index, + &mut declare_values, + &mut return_val, + tokens, + field_meta, + &container_meta, + ); + }); } - _ => todo!(), + syn::Fields::Unnamed(_) => panic!("unamed"), + syn::Fields::Unit => {} }; // Elements @@ -80,6 +88,7 @@ pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream { Some(name) => quote!(#name), None => ident.to_string().into_token_stream(), }; + quote!( impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { fn deserialize<'cx>(deserializer: &'cx mut ::instant_xml::Deserializer<'cx, 'xml>) -> Result { diff --git a/instant-xml-macros/src/ser.rs b/instant-xml-macros/src/ser.rs index 709f12a..c20c29a 100644 --- a/instant-xml-macros/src/ser.rs +++ b/instant-xml-macros/src/ser.rs @@ -7,22 +7,29 @@ use crate::Namespace; use super::{discard_lifetimes, ContainerMeta, FieldMeta}; pub fn to_xml(input: &syn::DeriveInput) -> proc_macro2::TokenStream { - let mut body = TokenStream::new(); - let mut attributes = TokenStream::new(); let meta = ContainerMeta::from_derive(input); match &input.data { - syn::Data::Struct(ref data) => { - match data.fields { - syn::Fields::Named(ref fields) => { - fields.named.iter().for_each(|field| { - process_named_field(field, &mut body, &mut attributes, &meta); - }); - } - syn::Fields::Unnamed(_) => todo!(), - syn::Fields::Unit => {} - }; - } + syn::Data::Struct(ref data) => serialize_struct(input, data, meta), _ => todo!(), + } +} + +fn serialize_struct( + input: &syn::DeriveInput, + data: &syn::DataStruct, + meta: ContainerMeta, +) -> proc_macro2::TokenStream { + let mut body = TokenStream::new(); + let mut attributes = TokenStream::new(); + + match data.fields { + syn::Fields::Named(ref fields) => { + fields.named.iter().for_each(|field| { + process_named_field(field, &mut body, &mut attributes, &meta); + }); + } + syn::Fields::Unnamed(_) => todo!(), + syn::Fields::Unit => {} }; let default_namespace = match &meta.ns.uri {