Simplify deserializer macro setup

This commit is contained in:
Dirkjan Ochtman 2022-09-07 09:21:48 +02:00
parent 01c896a9b2
commit 674039a791
2 changed files with 231 additions and 250 deletions

View File

@ -3,36 +3,7 @@ use quote::quote;
use crate::{ContainerMeta, FieldMeta, Namespace};
struct Tokens {
enum_: TokenStream,
consts: TokenStream,
names: TokenStream,
match_: TokenStream,
}
impl Default for Tokens {
fn default() -> Self {
Self {
enum_: TokenStream::new(),
consts: TokenStream::new(),
names: TokenStream::new(),
match_: TokenStream::new(),
}
}
}
pub struct Deserializer {
out: TokenStream,
}
impl quote::ToTokens for Deserializer {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.extend(self.out.clone());
}
}
impl Deserializer {
pub fn new(input: &syn::DeriveInput) -> Deserializer {
pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream {
let ident = &input.ident;
let container_meta = ContainerMeta::from_derive(input);
let default_namespace = match &container_meta.ns.uri {
@ -75,7 +46,7 @@ impl Deserializer {
false => &mut elements_tokens,
};
Self::process_field(
process_field(
field,
index,
&mut declare_values,
@ -106,7 +77,7 @@ impl Deserializer {
let attr_type_match = attributes_tokens.match_;
let name = ident.to_string();
let out = quote!(
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<Self, ::instant_xml::Error> {
use ::instant_xml::de::{Deserializer, Id, Node};
@ -176,13 +147,11 @@ impl Deserializer {
name: #name,
});
}
);
)
}
Deserializer { out }
}
#[allow(clippy::too_many_arguments)]
fn process_field(
#[allow(clippy::too_many_arguments)]
fn process_field(
field: &syn::Field,
index: usize,
declare_values: &mut TokenStream,
@ -190,7 +159,7 @@ impl Deserializer {
tokens: &mut Tokens,
field_meta: FieldMeta,
container_meta: &ContainerMeta,
) {
) {
let field_var = field.ident.as_ref().unwrap();
let field_var_str = field_var.to_string();
let const_field_var_str = Ident::new(&field_var_str.to_uppercase(), Span::call_site());
@ -261,6 +230,23 @@ impl Deserializer {
None => <#no_lifetime_type>::missing_value()?,
},
));
}
struct Tokens {
enum_: TokenStream,
consts: TokenStream,
names: TokenStream,
match_: TokenStream,
}
impl Default for Tokens {
fn default() -> Self {
Self {
enum_: TokenStream::new(),
consts: TokenStream::new(),
names: TokenStream::new(),
match_: TokenStream::new(),
}
}
}

View File

@ -6,7 +6,7 @@ mod ser;
use std::collections::BTreeMap;
use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, TokenStream, TokenTree};
use quote::{quote, ToTokens};
use quote::ToTokens;
use syn::parse_macro_input;
use syn::punctuated::Punctuated;
use syn::token::Colon2;
@ -20,12 +20,7 @@ pub fn to_xml(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
#[proc_macro_derive(FromXml, attributes(xml))]
pub fn from_xml(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = parse_macro_input!(input as syn::DeriveInput);
let deserializer = de::Deserializer::new(&ast);
proc_macro::TokenStream::from(quote!(
#deserializer
))
proc_macro::TokenStream::from(de::from_xml(&ast))
}
#[derive(Default)]