Clean up visitor code generation

This commit is contained in:
Jonas Platte 2020-12-02 17:14:03 +01:00
parent 12ddcdbc87
commit d3ee4112e3
No known key found for this signature in database
GPG Key ID: 9D5B897BFF66575C
3 changed files with 26 additions and 29 deletions

View File

@ -185,9 +185,8 @@ pub enum Field {
}
impl Field {
pub fn get_simple_type_visitor(&self) -> TokenStream {
let ident = format_ident!("visit_{}", self.to_string());
quote! {#ident}
pub fn get_simple_type_visitor(&self) -> Ident {
format_ident!("visit_{}", self.to_string())
}
}

View File

@ -1,5 +1,5 @@
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{DataEnum, Fields, Ident};
@ -149,26 +149,25 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
.iter()
.map(|field| YaSerdeField::new(field.clone()))
.enumerate()
.map(|(idx, field)| {
.filter_map(|(idx, field)| {
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span());
let make_visitor =
|visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| {
Some(quote! {
#[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label;
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #field_type;
let make_visitor = |visitor: &Ident, field_type: &TokenStream, fn_body: &TokenStream| {
quote! {
#[allow(non_snake_case, non_camel_case_types)]
struct #visitor_label;
impl<'de> ::yaserde::Visitor<'de> for #visitor_label {
type Value = #field_type;
fn #visitor(
self,
v: &::std::primitive::str,
) -> ::std::result::Result<Self::Value, ::std::string::String> {
#fn_body
}
fn #visitor(
self,
v: &::std::primitive::str,
) -> ::std::result::Result<Self::Value, ::std::string::String> {
#fn_body
}
})
};
}
}
};
let simple_type_visitor = |simple_type: Field| {
let visitor = simple_type.get_simple_type_visitor();
@ -189,8 +188,8 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
.map(|s| s.ident.to_string())
.collect();
make_visitor(
&quote! { visit_str },
Some(make_visitor(
&Ident::new("visit_str", Span::call_site()),
&quote! { #struct_name },
&quote! {
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
@ -198,16 +197,15 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
::yaserde::de::from_str(&content);
value
},
)
))
}
Field::FieldOption { data_type } | Field::FieldVec { data_type } => match *data_type {
Field::FieldStruct { .. } => None,
simple_type => simple_type_visitor(simple_type),
simple_type => Some(simple_type_visitor(simple_type)),
},
simple_type => simple_type_visitor(simple_type),
simple_type => Some(simple_type_visitor(simple_type)),
}
})
.filter_map(|f| f)
.collect()
}

View File

@ -229,7 +229,7 @@ pub fn parse(
let label_name = field.renamed_label_without_namespace();
let visitor_label = build_visitor_ident(&label_name, field.get_span(), None);
let visit = |action: &TokenStream, visitor: &TokenStream, visitor_label: &Ident| {
let visit = |action: &TokenStream, visitor: &Ident, visitor_label: &Ident| {
Some(quote! {
for attr in attributes {
if attr.name.local_name == #label_name {
@ -254,7 +254,7 @@ pub fn parse(
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
visit(
&action,
&quote! { visit_str },
&Ident::new("visit_str", Span::call_site()),
&build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)),
)
};
@ -421,7 +421,7 @@ pub fn parse(
fn build_call_visitor(
field_type: &TokenStream,
visitor: &TokenStream,
visitor: &Ident,
action: &TokenStream,
field: &YaSerdeField,
root_attributes: &YaSerdeAttribute,