From 703a238d02c61ef5abe01792a6d4e24c78dedcef Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Tue, 4 Feb 2020 17:47:14 +0700 Subject: [PATCH 1/4] Simplify tokenstream folding --- yaserde_derive/src/de/expand_struct.rs | 66 +++++++------------------ yaserde_derive/src/ser/expand_enum.rs | 27 +++------- yaserde_derive/src/ser/expand_struct.rs | 25 +++------- 3 files changed, 30 insertions(+), 88 deletions(-) diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 37814e5..71d115e 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -2,7 +2,7 @@ use attribute::*; use de::build_default_value::build_default_value; use field_type::*; use proc_macro2::{Span, TokenStream}; -use quote::{ToTokens, TokenStreamExt}; +use quote::ToTokens; use std::collections::BTreeMap; use syn::DataStruct; use syn::Ident; @@ -24,12 +24,8 @@ pub fn parse( None } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); let variables: TokenStream = data_struct .fields @@ -191,12 +187,8 @@ pub fn parse( None => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut sum, val| { - sum.append_all(val); - sum - }); + .filter_map(|x| x) + .collect(); let field_visitors: TokenStream = data_struct .fields @@ -383,12 +375,8 @@ pub fn parse( None => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut sum, val| { - sum.append_all(val); - sum - }); + .filter_map(|x| x) + .collect(); let call_visitors: TokenStream = data_struct .fields @@ -873,12 +861,8 @@ pub fn parse( None => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut sum, val| { - sum.append_all(val); - sum - }); + .filter_map(|x| x) + .collect(); let attributes_loading: TokenStream = data_struct .fields @@ -1093,12 +1077,8 @@ pub fn parse( _ => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut sum, val| { - sum.append_all(val); - sum - }); + .filter_map(|x| x) + .collect(); let set_text: TokenStream = data_struct .fields @@ -1173,12 +1153,8 @@ pub fn parse( | None => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); let struct_builder: TokenStream = data_struct .fields @@ -1195,12 +1171,8 @@ pub fn parse( None } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); quote! { use xml::reader::XmlEvent; @@ -1316,12 +1288,8 @@ fn build_call_visitor( None } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); Some(quote! { #label_name => { diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index f61e40f..3fc1d41 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -1,7 +1,6 @@ use attribute::*; use field_type::*; use proc_macro2::{Span, TokenStream}; -use quote::TokenStreamExt; use std::collections::BTreeMap; use syn::DataEnum; use syn::Fields; @@ -36,7 +35,7 @@ pub fn serialize( } }), Fields::Named(ref fields) => { - let enum_fields = fields + let enum_fields: TokenStream = fields .named .iter() .map(|field| { @@ -100,12 +99,8 @@ pub fn serialize( _ => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); Some(quote! { &#name::#label{..} => { @@ -210,12 +205,8 @@ pub fn serialize( } } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); let add_namespaces: TokenStream = namespaces .iter() @@ -224,12 +215,8 @@ pub fn serialize( .ns(#prefix, #namespace) )) }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); quote! { use xml::writer::XmlEvent; diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index d80f337..72ddeed 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -1,7 +1,6 @@ use attribute::*; use field_type::*; use proc_macro2::{Span, TokenStream}; -use quote::TokenStreamExt; use std::collections::BTreeMap; use std::string::ToString; use syn::DataStruct; @@ -225,12 +224,8 @@ pub fn serialize( _ => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); let add_namespaces: TokenStream = namespaces .iter() @@ -239,12 +234,8 @@ pub fn serialize( .ns(#prefix, #namespace) )) }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); let struct_inspector: TokenStream = data_struct .fields @@ -417,12 +408,8 @@ pub fn serialize( None => None, } }) - .filter(|x| x.is_some()) - .map(|x| x.unwrap()) - .fold(TokenStream::new(), |mut tokens, token| { - tokens.append_all(token); - tokens - }); + .filter_map(|x| x) + .collect(); quote! { use xml::writer::XmlEvent; From 5a0f0e55a7082a50f019bd8a38220f57a09beebf Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Tue, 4 Feb 2020 17:50:16 +0700 Subject: [PATCH 2/4] Remove unneeded Option's and unsafe's --- yaserde_derive/src/de/expand_struct.rs | 1374 +++++++++++------------ yaserde_derive/src/ser/expand_struct.rs | 435 ++++--- 2 files changed, 882 insertions(+), 927 deletions(-) diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 71d115e..1a5ec7b 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -34,53 +34,53 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - match get_field_type(field) { - Some(FieldType::FieldTypeString) => build_default_value( + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString => build_default_value( label, "e! {String}, "e! {"".to_string()}, &field_attrs.default, ), - Some(FieldType::FieldTypeBool) => { + FieldType::FieldTypeBool => { build_default_value(label, "e! {bool}, "e! {false}, &field_attrs.default) } - Some(FieldType::FieldTypeI8) => { + FieldType::FieldTypeI8 => { build_default_value(label, "e! {i8}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeU8) => { + FieldType::FieldTypeU8 => { build_default_value(label, "e! {u8}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeI16) => { + FieldType::FieldTypeI16 => { build_default_value(label, "e! {i16}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeU16) => { + FieldType::FieldTypeU16 => { build_default_value(label, "e! {u16}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeI32) => { + FieldType::FieldTypeI32 => { build_default_value(label, "e! {i32}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeU32) => { + FieldType::FieldTypeU32 => { build_default_value(label, "e! {u32}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeI64) => { + FieldType::FieldTypeI64 => { build_default_value(label, "e! {i64}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeU64) => { + FieldType::FieldTypeU64 => { build_default_value(label, "e! {u64}, "e! {0}, &field_attrs.default) } - Some(FieldType::FieldTypeF32) => { + FieldType::FieldTypeF32 => { build_default_value(label, "e! {f32}, "e! {0.0}, &field_attrs.default) } - Some(FieldType::FieldTypeF64) => { + FieldType::FieldTypeF64 => { build_default_value(label, "e! {f64}, "e! {0.0}, &field_attrs.default) } - Some(FieldType::FieldTypeStruct { struct_name }) => build_default_value( + FieldType::FieldTypeStruct { struct_name } => build_default_value( label, "e! {#struct_name}, "e! {#struct_name::default()}, &field_attrs.default, ), - Some(FieldType::FieldTypeOption { .. }) => { + FieldType::FieldTypeOption { .. } => { if let Some(d) = &field_attrs.default { let default_function = Ident::new(&d, Span::call_site()); @@ -95,97 +95,90 @@ pub fn parse( }) } } - Some(FieldType::FieldTypeVec { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeBool) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeI8) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeU8) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeI16) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeU16) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeI32) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeU32) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeI64) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeU64) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeF32) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeF64) => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeStruct { ref struct_name }) => build_default_value( - label, - "e! {Vec<#struct_name>}, - "e! {vec![]}, - &field_attrs.default, - ), - Some(&FieldType::FieldTypeOption { .. }) | Some(&FieldType::FieldTypeVec { .. }) => { - unimplemented!(); - } - None => { - unimplemented!(); - } + FieldType::FieldTypeVec { data_type } => match *data_type { + FieldType::FieldTypeString => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeBool => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeI8 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeU8 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeI16 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeU16 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeI32 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeU32 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeI64 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeU64 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeF32 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeF64 => build_default_value( + label, + "e! {Vec}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeStruct { ref struct_name } => build_default_value( + label, + "e! {Vec<#struct_name>}, + "e! {vec![]}, + &field_attrs.default, + ), + FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => { + unimplemented!(); } - } - None => None, - } + }, + }) }) .filter_map(|x| x) .collect(); @@ -201,44 +194,44 @@ pub fn parse( let visitor_label = build_visitor_ident(&label_name, None); - match get_field_type(field) { - Some(FieldType::FieldTypeString) => { + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString => { build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) } - Some(FieldType::FieldTypeBool) => { + FieldType::FieldTypeBool => { build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) } - Some(FieldType::FieldTypeI8) => { + FieldType::FieldTypeI8 => { build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) } - Some(FieldType::FieldTypeU8) => { + FieldType::FieldTypeU8 => { build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) } - Some(FieldType::FieldTypeI16) => { + FieldType::FieldTypeI16 => { build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) } - Some(FieldType::FieldTypeU16) => { + FieldType::FieldTypeU16 => { build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) } - Some(FieldType::FieldTypeI32) => { + FieldType::FieldTypeI32 => { build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) } - Some(FieldType::FieldTypeU32) => { + FieldType::FieldTypeU32 => { build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) } - Some(FieldType::FieldTypeI64) => { + FieldType::FieldTypeI64 => { build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) } - Some(FieldType::FieldTypeU64) => { + FieldType::FieldTypeU64 => { build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) } - Some(FieldType::FieldTypeF32) => { + FieldType::FieldTypeF32 => { build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) } - Some(FieldType::FieldTypeF64) => { + FieldType::FieldTypeF64 => { build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) } - Some(FieldType::FieldTypeStruct { struct_name }) => { + FieldType::FieldTypeStruct { struct_name } => { let struct_id: String = struct_name .segments .iter() @@ -260,120 +253,113 @@ pub fn parse( } }) } - Some(FieldType::FieldTypeOption { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) - } - Some(&FieldType::FieldTypeBool) => { - build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) - } - Some(&FieldType::FieldTypeI8) => { - build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) - } - Some(&FieldType::FieldTypeU8) => { - build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) - } - Some(&FieldType::FieldTypeI16) => { - build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) - } - Some(&FieldType::FieldTypeU16) => { - build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) - } - Some(&FieldType::FieldTypeI32) => { - build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) - } - Some(&FieldType::FieldTypeU32) => { - build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) - } - Some(&FieldType::FieldTypeI64) => { - build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) - } - Some(&FieldType::FieldTypeU64) => { - build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) - } - Some(&FieldType::FieldTypeF32) => { - build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) - } - Some(&FieldType::FieldTypeF64) => { - build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) - } - Some(&FieldType::FieldTypeStruct { ref struct_name }) => { - let struct_ident = Ident::new( - &format!("{}", struct_name.into_token_stream()), - Span::call_site(), - ); - Some(quote! { - #[allow(non_snake_case, non_camel_case_types)] - struct #visitor_label; - impl<'de> Visitor<'de> for #visitor_label { - type Value = #struct_ident; - } - }) - } - _ => { - unimplemented!(); - } + FieldType::FieldTypeOption { data_type } => match *data_type { + FieldType::FieldTypeString => { + build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) } - } - Some(FieldType::FieldTypeVec { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) - } - Some(&FieldType::FieldTypeBool) => { - build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) - } - Some(&FieldType::FieldTypeI8) => { - build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) - } - Some(&FieldType::FieldTypeU8) => { - build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) - } - Some(&FieldType::FieldTypeI16) => { - build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) - } - Some(&FieldType::FieldTypeU16) => { - build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) - } - Some(&FieldType::FieldTypeI32) => { - build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) - } - Some(&FieldType::FieldTypeU32) => { - build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) - } - Some(&FieldType::FieldTypeI64) => { - build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) - } - Some(&FieldType::FieldTypeU64) => { - build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) - } - Some(&FieldType::FieldTypeF32) => { - build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) - } - Some(&FieldType::FieldTypeF64) => { - build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) - } - Some(&FieldType::FieldTypeStruct { ref struct_name }) => { - let struct_ident = Ident::new( - &format!("{}", struct_name.into_token_stream()), - Span::call_site(), - ); - Some(quote! { - #[allow(non_snake_case, non_camel_case_types)] - struct #visitor_label; - impl<'de> Visitor<'de> for #visitor_label { - type Value = #struct_ident; - } - }) - } - _ => None, + FieldType::FieldTypeBool => { + build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) } - } - None => None, - } + FieldType::FieldTypeI8 => { + build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) + } + FieldType::FieldTypeU8 => { + build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) + } + FieldType::FieldTypeI16 => { + build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) + } + FieldType::FieldTypeU16 => { + build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) + } + FieldType::FieldTypeI32 => { + build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) + } + FieldType::FieldTypeU32 => { + build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) + } + FieldType::FieldTypeI64 => { + build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) + } + FieldType::FieldTypeU64 => { + build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) + } + FieldType::FieldTypeF32 => { + build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) + } + FieldType::FieldTypeF64 => { + build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) + } + FieldType::FieldTypeStruct { ref struct_name } => { + let struct_ident = Ident::new( + &format!("{}", struct_name.into_token_stream()), + Span::call_site(), + ); + Some(quote! { + #[allow(non_snake_case, non_camel_case_types)] + struct #visitor_label; + impl<'de> Visitor<'de> for #visitor_label { + type Value = #struct_ident; + } + }) + } + _ => { + unimplemented!(); + } + }, + FieldType::FieldTypeVec { data_type } => match *data_type { + FieldType::FieldTypeString => { + build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) + } + FieldType::FieldTypeBool => { + build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) + } + FieldType::FieldTypeI8 => { + build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) + } + FieldType::FieldTypeU8 => { + build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) + } + FieldType::FieldTypeI16 => { + build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) + } + FieldType::FieldTypeU16 => { + build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) + } + FieldType::FieldTypeI32 => { + build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) + } + FieldType::FieldTypeU32 => { + build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) + } + FieldType::FieldTypeI64 => { + build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) + } + FieldType::FieldTypeU64 => { + build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) + } + FieldType::FieldTypeF32 => { + build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) + } + FieldType::FieldTypeF64 => { + build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) + } + FieldType::FieldTypeStruct { ref struct_name } => { + let struct_ident = Ident::new( + &format!("{}", struct_name.into_token_stream()), + Span::call_site(), + ); + Some(quote! { + #[allow(non_snake_case, non_camel_case_types)] + struct #visitor_label; + impl<'de> Visitor<'de> for #visitor_label { + type Value = #struct_ident; + } + }) + } + _ => None, + }, + }) }) .filter_map(|x| x) .collect(); @@ -395,8 +381,8 @@ pub fn parse( .clone() .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - match get_field_type(field) { - Some(FieldType::FieldTypeString) => { + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString => { let visitor = Ident::new("visit_str", Span::call_site()); build_call_visitor( "e! {String}, @@ -407,7 +393,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeBool) => { + FieldType::FieldTypeBool => { let visitor = Ident::new("visit_bool", Span::call_site()); build_call_visitor( "e! {bool}, @@ -418,7 +404,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeI8) => { + FieldType::FieldTypeI8 => { let visitor = Ident::new("visit_i8", Span::call_site()); build_call_visitor( "e! {i8}, @@ -429,7 +415,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeU8) => { + FieldType::FieldTypeU8 => { let visitor = Ident::new("visit_u8", Span::call_site()); build_call_visitor( "e! {u8}, @@ -440,7 +426,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeU16) => { + FieldType::FieldTypeU16 => { let visitor = Ident::new("visit_u16", Span::call_site()); build_call_visitor( "e! {u16}, @@ -451,7 +437,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeI16) => { + FieldType::FieldTypeI16 => { let visitor = Ident::new("visit_i16", Span::call_site()); build_call_visitor( "e! {i16}, @@ -462,7 +448,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeU32) => { + FieldType::FieldTypeU32 => { let visitor = Ident::new("visit_u32", Span::call_site()); build_call_visitor( "e! {u32}, @@ -473,7 +459,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeI32) => { + FieldType::FieldTypeI32 => { let visitor = Ident::new("visit_i32", Span::call_site()); build_call_visitor( "e! {i32}, @@ -484,7 +470,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeU64) => { + FieldType::FieldTypeU64 => { let visitor = Ident::new("visit_u64", Span::call_site()); build_call_visitor( "e! {u64}, @@ -495,7 +481,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeI64) => { + FieldType::FieldTypeI64 => { let visitor = Ident::new("visit_i64", Span::call_site()); build_call_visitor( "e! {i64}, @@ -506,7 +492,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeF32) => { + FieldType::FieldTypeF32 => { let visitor = Ident::new("visit_f32", Span::call_site()); build_call_visitor( "e! {f32}, @@ -517,7 +503,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeF64) => { + FieldType::FieldTypeF64 => { let visitor = Ident::new("visit_f64", Span::call_site()); build_call_visitor( "e! {f64}, @@ -528,7 +514,7 @@ pub fn parse( &namespaces, ) } - Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote! { + FieldType::FieldTypeStruct { struct_name } => Some(quote! { #label_name => { reader.set_map_value(); match #struct_name::deserialize(reader) { @@ -542,324 +528,317 @@ pub fn parse( } } }), - Some(FieldType::FieldTypeOption { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - let visitor = Ident::new("visit_str", Span::call_site()); - build_call_visitor( - "e! {String}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeBool) => { - let visitor = Ident::new("visit_bool", Span::call_site()); - build_call_visitor( - "e! {bool}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU8) => { - let visitor = Ident::new("visit_u8", Span::call_site()); - build_call_visitor( - "e! {u8}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI8) => { - let visitor = Ident::new("visit_i8", Span::call_site()); - build_call_visitor( - "e! {i8}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU16) => { - let visitor = Ident::new("visit_u16", Span::call_site()); - build_call_visitor( - "e! {u16}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI16) => { - let visitor = Ident::new("visit_i16", Span::call_site()); - build_call_visitor( - "e! {i16}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU32) => { - let visitor = Ident::new("visit_u32", Span::call_site()); - build_call_visitor( - "e! {u32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI32) => { - let visitor = Ident::new("visit_i32", Span::call_site()); - build_call_visitor( - "e! {i32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU64) => { - let visitor = Ident::new("visit_u64", Span::call_site()); - build_call_visitor( - "e! {u64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI64) => { - let visitor = Ident::new("visit_i64", Span::call_site()); - build_call_visitor( - "e! {i64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeF32) => { - let visitor = Ident::new("visit_f32", Span::call_site()); - build_call_visitor( - "e! {f32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeF64) => { - let visitor = Ident::new("visit_f64", Span::call_site()); - build_call_visitor( - "e! {f64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeStruct { ref struct_name }) => { - let struct_ident = Ident::new( - &format!("{}", struct_name.into_token_stream()), - Span::call_site(), - ); - Some(quote! { - #label_name => { - reader.set_map_value(); - match #struct_ident::deserialize(reader) { - Ok(parsed_item) => { - #value_label = Some(parsed_item); - let _root = reader.next_event(); - }, - Err(msg) => { - return Err(msg); - }, - } - } - }) - } - _ => unimplemented!(), + FieldType::FieldTypeOption { data_type } => match *data_type { + FieldType::FieldTypeString => { + let visitor = Ident::new("visit_str", Span::call_site()); + build_call_visitor( + "e! {String}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) } - } - Some(FieldType::FieldTypeVec { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - let visitor = Ident::new("visit_str", Span::call_site()); - build_call_visitor( - "e! {String}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeBool) => { - let visitor = Ident::new("visit_bool", Span::call_site()); - build_call_visitor( - "e! {bool}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI8) => { - let visitor = Ident::new("visit_i8", Span::call_site()); - build_call_visitor( - "e! {i8}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU8) => { - let visitor = Ident::new("visit_u8", Span::call_site()); - build_call_visitor( - "e! {u8}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI16) => { - let visitor = Ident::new("visit_i16", Span::call_site()); - build_call_visitor( - "e! {i16}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU16) => { - let visitor = Ident::new("visit_u16", Span::call_site()); - build_call_visitor( - "e! {u16}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI32) => { - let visitor = Ident::new("visit_i32", Span::call_site()); - build_call_visitor( - "e! {i32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU32) => { - let visitor = Ident::new("visit_u32", Span::call_site()); - build_call_visitor( - "e! {u32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeI64) => { - let visitor = Ident::new("visit_i64", Span::call_site()); - build_call_visitor( - "e! {i64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeU64) => { - let visitor = Ident::new("visit_u64", Span::call_site()); - build_call_visitor( - "e! {u64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeF32) => { - let visitor = Ident::new("visit_f32", Span::call_site()); - build_call_visitor( - "e! {f32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeF64) => { - let visitor = Ident::new("visit_f64", Span::call_site()); - build_call_visitor( - "e! {f64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - Some(&FieldType::FieldTypeStruct { ref struct_name }) => { - let struct_ident = Ident::new( - &format!("{}", struct_name.into_token_stream()), - Span::call_site(), - ); - Some(quote! { - #label_name => { - reader.set_map_value(); - match #struct_ident::deserialize(reader) { - Ok(parsed_item) => { - #value_label.push(parsed_item); - let _root = reader.next_event(); - }, - Err(msg) => { - return Err(msg); - }, - } - } - }) - } - _ => unimplemented!(), + FieldType::FieldTypeBool => { + let visitor = Ident::new("visit_bool", Span::call_site()); + build_call_visitor( + "e! {bool}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) } - } - None => None, - } + FieldType::FieldTypeU8 => { + let visitor = Ident::new("visit_u8", Span::call_site()); + build_call_visitor( + "e! {u8}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI8 => { + let visitor = Ident::new("visit_i8", Span::call_site()); + build_call_visitor( + "e! {i8}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU16 => { + let visitor = Ident::new("visit_u16", Span::call_site()); + build_call_visitor( + "e! {u16}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI16 => { + let visitor = Ident::new("visit_i16", Span::call_site()); + build_call_visitor( + "e! {i16}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU32 => { + let visitor = Ident::new("visit_u32", Span::call_site()); + build_call_visitor( + "e! {u32}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI32 => { + let visitor = Ident::new("visit_i32", Span::call_site()); + build_call_visitor( + "e! {i32}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU64 => { + let visitor = Ident::new("visit_u64", Span::call_site()); + build_call_visitor( + "e! {u64}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI64 => { + let visitor = Ident::new("visit_i64", Span::call_site()); + build_call_visitor( + "e! {i64}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeF32 => { + let visitor = Ident::new("visit_f32", Span::call_site()); + build_call_visitor( + "e! {f32}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeF64 => { + let visitor = Ident::new("visit_f64", Span::call_site()); + build_call_visitor( + "e! {f64}, + &visitor, + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeStruct { ref struct_name } => { + let struct_ident = Ident::new( + &format!("{}", struct_name.into_token_stream()), + Span::call_site(), + ); + Some(quote! { + #label_name => { + reader.set_map_value(); + match #struct_ident::deserialize(reader) { + Ok(parsed_item) => { + #value_label = Some(parsed_item); + let _root = reader.next_event(); + }, + Err(msg) => { + return Err(msg); + }, + } + } + }) + } + _ => unimplemented!(), + }, + FieldType::FieldTypeVec { data_type } => match *data_type { + FieldType::FieldTypeString => { + let visitor = Ident::new("visit_str", Span::call_site()); + build_call_visitor( + "e! {String}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeBool => { + let visitor = Ident::new("visit_bool", Span::call_site()); + build_call_visitor( + "e! {bool}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI8 => { + let visitor = Ident::new("visit_i8", Span::call_site()); + build_call_visitor( + "e! {i8}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU8 => { + let visitor = Ident::new("visit_u8", Span::call_site()); + build_call_visitor( + "e! {u8}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI16 => { + let visitor = Ident::new("visit_i16", Span::call_site()); + build_call_visitor( + "e! {i16}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU16 => { + let visitor = Ident::new("visit_u16", Span::call_site()); + build_call_visitor( + "e! {u16}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI32 => { + let visitor = Ident::new("visit_i32", Span::call_site()); + build_call_visitor( + "e! {i32}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU32 => { + let visitor = Ident::new("visit_u32", Span::call_site()); + build_call_visitor( + "e! {u32}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeI64 => { + let visitor = Ident::new("visit_i64", Span::call_site()); + build_call_visitor( + "e! {i64}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeU64 => { + let visitor = Ident::new("visit_u64", Span::call_site()); + build_call_visitor( + "e! {u64}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeF32 => { + let visitor = Ident::new("visit_f32", Span::call_site()); + build_call_visitor( + "e! {f32}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeF64 => { + let visitor = Ident::new("visit_f64", Span::call_site()); + build_call_visitor( + "e! {f64}, + &visitor, + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ) + } + FieldType::FieldTypeStruct { ref struct_name } => { + let struct_ident = Ident::new( + &format!("{}", struct_name.into_token_stream()), + Span::call_site(), + ); + Some(quote! { + #label_name => { + reader.set_map_value(); + match #struct_ident::deserialize(reader) { + Ok(parsed_item) => { + #value_label.push(parsed_item); + let _root = reader.next_event(); + }, + Err(msg) => { + return Err(msg); + }, + } + } + }) + } + _ => unimplemented!(), + }, + }) }) .filter_map(|x| x) .collect(); @@ -881,185 +860,186 @@ pub fn parse( let visitor_label = build_visitor_ident(&label_name, None); - match get_field_type(field) { - Some(FieldType::FieldTypeString) => Some(quote! { + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString => Some(quote! { for attr in attributes { if attr.name.local_name == #label_name { #label = attr.value.to_owned(); } } }), - Some(FieldType::FieldTypeBool) => build_call_visitor_for_attribute( + FieldType::FieldTypeBool => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_bool}, &visitor_label, ), - Some(FieldType::FieldTypeI8) => build_call_visitor_for_attribute( + FieldType::FieldTypeI8 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_i8}, &visitor_label, ), - Some(FieldType::FieldTypeU8) => build_call_visitor_for_attribute( + FieldType::FieldTypeU8 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_u8}, &visitor_label, ), - Some(FieldType::FieldTypeI16) => build_call_visitor_for_attribute( + FieldType::FieldTypeI16 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_i16}, &visitor_label, ), - Some(FieldType::FieldTypeU16) => build_call_visitor_for_attribute( + FieldType::FieldTypeU16 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_u16}, &visitor_label, ), - Some(FieldType::FieldTypeI32) => build_call_visitor_for_attribute( + FieldType::FieldTypeI32 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_i32}, &visitor_label, ), - Some(FieldType::FieldTypeU32) => build_call_visitor_for_attribute( + FieldType::FieldTypeU32 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_u32}, &visitor_label, ), - Some(FieldType::FieldTypeI64) => build_call_visitor_for_attribute( + FieldType::FieldTypeI64 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_i64}, &visitor_label, ), - Some(FieldType::FieldTypeU64) => build_call_visitor_for_attribute( + FieldType::FieldTypeU64 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_u64}, &visitor_label, ), - Some(FieldType::FieldTypeF32) => build_call_visitor_for_attribute( + FieldType::FieldTypeF32 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_f32}, &visitor_label, ), - Some(FieldType::FieldTypeF64) => build_call_visitor_for_attribute( + FieldType::FieldTypeF64 => build_call_visitor_for_attribute( label, &label_name, "e! {= value}, "e! {visit_f64}, &visitor_label, ), - Some(FieldType::FieldTypeOption { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_str}, - &visitor_label, - ), - Some(&FieldType::FieldTypeBool) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_bool}, - &visitor_label, - ), - Some(&FieldType::FieldTypeU8) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u8}, - &visitor_label, - ), - Some(&FieldType::FieldTypeI8) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i8}, - &visitor_label, - ), - Some(&FieldType::FieldTypeU16) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u16}, - &visitor_label, - ), - Some(&FieldType::FieldTypeI16) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i16}, - &visitor_label, - ), - Some(&FieldType::FieldTypeU32) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u32}, - &visitor_label, - ), - Some(&FieldType::FieldTypeI32) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i32}, - &visitor_label, - ), - Some(&FieldType::FieldTypeU64) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u64}, - &visitor_label, - ), - Some(&FieldType::FieldTypeI64) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i64}, - &visitor_label, - ), - Some(&FieldType::FieldTypeF32) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_f32}, - &visitor_label, - ), - Some(&FieldType::FieldTypeF64) => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_f64}, - &visitor_label, - ), - _ => None, - } - } - Some(FieldType::FieldTypeStruct { struct_name }) => { - let struct_ident = build_visitor_ident( + FieldType::FieldTypeOption { data_type } => match *data_type { + FieldType::FieldTypeString => build_call_visitor_for_attribute( + label, &label_name, - Some(&struct_name.into_token_stream().to_string()), + "e! {= Some(value)}, + "e! {visit_str}, + &visitor_label, + ), + FieldType::FieldTypeBool => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_bool}, + &visitor_label, + ), + FieldType::FieldTypeU8 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_u8}, + &visitor_label, + ), + FieldType::FieldTypeI8 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_i8}, + &visitor_label, + ), + FieldType::FieldTypeU16 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_u16}, + &visitor_label, + ), + FieldType::FieldTypeI16 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_i16}, + &visitor_label, + ), + FieldType::FieldTypeU32 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_u32}, + &visitor_label, + ), + FieldType::FieldTypeI32 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_i32}, + &visitor_label, + ), + FieldType::FieldTypeU64 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_u64}, + &visitor_label, + ), + FieldType::FieldTypeI64 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_i64}, + &visitor_label, + ), + FieldType::FieldTypeF32 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_f32}, + &visitor_label, + ), + FieldType::FieldTypeF64 => build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + "e! {visit_f64}, + &visitor_label, + ), + _ => None, + }, + FieldType::FieldTypeStruct { struct_name } => { + let struct_ident = Ident::new( + &format!( + "__Visitor_{}_{}", + label_name, + struct_name.into_token_stream() + ), + Span::call_site(), ); Some(quote! { @@ -1075,7 +1055,7 @@ pub fn parse( }) } _ => None, - } + }) }) .filter_map(|x| x) .collect(); @@ -1087,71 +1067,70 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - match get_field_type(field) { - Some(FieldType::FieldTypeString) => { + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString => { build_set_text_to_value(&field_attrs, label, "e! {text_content.to_owned()}) } - Some(FieldType::FieldTypeBool) => build_set_text_to_value( + FieldType::FieldTypeBool => build_set_text_to_value( &field_attrs, label, "e! {bool::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeI8) => build_set_text_to_value( + FieldType::FieldTypeI8 => build_set_text_to_value( &field_attrs, label, "e! {i8::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeU8) => build_set_text_to_value( + FieldType::FieldTypeU8 => build_set_text_to_value( &field_attrs, label, "e! {u8::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeI16) => build_set_text_to_value( + FieldType::FieldTypeI16 => build_set_text_to_value( &field_attrs, label, "e! {i16::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeU16) => build_set_text_to_value( + FieldType::FieldTypeU16 => build_set_text_to_value( &field_attrs, label, "e! {u16::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeI32) => build_set_text_to_value( + FieldType::FieldTypeI32 => build_set_text_to_value( &field_attrs, label, "e! {i32::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeU32) => build_set_text_to_value( + FieldType::FieldTypeU32 => build_set_text_to_value( &field_attrs, label, "e! {u32::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeI64) => build_set_text_to_value( + FieldType::FieldTypeI64 => build_set_text_to_value( &field_attrs, label, "e! {i64::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeU64) => build_set_text_to_value( + FieldType::FieldTypeU64 => build_set_text_to_value( &field_attrs, label, "e! {u64::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeF32) => build_set_text_to_value( + FieldType::FieldTypeF32 => build_set_text_to_value( &field_attrs, label, "e! {f32::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeF64) => build_set_text_to_value( + FieldType::FieldTypeF64 => build_set_text_to_value( &field_attrs, label, "e! {f64::from_str(text_content).unwrap()}, ), - Some(FieldType::FieldTypeStruct { .. }) - | Some(FieldType::FieldTypeOption { .. }) - | Some(FieldType::FieldTypeVec { .. }) - | None => None, - } + FieldType::FieldTypeStruct { .. } + | FieldType::FieldTypeOption { .. } + | FieldType::FieldTypeVec { .. } => None, + }) }) .filter_map(|x| x) .collect(); @@ -1163,13 +1142,9 @@ pub fn parse( let label = &field.ident; let value_label = &get_value_label(&field.ident); - if get_field_type(field).is_some() { - Some(quote! { - #label: #value_label, - }) - } else { - None - } + get_field_type(field).map(|_| { + quote! { #label: #value_label, } + }) }) .filter_map(|x| x) .collect(); @@ -1281,9 +1256,8 @@ fn build_call_visitor( let namespaces_matches: TokenStream = namespaces .iter() .map(|(p, ns)| { - let str_ns = ns.as_str(); if prefix == Some(p.to_string()) { - Some(quote!(#str_ns => {})) + Some(quote!(#ns => {})) } else { None } @@ -1362,13 +1336,9 @@ fn build_set_text_to_value( } fn get_value_label(ident: &Option) -> Option { - match &ident { - Some(ident) => Some(syn::Ident::new( - &format!("__{}_value", ident.to_string()), - ident.span(), - )), - None => None, - } + ident + .clone() + .map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span())) } fn build_visitor_ident(label: &str, struct_id: Option<&str>) -> Ident { diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 72ddeed..470151f 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -27,19 +27,19 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - match get_field_type(field) { - Some(FieldType::FieldTypeString) - | Some(FieldType::FieldTypeBool) - | Some(FieldType::FieldTypeI8) - | Some(FieldType::FieldTypeU8) - | Some(FieldType::FieldTypeI16) - | Some(FieldType::FieldTypeU16) - | Some(FieldType::FieldTypeI32) - | Some(FieldType::FieldTypeU32) - | Some(FieldType::FieldTypeI64) - | Some(FieldType::FieldTypeU64) - | Some(FieldType::FieldTypeF32) - | Some(FieldType::FieldTypeF64) => { + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString + | FieldType::FieldTypeBool + | FieldType::FieldTypeI8 + | FieldType::FieldTypeU8 + | FieldType::FieldTypeI16 + | FieldType::FieldTypeU16 + | FieldType::FieldTypeI32 + | FieldType::FieldTypeU32 + | FieldType::FieldTypeI64 + | FieldType::FieldTypeU64 + | FieldType::FieldTypeF32 + | FieldType::FieldTypeF64 => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, Span::call_site()); Some(quote! { @@ -72,71 +72,49 @@ pub fn serialize( }) } } - Some(FieldType::FieldTypeOption { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); - Some(quote! { - let struct_start_event = - if self.#label != #default_function() { - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &value) - } else { - struct_start_event - } - } else { - struct_start_event - }; - }) - } else { - Some(quote! { - let struct_start_event = + FieldType::FieldTypeOption { data_type } => match *data_type { + FieldType::FieldTypeString => { + if let Some(ref d) = field_attrs.default { + let default_function = Ident::new(&d, Span::call_site()); + Some(quote! { + let struct_start_event = + if self.#label != #default_function() { if let Some(ref value) = self.#label { struct_start_event.attr(#label_name, &value) } else { struct_start_event - }; - }) - } + } + } else { + struct_start_event + }; + }) + } else { + Some(quote! { + let struct_start_event = + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, &value) + } else { + struct_start_event + }; + }) } - Some(&FieldType::FieldTypeBool) - | Some(&FieldType::FieldTypeI8) - | Some(&FieldType::FieldTypeU8) - | Some(&FieldType::FieldTypeI16) - | Some(&FieldType::FieldTypeU16) - | Some(&FieldType::FieldTypeI32) - | Some(&FieldType::FieldTypeU32) - | Some(&FieldType::FieldTypeI64) - | Some(&FieldType::FieldTypeU64) - | Some(&FieldType::FieldTypeF32) - | Some(&FieldType::FieldTypeF64) => { - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); - Some(quote! { - let struct_start_event = - if self.#label != #default_function() { - if let Some(ref value) = self.#label { - struct_start_event.attr(#label_name, &*{ - use std::mem; - unsafe { - let content = format!("{}", value); - let ret : &'static str = mem::transmute(&content as &str); - mem::forget(content); - ret - } - }) - } else { - struct_start_event - } - } else { - struct_start_event - }; - }) - } else { - Some(quote! { - let struct_start_event = + } + FieldType::FieldTypeBool + | FieldType::FieldTypeI8 + | FieldType::FieldTypeU8 + | FieldType::FieldTypeI16 + | FieldType::FieldTypeU16 + | FieldType::FieldTypeI32 + | FieldType::FieldTypeU32 + | FieldType::FieldTypeI64 + | FieldType::FieldTypeU64 + | FieldType::FieldTypeF32 + | FieldType::FieldTypeF64 => { + if let Some(ref d) = field_attrs.default { + let default_function = Ident::new(&d, Span::call_site()); + Some(quote! { + let struct_start_event = + if self.#label != #default_function() { if let Some(ref value) = self.#label { struct_start_event.attr(#label_name, &*{ use std::mem; @@ -149,38 +127,57 @@ pub fn serialize( }) } else { struct_start_event - }; - }) - } - } - Some(&FieldType::FieldTypeVec { .. }) => { - let item_ident = Ident::new("yas_item", Span::call_site()); - let inner = enclose_formatted_characters(&item_ident, label_name); - - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); - - Some(quote! { - if self.#label != #default_function() { - if let Some(ref yas_list) = self.#label { - for yas_item in yas_list.iter() { - #inner + } + } else { + struct_start_event + }; + }) + } else { + Some(quote! { + let struct_start_event = + if let Some(ref value) = self.#label { + struct_start_event.attr(#label_name, &*{ + use std::mem; + unsafe { + let content = format!("{}", value); + let ret : &'static str = mem::transmute(&content as &str); + mem::forget(content); + ret } + }) + } else { + struct_start_event + }; + }) + } + } + FieldType::FieldTypeVec { .. } => { + let item_ident = Ident::new("yas_item", Span::call_site()); + let inner = enclose_formatted_characters(&item_ident, label_name); + + if let Some(ref d) = field_attrs.default { + let default_function = Ident::new(&d, Span::call_site()); + + Some(quote! { + if self.#label != #default_function() { + if let Some(ref yas_list) = self.#label { + for yas_item in yas_list.iter() { + #inner } } - }) - } else { - Some(quote! { - for yas_item in &self.#label { - #inner - } - }) - } + } + }) + } else { + Some(quote! { + for yas_item in &self.#label { + #inner + } + }) } - _ => unimplemented!(), } - } - Some(FieldType::FieldTypeStruct { .. }) => { + _ => unimplemented!(), + }, + FieldType::FieldTypeStruct { .. } => { if let Some(ref d) = field_attrs.default { let default_function = Ident::new(&d, Span::call_site()); Some(quote! { @@ -222,7 +219,7 @@ pub fn serialize( } } _ => None, - } + }) }) .filter_map(|x| x) .collect(); @@ -256,157 +253,145 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - match get_field_type(field) { - Some(FieldType::FieldTypeString) - | Some(FieldType::FieldTypeBool) - | Some(FieldType::FieldTypeI8) - | Some(FieldType::FieldTypeU8) - | Some(FieldType::FieldTypeI16) - | Some(FieldType::FieldTypeU16) - | Some(FieldType::FieldTypeI32) - | Some(FieldType::FieldTypeU32) - | Some(FieldType::FieldTypeI64) - | Some(FieldType::FieldTypeU64) - | Some(FieldType::FieldTypeF32) - | Some(FieldType::FieldTypeF64) => { - serialize_element(label, label_name, &field_attrs.default) - } - Some(FieldType::FieldTypeOption { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) - | Some(&FieldType::FieldTypeBool) - | Some(&FieldType::FieldTypeI8) - | Some(&FieldType::FieldTypeU8) - | Some(&FieldType::FieldTypeI16) - | Some(&FieldType::FieldTypeU16) - | Some(&FieldType::FieldTypeI32) - | Some(&FieldType::FieldTypeU32) - | Some(&FieldType::FieldTypeI64) - | Some(&FieldType::FieldTypeU64) - | Some(&FieldType::FieldTypeF32) - | Some(&FieldType::FieldTypeF64) => { - let item_ident = Ident::new("yas_item", Span::call_site()); - let inner = enclose_formatted_characters_for_value(&item_ident, label_name); + get_field_type(field).and_then(|field| match field { + FieldType::FieldTypeString + | FieldType::FieldTypeBool + | FieldType::FieldTypeI8 + | FieldType::FieldTypeU8 + | FieldType::FieldTypeI16 + | FieldType::FieldTypeU16 + | FieldType::FieldTypeI32 + | FieldType::FieldTypeU32 + | FieldType::FieldTypeI64 + | FieldType::FieldTypeU64 + | FieldType::FieldTypeF32 + | FieldType::FieldTypeF64 => serialize_element(label, label_name, &field_attrs.default), + FieldType::FieldTypeOption { data_type } => match *data_type { + FieldType::FieldTypeString + | FieldType::FieldTypeBool + | FieldType::FieldTypeI8 + | FieldType::FieldTypeU8 + | FieldType::FieldTypeI16 + | FieldType::FieldTypeU16 + | FieldType::FieldTypeI32 + | FieldType::FieldTypeU32 + | FieldType::FieldTypeI64 + | FieldType::FieldTypeU64 + | FieldType::FieldTypeF32 + | FieldType::FieldTypeF64 => { + let item_ident = Ident::new("yas_item", Span::call_site()); + let inner = enclose_formatted_characters_for_value(&item_ident, label_name); - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + if let Some(ref d) = field_attrs.default { + let default_function = Ident::new(&d, Span::call_site()); - Some(quote! { - if self.#label != #default_function() { - if let Some(ref yas_item) = self.#label { - #inner - } - } - }) - } else { - Some(quote! { + Some(quote! { + if self.#label != #default_function() { if let Some(ref yas_item) = self.#label { #inner } - }) - } + } + }) + } else { + Some(quote! { + if let Some(ref yas_item) = self.#label { + #inner + } + }) } - Some(&FieldType::FieldTypeVec { .. }) => { - let item_ident = Ident::new("yas_item", Span::call_site()); - let inner = enclose_formatted_characters_for_value(&item_ident, label_name); + } + FieldType::FieldTypeVec { .. } => { + let item_ident = Ident::new("yas_item", Span::call_site()); + let inner = enclose_formatted_characters_for_value(&item_ident, label_name); - if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + if let Some(ref d) = field_attrs.default { + let default_function = Ident::new(&d, Span::call_site()); - Some(quote! { - if self.#label != #default_function() { - if let Some(ref yas_items) = &self.#label { - for yas_item in yas_items.iter() { - #inner - } - } - } - }) - } else { - Some(quote! { + Some(quote! { + if self.#label != #default_function() { if let Some(ref yas_items) = &self.#label { for yas_item in yas_items.iter() { #inner } } - }) - } + } + }) + } else { + Some(quote! { + if let Some(ref yas_items) = &self.#label { + for yas_item in yas_items.iter() { + #inner + } + } + }) } - Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! { - if let Some(ref item) = &self.#label { - writer.set_start_event_name(Some(#label_name.to_string())); - writer.set_skip_start_end(false); - item.serialize(writer)?; - } - }), - _ => unimplemented!(), } - } - Some(FieldType::FieldTypeStruct { .. }) => Some(quote! { + FieldType::FieldTypeStruct { .. } => Some(quote! { + if let Some(ref item) = &self.#label { + writer.set_start_event_name(Some(#label_name.to_string())); + writer.set_skip_start_end(false); + item.serialize(writer)?; + } + }), + _ => unimplemented!(), + }, + FieldType::FieldTypeStruct { .. } => Some(quote! { writer.set_start_event_name(Some(#label_name.to_string())); writer.set_skip_start_end(false); self.#label.serialize(writer)?; }), - Some(FieldType::FieldTypeVec { data_type }) => { - let dt = Box::into_raw(data_type); - match unsafe { dt.as_ref() } { - Some(&FieldType::FieldTypeString) => { - let item_ident = Ident::new("yas_item", Span::call_site()); - let inner = enclose_formatted_characters_for_value(&item_ident, label_name); + FieldType::FieldTypeVec { data_type } => match *data_type { + FieldType::FieldTypeString => { + let item_ident = Ident::new("yas_item", Span::call_site()); + let inner = enclose_formatted_characters_for_value(&item_ident, label_name); - Some(quote! { - for yas_item in &self.#label { - #inner - } - }) - } - Some(&FieldType::FieldTypeBool) - | Some(&FieldType::FieldTypeI8) - | Some(&FieldType::FieldTypeU8) - | Some(&FieldType::FieldTypeI16) - | Some(&FieldType::FieldTypeU16) - | Some(&FieldType::FieldTypeI32) - | Some(&FieldType::FieldTypeU32) - | Some(&FieldType::FieldTypeI64) - | Some(&FieldType::FieldTypeU64) - | Some(&FieldType::FieldTypeF32) - | Some(&FieldType::FieldTypeF64) => { - let item_ident = Ident::new("yas_item", Span::call_site()); - let inner = enclose_formatted_characters_for_value(&item_ident, label_name); - - Some(quote! { - for yas_item in &self.#label { - #inner - } - }) - } - Some(&FieldType::FieldTypeOption { .. }) => Some(quote! { - for item in &self.#label { - if let Some(value) = item { - writer.set_start_event_name(None); - writer.set_skip_start_end(false); - value.serialize(writer)?; - } + Some(quote! { + for yas_item in &self.#label { + #inner } - }), - Some(&FieldType::FieldTypeStruct { .. }) => Some(quote! { - for item in &self.#label { + }) + } + FieldType::FieldTypeBool + | FieldType::FieldTypeI8 + | FieldType::FieldTypeU8 + | FieldType::FieldTypeI16 + | FieldType::FieldTypeU16 + | FieldType::FieldTypeI32 + | FieldType::FieldTypeU32 + | FieldType::FieldTypeI64 + | FieldType::FieldTypeU64 + | FieldType::FieldTypeF32 + | FieldType::FieldTypeF64 => { + let item_ident = Ident::new("yas_item", Span::call_site()); + let inner = enclose_formatted_characters_for_value(&item_ident, label_name); + + Some(quote! { + for yas_item in &self.#label { + #inner + } + }) + } + FieldType::FieldTypeOption { .. } => Some(quote! { + for item in &self.#label { + if let Some(value) = item { writer.set_start_event_name(None); writer.set_skip_start_end(false); - item.serialize(writer)?; + value.serialize(writer)?; } - }), - Some(&FieldType::FieldTypeVec { .. }) => { - unimplemented!(); } - None => { - unimplemented!(); + }), + FieldType::FieldTypeStruct { .. } => Some(quote! { + for item in &self.#label { + writer.set_start_event_name(None); + writer.set_skip_start_end(false); + item.serialize(writer)?; } + }), + FieldType::FieldTypeVec { .. } => { + unimplemented!(); } - } - None => None, - } + }, + }) }) .filter_map(|x| x) .collect(); From 65838ced802ab14ec162c0eae720634858a36669 Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Tue, 4 Feb 2020 19:08:05 +0700 Subject: [PATCH 3/4] Reduce code duplication when handling simple types --- yaserde_derive/src/de/expand_enum.rs | 49 +- yaserde_derive/src/de/expand_struct.rs | 941 +++---------------------- yaserde_derive/src/field_type.rs | 27 + 3 files changed, 142 insertions(+), 875 deletions(-) diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index 6eb1d9f..b65b8d1 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -135,23 +135,23 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .map(|(idx, field)| { let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); - 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> Visitor<'de> for #visitor_label { - type Value = #field_type; + let make_visitor = |visitor: &Ident, field_type: &TokenStream, fn_body: &TokenStream| { + Some(quote! { + #[allow(non_snake_case, non_camel_case_types)] + struct #visitor_label; + impl<'de> Visitor<'de> for #visitor_label { + type Value = #field_type; - fn #visitor(self, v: &str) -> Result { - #fn_body - } + fn #visitor(self, v: &str) -> Result { + #fn_body } - }) - }; + } + }) + }; let simple_type_visitor = |simple_type| { - let (field_type, visitor) = convert_simple_type(simple_type); + let field_type = get_simple_type_token(&simple_type); + let visitor = get_simple_type_visitor(&simple_type); make_visitor( &visitor, @@ -169,7 +169,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .collect(); make_visitor( - "e! { visit_str }, + &Ident::new("visit_str", Span::call_site()), "e! { #struct_name }, "e! { let content = "<".to_string() + #struct_id + ">" + v + ""; @@ -203,7 +203,8 @@ fn build_unnamed_visitor_calls( let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); let call_simple_type_visitor = |simple_type, action| { - let (field_type, visitor) = convert_simple_type(simple_type); + let field_type = get_simple_type_token(&simple_type); + let visitor = get_simple_type_visitor(&simple_type); let label_name = format!("field_{}", idx); @@ -288,21 +289,3 @@ fn build_unnamed_visitor_calls( .filter_map(|f| f) .collect() } - -fn convert_simple_type(simple_type: FieldType) -> (TokenStream, TokenStream) { - match simple_type { - FieldType::FieldTypeString => (quote! {String}, quote! {visit_str}), - FieldType::FieldTypeBool => (quote! {bool}, quote! {visit_bool}), - FieldType::FieldTypeU8 => (quote! {u8}, quote! {visit_u8}), - FieldType::FieldTypeI8 => (quote! {i8}, quote! {visit_i8}), - FieldType::FieldTypeU16 => (quote! {u16}, quote! {visit_u16}), - FieldType::FieldTypeI16 => (quote! {i16}, quote! {visit_i16}), - FieldType::FieldTypeU32 => (quote! {u32}, quote! {visit_u32}), - FieldType::FieldTypeI32 => (quote! {i32}, quote! {visit_i32}), - FieldType::FieldTypeU64 => (quote! {u64}, quote! {visit_u64}), - FieldType::FieldTypeI64 => (quote! {i64}, quote! {visit_i64}), - FieldType::FieldTypeF32 => (quote! {f32}, quote! {visit_f32}), - FieldType::FieldTypeF64 => (quote! {f64}, quote! {visit_f64}), - _ => panic!("Not a simple type: {:?}", simple_type), - } -} diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 1a5ec7b..44faa44 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -35,45 +35,6 @@ pub fn parse( let field_attrs = YaSerdeAttribute::parse(&field.attrs); get_field_type(field).and_then(|field| match field { - FieldType::FieldTypeString => build_default_value( - label, - "e! {String}, - "e! {"".to_string()}, - &field_attrs.default, - ), - FieldType::FieldTypeBool => { - build_default_value(label, "e! {bool}, "e! {false}, &field_attrs.default) - } - FieldType::FieldTypeI8 => { - build_default_value(label, "e! {i8}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeU8 => { - build_default_value(label, "e! {u8}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeI16 => { - build_default_value(label, "e! {i16}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeU16 => { - build_default_value(label, "e! {u16}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeI32 => { - build_default_value(label, "e! {i32}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeU32 => { - build_default_value(label, "e! {u32}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeI64 => { - build_default_value(label, "e! {i64}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeU64 => { - build_default_value(label, "e! {u64}, "e! {0}, &field_attrs.default) - } - FieldType::FieldTypeF32 => { - build_default_value(label, "e! {f32}, "e! {0.0}, &field_attrs.default) - } - FieldType::FieldTypeF64 => { - build_default_value(label, "e! {f64}, "e! {0.0}, &field_attrs.default) - } FieldType::FieldTypeStruct { struct_name } => build_default_value( label, "e! {#struct_name}, @@ -96,78 +57,6 @@ pub fn parse( } } FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeString => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeBool => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeI8 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeU8 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeI16 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeU16 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeI32 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeU32 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeI64 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeU64 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeF32 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), - FieldType::FieldTypeF64 => build_default_value( - label, - "e! {Vec}, - "e! {vec![]}, - &field_attrs.default, - ), FieldType::FieldTypeStruct { ref struct_name } => build_default_value( label, "e! {Vec<#struct_name>}, @@ -177,7 +66,26 @@ pub fn parse( FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => { unimplemented!(); } + simple_type => { + let type_token = get_simple_type_token(&simple_type); + + build_default_value( + label, + "e! {Vec<#type_token>}, + "e! {vec![]}, + &field_attrs.default, + ) + } }, + simple_type => { + let type_token = get_simple_type_token(&simple_type); + build_default_value( + label, + &type_token, + "e! {#type_token::default()}, + &field_attrs.default, + ) + } }) }) .filter_map(|x| x) @@ -195,42 +103,6 @@ pub fn parse( let visitor_label = build_visitor_ident(&label_name, None); get_field_type(field).and_then(|field| match field { - FieldType::FieldTypeString => { - build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) - } - FieldType::FieldTypeBool => { - build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) - } - FieldType::FieldTypeI8 => { - build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) - } - FieldType::FieldTypeU8 => { - build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) - } - FieldType::FieldTypeI16 => { - build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) - } - FieldType::FieldTypeU16 => { - build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) - } - FieldType::FieldTypeI32 => { - build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) - } - FieldType::FieldTypeU32 => { - build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) - } - FieldType::FieldTypeI64 => { - build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) - } - FieldType::FieldTypeU64 => { - build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) - } - FieldType::FieldTypeF32 => { - build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) - } - FieldType::FieldTypeF64 => { - build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) - } FieldType::FieldTypeStruct { struct_name } => { let struct_id: String = struct_name .segments @@ -254,42 +126,6 @@ pub fn parse( }) } FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeString => { - build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) - } - FieldType::FieldTypeBool => { - build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) - } - FieldType::FieldTypeI8 => { - build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) - } - FieldType::FieldTypeU8 => { - build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) - } - FieldType::FieldTypeI16 => { - build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) - } - FieldType::FieldTypeU16 => { - build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) - } - FieldType::FieldTypeI32 => { - build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) - } - FieldType::FieldTypeU32 => { - build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) - } - FieldType::FieldTypeI64 => { - build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) - } - FieldType::FieldTypeU64 => { - build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) - } - FieldType::FieldTypeF32 => { - build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) - } - FieldType::FieldTypeF64 => { - build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) - } FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), @@ -303,47 +139,14 @@ pub fn parse( } }) } - _ => { - unimplemented!(); - } + FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None, + simple_type => build_declare_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + &visitor_label, + ), }, FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeString => { - build_declare_visitor("e! {String}, "e! {visit_str}, &visitor_label) - } - FieldType::FieldTypeBool => { - build_declare_visitor("e! {bool}, "e! {visit_bool}, &visitor_label) - } - FieldType::FieldTypeI8 => { - build_declare_visitor("e! {i8}, "e! {visit_i8}, &visitor_label) - } - FieldType::FieldTypeU8 => { - build_declare_visitor("e! {u8}, "e! {visit_u8}, &visitor_label) - } - FieldType::FieldTypeI16 => { - build_declare_visitor("e! {i16}, "e! {visit_i16}, &visitor_label) - } - FieldType::FieldTypeU16 => { - build_declare_visitor("e! {u16}, "e! {visit_u16}, &visitor_label) - } - FieldType::FieldTypeI32 => { - build_declare_visitor("e! {i32}, "e! {visit_i32}, &visitor_label) - } - FieldType::FieldTypeU32 => { - build_declare_visitor("e! {u32}, "e! {visit_u32}, &visitor_label) - } - FieldType::FieldTypeI64 => { - build_declare_visitor("e! {i64}, "e! {visit_i64}, &visitor_label) - } - FieldType::FieldTypeU64 => { - build_declare_visitor("e! {u64}, "e! {visit_u64}, &visitor_label) - } - FieldType::FieldTypeF32 => { - build_declare_visitor("e! {f32}, "e! {visit_f32}, &visitor_label) - } - FieldType::FieldTypeF64 => { - build_declare_visitor("e! {f64}, "e! {visit_f64}, &visitor_label) - } FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), @@ -357,8 +160,18 @@ pub fn parse( } }) } - _ => None, + FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None, + simple_type => build_declare_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + &visitor_label, + ), }, + simple_type => build_declare_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + &visitor_label, + ), }) }) .filter_map(|x| x) @@ -382,138 +195,6 @@ pub fn parse( .unwrap_or_else(|| label.as_ref().unwrap().to_string()); get_field_type(field).and_then(|field| match field { - FieldType::FieldTypeString => { - let visitor = Ident::new("visit_str", Span::call_site()); - build_call_visitor( - "e! {String}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeBool => { - let visitor = Ident::new("visit_bool", Span::call_site()); - build_call_visitor( - "e! {bool}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI8 => { - let visitor = Ident::new("visit_i8", Span::call_site()); - build_call_visitor( - "e! {i8}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU8 => { - let visitor = Ident::new("visit_u8", Span::call_site()); - build_call_visitor( - "e! {u8}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU16 => { - let visitor = Ident::new("visit_u16", Span::call_site()); - build_call_visitor( - "e! {u16}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI16 => { - let visitor = Ident::new("visit_i16", Span::call_site()); - build_call_visitor( - "e! {i16}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU32 => { - let visitor = Ident::new("visit_u32", Span::call_site()); - build_call_visitor( - "e! {u32}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI32 => { - let visitor = Ident::new("visit_i32", Span::call_site()); - build_call_visitor( - "e! {i32}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU64 => { - let visitor = Ident::new("visit_u64", Span::call_site()); - build_call_visitor( - "e! {u64}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI64 => { - let visitor = Ident::new("visit_i64", Span::call_site()); - build_call_visitor( - "e! {i64}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF32 => { - let visitor = Ident::new("visit_f32", Span::call_site()); - build_call_visitor( - "e! {f32}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF64 => { - let visitor = Ident::new("visit_f64", Span::call_site()); - build_call_visitor( - "e! {f64}, - &visitor, - "e! {= value}, - &field_attrs, - label, - &namespaces, - ) - } FieldType::FieldTypeStruct { struct_name } => Some(quote! { #label_name => { reader.set_map_value(); @@ -529,138 +210,6 @@ pub fn parse( } }), FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeString => { - let visitor = Ident::new("visit_str", Span::call_site()); - build_call_visitor( - "e! {String}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeBool => { - let visitor = Ident::new("visit_bool", Span::call_site()); - build_call_visitor( - "e! {bool}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU8 => { - let visitor = Ident::new("visit_u8", Span::call_site()); - build_call_visitor( - "e! {u8}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI8 => { - let visitor = Ident::new("visit_i8", Span::call_site()); - build_call_visitor( - "e! {i8}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU16 => { - let visitor = Ident::new("visit_u16", Span::call_site()); - build_call_visitor( - "e! {u16}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI16 => { - let visitor = Ident::new("visit_i16", Span::call_site()); - build_call_visitor( - "e! {i16}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU32 => { - let visitor = Ident::new("visit_u32", Span::call_site()); - build_call_visitor( - "e! {u32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI32 => { - let visitor = Ident::new("visit_i32", Span::call_site()); - build_call_visitor( - "e! {i32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU64 => { - let visitor = Ident::new("visit_u64", Span::call_site()); - build_call_visitor( - "e! {u64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI64 => { - let visitor = Ident::new("visit_i64", Span::call_site()); - build_call_visitor( - "e! {i64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF32 => { - let visitor = Ident::new("visit_f32", Span::call_site()); - build_call_visitor( - "e! {f32}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF64 => { - let visitor = Ident::new("visit_f64", Span::call_site()); - build_call_visitor( - "e! {f64}, - &visitor, - "e! {= Some(value)}, - &field_attrs, - label, - &namespaces, - ) - } FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), @@ -681,141 +230,17 @@ pub fn parse( } }) } - _ => unimplemented!(), + FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(), + simple_type => build_call_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + "e! {= Some(value)}, + &field_attrs, + label, + &namespaces, + ), }, FieldType::FieldTypeVec { data_type } => match *data_type { - FieldType::FieldTypeString => { - let visitor = Ident::new("visit_str", Span::call_site()); - build_call_visitor( - "e! {String}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeBool => { - let visitor = Ident::new("visit_bool", Span::call_site()); - build_call_visitor( - "e! {bool}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI8 => { - let visitor = Ident::new("visit_i8", Span::call_site()); - build_call_visitor( - "e! {i8}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU8 => { - let visitor = Ident::new("visit_u8", Span::call_site()); - build_call_visitor( - "e! {u8}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI16 => { - let visitor = Ident::new("visit_i16", Span::call_site()); - build_call_visitor( - "e! {i16}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU16 => { - let visitor = Ident::new("visit_u16", Span::call_site()); - build_call_visitor( - "e! {u16}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI32 => { - let visitor = Ident::new("visit_i32", Span::call_site()); - build_call_visitor( - "e! {i32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU32 => { - let visitor = Ident::new("visit_u32", Span::call_site()); - build_call_visitor( - "e! {u32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeI64 => { - let visitor = Ident::new("visit_i64", Span::call_site()); - build_call_visitor( - "e! {i64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeU64 => { - let visitor = Ident::new("visit_u64", Span::call_site()); - build_call_visitor( - "e! {u64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF32 => { - let visitor = Ident::new("visit_f32", Span::call_site()); - build_call_visitor( - "e! {f32}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } - FieldType::FieldTypeF64 => { - let visitor = Ident::new("visit_f64", Span::call_site()); - build_call_visitor( - "e! {f64}, - &visitor, - "e! {.push(value)}, - &field_attrs, - label, - &namespaces, - ) - } FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), @@ -836,8 +261,24 @@ pub fn parse( } }) } - _ => unimplemented!(), + FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(), + simple_type => build_call_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + "e! {.push(value)}, + &field_attrs, + label, + &namespaces, + ), }, + simple_type => build_call_visitor( + &get_simple_type_token(&simple_type), + &get_simple_type_visitor(&simple_type), + "e! {= value}, + &field_attrs, + label, + &namespaces, + ), }) }) .filter_map(|x| x) @@ -868,169 +309,21 @@ pub fn parse( } } }), - FieldType::FieldTypeBool => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_bool}, - &visitor_label, - ), - FieldType::FieldTypeI8 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_i8}, - &visitor_label, - ), - FieldType::FieldTypeU8 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_u8}, - &visitor_label, - ), - FieldType::FieldTypeI16 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_i16}, - &visitor_label, - ), - FieldType::FieldTypeU16 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_u16}, - &visitor_label, - ), - FieldType::FieldTypeI32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_i32}, - &visitor_label, - ), - FieldType::FieldTypeU32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_u32}, - &visitor_label, - ), - FieldType::FieldTypeI64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_i64}, - &visitor_label, - ), - FieldType::FieldTypeU64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_u64}, - &visitor_label, - ), - FieldType::FieldTypeF32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_f32}, - &visitor_label, - ), - FieldType::FieldTypeF64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= value}, - "e! {visit_f64}, - &visitor_label, - ), FieldType::FieldTypeOption { data_type } => match *data_type { - FieldType::FieldTypeString => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_str}, - &visitor_label, - ), - FieldType::FieldTypeBool => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_bool}, - &visitor_label, - ), - FieldType::FieldTypeU8 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u8}, - &visitor_label, - ), - FieldType::FieldTypeI8 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i8}, - &visitor_label, - ), - FieldType::FieldTypeU16 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u16}, - &visitor_label, - ), - FieldType::FieldTypeI16 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i16}, - &visitor_label, - ), - FieldType::FieldTypeU32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u32}, - &visitor_label, - ), - FieldType::FieldTypeI32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i32}, - &visitor_label, - ), - FieldType::FieldTypeU64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_u64}, - &visitor_label, - ), - FieldType::FieldTypeI64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_i64}, - &visitor_label, - ), - FieldType::FieldTypeF32 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_f32}, - &visitor_label, - ), - FieldType::FieldTypeF64 => build_call_visitor_for_attribute( - label, - &label_name, - "e! {= Some(value)}, - "e! {visit_f64}, - &visitor_label, - ), - _ => None, + FieldType::FieldTypeStruct { .. } + | FieldType::FieldTypeOption { .. } + | FieldType::FieldTypeVec { .. } => None, + simple_type => { + let visitor = get_simple_type_visitor(&simple_type); + + build_call_visitor_for_attribute( + label, + &label_name, + "e! {= Some(value)}, + &visitor, + &visitor_label, + ) + } }, FieldType::FieldTypeStruct { struct_name } => { let struct_ident = Ident::new( @@ -1054,7 +347,18 @@ pub fn parse( } }) } - _ => None, + FieldType::FieldTypeVec { .. } => None, + simple_type => { + let visitor = get_simple_type_visitor(&simple_type); + + build_call_visitor_for_attribute( + label, + &label_name, + "e! {= value}, + &visitor, + &visitor_label, + ) + } }) }) .filter_map(|x| x) @@ -1071,65 +375,18 @@ pub fn parse( FieldType::FieldTypeString => { build_set_text_to_value(&field_attrs, label, "e! {text_content.to_owned()}) } - FieldType::FieldTypeBool => build_set_text_to_value( - &field_attrs, - label, - "e! {bool::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeI8 => build_set_text_to_value( - &field_attrs, - label, - "e! {i8::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeU8 => build_set_text_to_value( - &field_attrs, - label, - "e! {u8::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeI16 => build_set_text_to_value( - &field_attrs, - label, - "e! {i16::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeU16 => build_set_text_to_value( - &field_attrs, - label, - "e! {u16::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeI32 => build_set_text_to_value( - &field_attrs, - label, - "e! {i32::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeU32 => build_set_text_to_value( - &field_attrs, - label, - "e! {u32::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeI64 => build_set_text_to_value( - &field_attrs, - label, - "e! {i64::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeU64 => build_set_text_to_value( - &field_attrs, - label, - "e! {u64::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeF32 => build_set_text_to_value( - &field_attrs, - label, - "e! {f32::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeF64 => build_set_text_to_value( - &field_attrs, - label, - "e! {f64::from_str(text_content).unwrap()}, - ), - FieldType::FieldTypeStruct { .. } | FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None, + simple_type => { + let type_token = get_simple_type_token(&simple_type); + + build_set_text_to_value( + &field_attrs, + label, + "e! {#type_token::from_str(text_content).unwrap()}, + ) + } }) }) .filter_map(|x| x) @@ -1218,7 +475,7 @@ pub fn parse( fn build_declare_visitor( field_type: &TokenStream, - visitor: &TokenStream, + visitor: &Ident, visitor_label: &Ident, ) -> Option { Some(quote! { @@ -1305,7 +562,7 @@ fn build_call_visitor_for_attribute( label: &Option, label_name: &str, action: &TokenStream, - visitor: &TokenStream, + visitor: &Ident, visitor_label: &Ident, ) -> Option { Some(quote! { diff --git a/yaserde_derive/src/field_type.rs b/yaserde_derive/src/field_type.rs index 8975f98..8f563ea 100644 --- a/yaserde_derive/src/field_type.rs +++ b/yaserde_derive/src/field_type.rs @@ -73,3 +73,30 @@ fn get_sub_type(t: &syn::PathSegment) -> Option { None } + +pub fn get_simple_type_token(field_type: &FieldType) -> proc_macro2::TokenStream { + match field_type { + FieldType::FieldTypeString => quote! {String}, + FieldType::FieldTypeBool => quote! {bool}, + FieldType::FieldTypeI8 => quote! {i8}, + FieldType::FieldTypeU8 => quote! {u8}, + FieldType::FieldTypeI16 => quote! {i16}, + FieldType::FieldTypeU16 => quote! {u16}, + FieldType::FieldTypeI32 => quote! {i32}, + FieldType::FieldTypeU32 => quote! {u32}, + FieldType::FieldTypeI64 => quote! {i64}, + FieldType::FieldTypeU64 => quote! {u64}, + FieldType::FieldTypeF32 => quote! {f32}, + FieldType::FieldTypeF64 => quote! {f64}, + _ => panic!("Not a simple type: {:?}", field_type), + } +} + +pub fn get_simple_type_visitor(field_type: &FieldType) -> syn::Ident { + format_ident!( + "visit_{}", + get_simple_type_token(field_type) + .to_string() + .replace("String", "str") + ) +} From f9e8d91590a75f1f711164999f244c121c6f96eb Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Tue, 4 Feb 2020 19:56:22 +0700 Subject: [PATCH 4/4] Use actual spans instead of Span::call_site() --- yaserde_derive/src/de/build_default_value.rs | 7 ++- yaserde_derive/src/de/expand_enum.rs | 32 +++++++------- yaserde_derive/src/de/expand_struct.rs | 45 +++++++++++--------- yaserde_derive/src/de/mod.rs | 7 +-- yaserde_derive/src/field_type.rs | 8 ++-- yaserde_derive/src/ser/element.rs | 8 +++- yaserde_derive/src/ser/expand_enum.rs | 5 ++- yaserde_derive/src/ser/expand_struct.rs | 31 +++++++------- yaserde_derive/src/ser/mod.rs | 7 +-- 9 files changed, 83 insertions(+), 67 deletions(-) diff --git a/yaserde_derive/src/de/build_default_value.rs b/yaserde_derive/src/de/build_default_value.rs index 19843cc..39561e4 100644 --- a/yaserde_derive/src/de/build_default_value.rs +++ b/yaserde_derive/src/de/build_default_value.rs @@ -8,7 +8,12 @@ pub fn build_default_value( default: &Option, ) -> Option { if let Some(d) = default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new( + &d, + label + .as_ref() + .map_or(Span::call_site(), |ident| ident.span()), + ); Some(quote! { #[allow(unused_mut)] diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index b65b8d1..6f6d210 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -1,7 +1,8 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataEnum; use syn::Fields; use syn::Ident; @@ -133,21 +134,22 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .iter() .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); - let make_visitor = |visitor: &Ident, field_type: &TokenStream, fn_body: &TokenStream| { - Some(quote! { - #[allow(non_snake_case, non_camel_case_types)] - struct #visitor_label; - impl<'de> Visitor<'de> for #visitor_label { - type Value = #field_type; + 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> Visitor<'de> for #visitor_label { + type Value = #field_type; - fn #visitor(self, v: &str) -> Result { - #fn_body + fn #visitor(self, v: &str) -> Result { + #fn_body + } } - } - }) - }; + }) + }; let simple_type_visitor = |simple_type| { let field_type = get_simple_type_token(&simple_type); @@ -169,7 +171,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .collect(); make_visitor( - &Ident::new("visit_str", Span::call_site()), + "e! { visit_str }, "e! { #struct_name }, "e! { let content = "<".to_string() + #struct_id + ">" + v + ""; @@ -200,7 +202,7 @@ fn build_unnamed_visitor_calls( .iter() .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); let call_simple_type_visitor = |simple_type, action| { let field_type = get_simple_type_token(&simple_type); diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 44faa44..f18664f 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -4,6 +4,7 @@ use field_type::*; use proc_macro2::{Span, TokenStream}; use quote::ToTokens; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataStruct; use syn::Ident; @@ -34,7 +35,7 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => build_default_value( label, "e! {#struct_name}, @@ -43,7 +44,7 @@ pub fn parse( ), FieldType::FieldTypeOption { .. } => { if let Some(d) = &field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { #[allow(unused_mut, non_snake_case, non_camel_case_types)] @@ -100,16 +101,16 @@ pub fn parse( .rename .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, field.span(), None); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => { let struct_id: String = struct_name .segments .iter() .map(|s| s.ident.to_string()) .collect(); - let struct_ident = build_visitor_ident(&label_name, Some(&struct_id)); + let struct_ident = build_visitor_ident(&label_name, field.span(), Some(&struct_id)); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -129,7 +130,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -150,7 +151,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -194,7 +195,7 @@ pub fn parse( .clone() .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => Some(quote! { #label_name => { reader.set_map_value(); @@ -213,7 +214,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #label_name => { @@ -238,13 +239,14 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }, FieldType::FieldTypeVec { data_type } => match *data_type { FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #label_name => { @@ -269,6 +271,7 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }, simple_type => build_call_visitor( @@ -278,6 +281,7 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }) }) @@ -299,9 +303,9 @@ pub fn parse( .rename .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, field.span(), None); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString => Some(quote! { for attr in attributes { if attr.name.local_name == #label_name { @@ -332,7 +336,7 @@ pub fn parse( label_name, struct_name.into_token_stream() ), - Span::call_site(), + field.span(), ); Some(quote! { @@ -371,7 +375,7 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString => { build_set_text_to_value(&field_attrs, label, "e! {text_content.to_owned()}) } @@ -475,7 +479,7 @@ pub fn parse( fn build_declare_visitor( field_type: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, visitor_label: &Ident, ) -> Option { Some(quote! { @@ -493,11 +497,12 @@ fn build_declare_visitor( fn build_call_visitor( field_type: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, action: &TokenStream, field_attrs: &YaSerdeAttribute, label: &Option, namespaces: &BTreeMap, + span: Span, ) -> Option { let prefix = field_attrs.prefix.clone(); @@ -508,7 +513,7 @@ fn build_call_visitor( .clone() .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, span, None); let namespaces_matches: TokenStream = namespaces .iter() @@ -562,7 +567,7 @@ fn build_call_visitor_for_attribute( label: &Option, label_name: &str, action: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, visitor_label: &Ident, ) -> Option { Some(quote! { @@ -598,13 +603,13 @@ fn get_value_label(ident: &Option) -> Option { .map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span())) } -fn build_visitor_ident(label: &str, struct_id: Option<&str>) -> Ident { +fn build_visitor_ident(label: &str, span: Span, struct_id: Option<&str>) -> Ident { Ident::new( &format!( "__Visitor_{}_{}", label.replace(".", "_"), struct_id.unwrap_or("") ), - Span::call_site(), + span, ) } diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index 617df1f..455303b 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -3,7 +3,7 @@ pub mod expand_enum; pub mod expand_struct; use attribute; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use syn; use syn::Ident; @@ -29,10 +29,7 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result unimplemented!(), }; - let dummy_const = Ident::new( - &format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), - Span::call_site(), - ); + let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span()); let generated = quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] diff --git a/yaserde_derive/src/field_type.rs b/yaserde_derive/src/field_type.rs index 8f563ea..fb245b8 100644 --- a/yaserde_derive/src/field_type.rs +++ b/yaserde_derive/src/field_type.rs @@ -92,11 +92,13 @@ pub fn get_simple_type_token(field_type: &FieldType) -> proc_macro2::TokenStream } } -pub fn get_simple_type_visitor(field_type: &FieldType) -> syn::Ident { - format_ident!( +pub fn get_simple_type_visitor(field_type: &FieldType) -> proc_macro2::TokenStream { + let ident = format_ident!( "visit_{}", get_simple_type_token(field_type) .to_string() .replace("String", "str") - ) + ); + + quote! {#ident} } diff --git a/yaserde_derive/src/ser/element.rs b/yaserde_derive/src/ser/element.rs index aa53b94..69a77c1 100644 --- a/yaserde_derive/src/ser/element.rs +++ b/yaserde_derive/src/ser/element.rs @@ -50,7 +50,13 @@ pub fn serialize_element( let inner = enclose_characters(label, label_name); if let Some(ref d) = default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new( + &d, + label + .as_ref() + .map_or(Span::call_site(), |ident| ident.span()), + ); + Some(quote! { if self.#label != #default_function() { #inner diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index 3fc1d41..dadd224 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -1,7 +1,8 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataEnum; use syn::Fields; use syn::Ident; @@ -53,7 +54,7 @@ pub fn serialize( } let renamed_field_label = match field_attrs.rename { - Some(value) => Some(Ident::new(&value.replace("\"", ""), Span::call_site())), + Some(value) => Some(Ident::new(&value.replace("\"", ""), field.span())), None => field.ident.clone(), }; let field_label_name = renamed_field_label.unwrap().to_string(); diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 470151f..0ecd409 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -1,8 +1,9 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; use std::string::ToString; +use syn::spanned::Spanned; use syn::DataStruct; use syn::Ident; @@ -27,7 +28,7 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString | FieldType::FieldTypeBool | FieldType::FieldTypeI8 @@ -41,7 +42,7 @@ pub fn serialize( | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -75,7 +76,7 @@ pub fn serialize( FieldType::FieldTypeOption { data_type } => match *data_type { FieldType::FieldTypeString => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -111,7 +112,7 @@ pub fn serialize( | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -152,11 +153,11 @@ pub fn serialize( } } FieldType::FieldTypeVec { .. } => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -179,7 +180,7 @@ pub fn serialize( }, FieldType::FieldTypeStruct { .. } => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -253,7 +254,7 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString | FieldType::FieldTypeBool | FieldType::FieldTypeI8 @@ -279,11 +280,11 @@ pub fn serialize( | FieldType::FieldTypeU64 | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -301,11 +302,11 @@ pub fn serialize( } } FieldType::FieldTypeVec { .. } => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -342,7 +343,7 @@ pub fn serialize( }), FieldType::FieldTypeVec { data_type } => match *data_type { FieldType::FieldTypeString => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { @@ -362,7 +363,7 @@ pub fn serialize( | FieldType::FieldTypeU64 | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index edeabfe..ff8ecff 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -3,7 +3,7 @@ pub mod expand_enum; pub mod expand_struct; use attribute; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use syn; use syn::Ident; @@ -31,10 +31,7 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result unimplemented!(), }; - let dummy_const = Ident::new( - &format!("_IMPL_YA_SERIALIZE_FOR_{}", name), - Span::call_site(), - ); + let dummy_const = Ident::new(&format!("_IMPL_YA_SERIALIZE_FOR_{}", name), name.span()); let generated = quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]