skip serialization if value equals to default

This commit is contained in:
Marc-Antoine Arnaud
2018-12-07 10:21:59 +01:00
parent 9f19057353
commit 28c13f5861
15 changed files with 885 additions and 525 deletions

View File

@@ -0,0 +1,24 @@
use proc_macro2::{Span, TokenStream};
use syn::Ident;
pub fn build_default_value(
label: &Option<Ident>,
field_type: &TokenStream,
value: &TokenStream,
default: &Option<String>,
) -> Option<TokenStream> {
if let Some(d) = default {
let default_function = Ident::new(&d, Span::call_site());
Some(quote! {
#[allow(unused_mut)]
let mut #label : #field_type = #default_function();
})
} else {
Some(quote! {
#[allow(unused_mut)]
let mut #label : #field_type = #value;
})
}
}

View File

@@ -6,6 +6,7 @@ use std::collections::BTreeMap;
use syn::DataEnum;
use syn::Fields;
use syn::Ident;
use de::build_default_value::build_default_value;
pub fn parse(
data_enum: &DataEnum,
@@ -24,95 +25,111 @@ pub fn parse(
.iter()
.map(|field| {
let field_label = &field.ident;
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
match get_field_type(field) {
Some(FieldType::FieldTypeString) => {
build_default_value(field_label, &quote!{String}, &quote!{"".to_string()})
build_default_value(field_label, &quote! {String}, &quote! {"".to_string()}, &field_attrs.default)
}
Some(FieldType::FieldTypeBool) => {
build_default_value(field_label, &quote!{bool}, &quote!{false})
build_default_value(field_label, &quote! {bool}, &quote! {false}, &field_attrs.default)
}
Some(FieldType::FieldTypeI8) => {
build_default_value(field_label, &quote!{i8}, &quote!{0})
build_default_value(field_label, &quote! {i8}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeU8) => {
build_default_value(field_label, &quote!{u8}, &quote!{0})
build_default_value(field_label, &quote! {u8}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeI16) => {
build_default_value(field_label, &quote!{i16}, &quote!{0})
build_default_value(field_label, &quote! {i16}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeU16) => {
build_default_value(field_label, &quote!{u16}, &quote!{0})
build_default_value(field_label, &quote! {u16}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeI32) => {
build_default_value(field_label, &quote!{i32}, &quote!{0})
build_default_value(field_label, &quote! {i32}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeU32) => {
build_default_value(field_label, &quote!{u32}, &quote!{0})
build_default_value(field_label, &quote! {u32}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeI64) => {
build_default_value(field_label, &quote!{i64}, &quote!{0})
build_default_value(field_label, &quote! {i64}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeU64) => {
build_default_value(field_label, &quote!{u64}, &quote!{0})
build_default_value(field_label, &quote! {u64}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeF32) => {
build_default_value(field_label, &quote!{f32}, &quote!{0})
build_default_value(field_label, &quote! {f32}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeF64) => {
build_default_value(field_label, &quote!{f64}, &quote!{0})
build_default_value(field_label, &quote! {f64}, &quote! {0}, &field_attrs.default)
}
Some(FieldType::FieldTypeStruct { struct_name }) => build_default_value(
field_label,
&quote! {#struct_name},
&quote! {#struct_name::default()},
&field_attrs.default,
),
Some(FieldType::FieldTypeOption { .. }) => {
if let Some(d) = &field_attrs.default {
let default_function = Ident::new(&d, Span::call_site());
Some(quote! {
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
let mut #field_label = #default_function();
})
} else {
Some(quote! {
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
let mut #field_label = None;
})
}
}
Some(FieldType::FieldTypeStruct { struct_name }) => Some(quote!{
#[allow(unused_mut)]
let mut #field_label : #struct_name = #struct_name::default();
}),
Some(FieldType::FieldTypeOption { .. }) => Some(quote!{
#[allow(unused_mut)]
let mut #field_label = None;
}),
Some(FieldType::FieldTypeVec { data_type }) => {
let dt = Box::into_raw(data_type);
match unsafe { dt.as_ref() } {
Some(&FieldType::FieldTypeString) => {
build_default_value(field_label, &quote!{Vec<String>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<String>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeBool) => {
build_default_value(field_label, &quote!{Vec<bool>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<bool>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeI8) => {
build_default_value(field_label, &quote!{Vec<i8>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<i8>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeU8) => {
build_default_value(field_label, &quote!{Vec<u8>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<u8>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeI16) => {
build_default_value(field_label, &quote!{Vec<i16>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<i16>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeU16) => {
build_default_value(field_label, &quote!{Vec<u16>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<u16>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeI32) => {
build_default_value(field_label, &quote!{Vec<i32>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<i32>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeU32) => {
build_default_value(field_label, &quote!{Vec<u32>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<u32>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeI64) => {
build_default_value(field_label, &quote!{Vec<i64>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<i64>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeU64) => {
build_default_value(field_label, &quote!{Vec<u64>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<u64>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeF32) => {
build_default_value(field_label, &quote!{Vec<f32>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<f32>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeF64) => {
build_default_value(field_label, &quote!{Vec<f64>}, &quote!{vec![]})
build_default_value(field_label, &quote! {Vec<f64>}, &quote! {vec![]}, &field_attrs.default)
}
Some(&FieldType::FieldTypeStruct { ref struct_name }) => Some(quote!{
#[allow(unused_mut)]
let mut #field_label : Vec<#struct_name> = vec![];
}),
Some(&FieldType::FieldTypeStruct { ref struct_name }) => build_default_value(
field_label,
&quote! {Vec<#struct_name>},
&quote! {vec![]},
&field_attrs.default,
),
Some(&FieldType::FieldTypeOption { .. })
| Some(&FieldType::FieldTypeVec { .. }) => {
unimplemented!();
@@ -158,7 +175,7 @@ pub fn parse(
let label_name = renamed_label.to_string();
match variant.fields {
Fields::Unit => Some(quote!{
Fields::Unit => Some(quote! {
#label_name => {
simple_enum_value = Some(#name::#label);
}
@@ -173,7 +190,7 @@ pub fn parse(
tokens
});
quote!{
quote! {
use xml::reader::XmlEvent;
impl YaDeserialize for #name {
@@ -232,14 +249,3 @@ pub fn parse(
}
}
}
fn build_default_value(
label: &Option<Ident>,
field_type: &TokenStream,
default: &TokenStream,
) -> Option<TokenStream> {
Some(quote!{
#[allow(unused_mut)]
let mut #label : #field_type = #default;
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,5 @@
pub mod build_default_value;
pub mod expand_enum;
pub mod expand_struct;