Extract struct handling for ser/de macros

This commit is contained in:
rsdy 2022-09-22 10:55:38 +01:00 committed by Dirkjan Ochtman
parent fb7570056d
commit cfd5d48841
2 changed files with 55 additions and 39 deletions

View File

@ -5,7 +5,20 @@ use super::{discard_lifetimes, ContainerMeta, FieldMeta, Namespace};
pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream { pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream {
let ident = &input.ident; 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 { let default_namespace = match &container_meta.ns.uri {
Some(ns) => quote!(#ns), Some(ns) => quote!(#ns),
None => quote!(""), None => quote!(""),
@ -35,33 +48,28 @@ pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream {
let mut declare_values = TokenStream::new(); let mut declare_values = TokenStream::new();
let mut return_val = TokenStream::new(); let mut return_val = TokenStream::new();
match &input.data { match data.fields {
syn::Data::Struct(ref data) => { syn::Fields::Named(ref fields) => {
match data.fields { fields.named.iter().enumerate().for_each(|(index, field)| {
syn::Fields::Named(ref fields) => { let field_meta = FieldMeta::from_field(field);
fields.named.iter().enumerate().for_each(|(index, field)| { let tokens = match field_meta.attribute {
let field_meta = FieldMeta::from_field(field); true => &mut attributes_tokens,
let tokens = match field_meta.attribute { false => &mut elements_tokens,
true => &mut attributes_tokens, };
false => &mut elements_tokens,
};
process_field( process_field(
field, field,
index, index,
&mut declare_values, &mut declare_values,
&mut return_val, &mut return_val,
tokens, tokens,
field_meta, field_meta,
&container_meta, &container_meta,
); );
}); });
}
syn::Fields::Unnamed(_) => panic!("unamed"),
syn::Fields::Unit => {}
};
} }
_ => todo!(), syn::Fields::Unnamed(_) => panic!("unamed"),
syn::Fields::Unit => {}
}; };
// Elements // Elements
@ -80,6 +88,7 @@ pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream {
Some(name) => quote!(#name), Some(name) => quote!(#name),
None => ident.to_string().into_token_stream(), None => ident.to_string().into_token_stream(),
}; };
quote!( quote!(
impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause {
fn deserialize<'cx>(deserializer: &'cx mut ::instant_xml::Deserializer<'cx, 'xml>) -> Result<Self, ::instant_xml::Error> { fn deserialize<'cx>(deserializer: &'cx mut ::instant_xml::Deserializer<'cx, 'xml>) -> Result<Self, ::instant_xml::Error> {

View File

@ -7,22 +7,29 @@ use crate::Namespace;
use super::{discard_lifetimes, ContainerMeta, FieldMeta}; use super::{discard_lifetimes, ContainerMeta, FieldMeta};
pub fn to_xml(input: &syn::DeriveInput) -> proc_macro2::TokenStream { 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); let meta = ContainerMeta::from_derive(input);
match &input.data { match &input.data {
syn::Data::Struct(ref data) => { syn::Data::Struct(ref data) => serialize_struct(input, data, meta),
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 => {}
};
}
_ => todo!(), _ => 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 { let default_namespace = match &meta.ns.uri {