Merge pull request #71 from media-io/refactor_code

reorganize some code
This commit is contained in:
Marc-Antoine ARNAUD 2020-04-19 18:23:55 +02:00 committed by GitHub
commit a56f6473b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 152 additions and 153 deletions

View File

@ -7,22 +7,22 @@ pub fn build_default_value(
value: &TokenStream,
default: &Option<String>,
) -> Option<TokenStream> {
if let Some(d) = default {
let default_function = Ident::new(
&d,
label
.as_ref()
.map_or(Span::call_site(), |ident| ident.span()),
);
let value = default
.as_ref()
.map(|d| {
let default_function = Ident::new(
&d,
label
.as_ref()
.map_or(Span::call_site(), |ident| ident.span()),
);
Some(quote! {
#[allow(unused_mut)]
let mut #label : #field_type = #default_function();
quote!(#default_function())
})
} else {
Some(quote! {
#[allow(unused_mut)]
let mut #label : #field_type = #value;
})
}
.unwrap_or_else(|| quote!(#value));
Some(quote! {
#[allow(unused_mut)]
let mut #label : #field_type = #value;
})
}

View File

@ -1,5 +1,6 @@
use crate::attribute::*;
use crate::field_type::*;
use crate::ser::{implement_deserializer::implement_deserializer, label::build_label_name};
use proc_macro2::TokenStream;
use syn::spanned::Spanned;
use syn::DataEnum;
@ -12,20 +13,32 @@ pub fn serialize(
root: &str,
root_attributes: &YaSerdeAttribute,
) -> TokenStream {
let write_enum_content: TokenStream = data_enum
let inner_enum_inspector = inner_enum_inspector(data_enum, name, root_attributes);
implement_deserializer(
name,
root,
root_attributes,
quote!(),
quote!(match self {
#inner_enum_inspector
}),
)
}
fn inner_enum_inspector(
data_enum: &DataEnum,
name: &Ident,
root_attributes: &YaSerdeAttribute,
) -> TokenStream {
data_enum
.variants
.iter()
.map(|variant| {
let label = &variant.ident;
let label_name = {
let variant_attrs = YaSerdeAttribute::parse(&variant.attrs);
let prefix = variant_attrs.prefix.map_or(String::new(), |p| p + ":");
let renamed_label = variant_attrs
.rename
.unwrap_or_else(|| variant.ident.to_string());
let variant_attrs = YaSerdeAttribute::parse(&variant.attrs);
prefix + renamed_label.as_str()
};
let label = &variant.ident;
let label_name = build_label_name(&label, &variant_attrs, &root_attributes.default_namespace);
match variant.fields {
Fields::Unit => Some(quote! {
@ -220,58 +233,5 @@ pub fn serialize(
}
})
.filter_map(|x| x)
.collect();
let add_namespaces: TokenStream = root_attributes
.namespaces
.iter()
.map(|(prefix, namespace)| {
if let Some(dn) = &root_attributes.default_namespace {
if dn == prefix {
return Some(quote!(
.default_ns(#namespace)
));
}
}
Some(quote!(
.ns(#prefix, #namespace)
))
})
.filter_map(|x| x)
.collect();
let flatten = root_attributes.flatten;
quote! {
use xml::writer::XmlEvent;
impl YaSerialize for #name {
#[allow(unused_variables)]
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
-> Result<(), String> {
let skip = writer.skip_start_end();
if !#flatten && !skip {
if let Some(label) = writer.get_start_event_name() {
let struct_start_event = XmlEvent::start_element(label.as_ref());
writer.write(struct_start_event).map_err(|e| e.to_string())?;
} else {
let struct_start_event = XmlEvent::start_element(#root)#add_namespaces;
writer.write(struct_start_event).map_err(|e| e.to_string())?;
}
}
match self {
#write_enum_content
}
if !#flatten && !skip {
let struct_end_event = XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?;
}
Ok(())
}
}
}
.collect()
}

View File

@ -1,8 +1,9 @@
use crate::attribute::*;
use crate::field_type::*;
use crate::ser::element::*;
use crate::ser::{
element::*, implement_deserializer::implement_deserializer, label::build_label_name,
};
use proc_macro2::TokenStream;
use std::string::ToString;
use syn::spanned::Spanned;
use syn::DataStruct;
use syn::Ident;
@ -24,7 +25,11 @@ pub fn serialize(
let label = &field.ident;
let label_name = build_label_name(&field, &field_attrs, &root_attributes.default_namespace);
let label_name = build_label_name(
&label.as_ref().unwrap(),
&field_attrs,
&root_attributes.default_namespace,
);
get_field_type(field).and_then(|f| match f {
FieldType::FieldTypeString
@ -203,24 +208,6 @@ pub fn serialize(
.filter_map(|x| x)
.collect();
let add_namespaces: TokenStream = root_attributes
.namespaces
.iter()
.map(|(prefix, namespace)| {
if let Some(dn) = &root_attributes.default_namespace {
if dn == prefix {
return Some(quote!(
.default_ns(#namespace)
));
}
}
Some(quote!(
.ns(#prefix, #namespace)
))
})
.filter_map(|x| x)
.collect();
let struct_inspector: TokenStream = data_struct
.fields
.iter()
@ -238,7 +225,11 @@ pub fn serialize(
));
}
let label_name = build_label_name(&field, &field_attrs, &root_attributes.default_namespace);
let label_name = build_label_name(
&label.as_ref().unwrap(),
&field_attrs,
&root_attributes.default_namespace,
);
let conditions = condition_generator(label, &field_attrs);
get_field_type(field).and_then(|f| match f {
@ -380,55 +371,11 @@ pub fn serialize(
.filter_map(|x| x)
.collect();
let flatten = root_attributes.flatten;
quote! {
use xml::writer::XmlEvent;
impl YaSerialize for #name {
#[allow(unused_variables)]
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
-> Result<(), String> {
let skip = writer.skip_start_end();
if !#flatten && !skip {
let yaserde_label = writer.get_start_event_name().unwrap_or_else(|| #root.to_string());
let struct_start_event = XmlEvent::start_element(yaserde_label.as_ref())#add_namespaces;
#build_attributes
writer.write(struct_start_event).map_err(|e| e.to_string())?;
}
#struct_inspector
if !#flatten && !skip {
let struct_end_event = XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?;
}
Ok(())
}
}
}
}
fn build_label_name(
field: &syn::Field,
field_attrs: &YaSerdeAttribute,
default_namespace: &Option<String>,
) -> String {
let prefix = if default_namespace == &field_attrs.prefix {
"".to_string()
} else {
field_attrs
.prefix
.clone()
.map_or("".to_string(), |prefix| prefix + ":")
};
let label = field_attrs
.rename
.clone()
.unwrap_or_else(|| field.ident.as_ref().unwrap().to_string());
format!("{}{}", prefix, label)
implement_deserializer(
name,
root,
root_attributes,
build_attributes,
struct_inspector,
)
}

View File

@ -0,0 +1,43 @@
use crate::attribute::YaSerdeAttribute;
use crate::ser::namespace::generate_namespaces_definition;
use proc_macro2::Ident;
use proc_macro2::TokenStream;
pub fn implement_deserializer(
name: &Ident,
root: &str,
attributes: &YaSerdeAttribute,
attributes_inspector: TokenStream,
inner_inspector: TokenStream,
) -> TokenStream {
let namespaces_definition = generate_namespaces_definition(attributes);
let flatten = attributes.flatten;
quote! {
use xml::writer::XmlEvent;
impl YaSerialize for #name {
#[allow(unused_variables)]
fn serialize<W: Write>(&self, writer: &mut yaserde::ser::Serializer<W>)
-> Result<(), String> {
let skip = writer.skip_start_end();
if !#flatten && !skip {
let yaserde_label = writer.get_start_event_name().unwrap_or_else(|| #root.to_string());
let struct_start_event = XmlEvent::start_element(yaserde_label.as_ref())#namespaces_definition;
#attributes_inspector
writer.write(struct_start_event).map_err(|e| e.to_string())?;
}
#inner_inspector
if !#flatten && !skip {
let struct_end_event = XmlEvent::end_element();
writer.write(struct_end_event).map_err(|e| e.to_string())?;
}
Ok(())
}
}
}
}

View File

@ -0,0 +1,24 @@
use crate::attribute::YaSerdeAttribute;
use proc_macro2::Ident;
pub fn build_label_name(
label: &Ident,
field_attrs: &YaSerdeAttribute,
default_namespace: &Option<String>,
) -> String {
let prefix = if default_namespace == &field_attrs.prefix {
"".to_string()
} else {
field_attrs
.prefix
.clone()
.map_or("".to_string(), |prefix| prefix + ":")
};
let label = field_attrs
.rename
.clone()
.unwrap_or_else(|| label.to_string());
format!("{}{}", prefix, label)
}

View File

@ -1,6 +1,9 @@
pub mod element;
pub mod expand_enum;
pub mod expand_struct;
pub mod implement_deserializer;
pub mod label;
pub mod namespace;
use crate::attribute::YaSerdeAttribute;
use proc_macro2::TokenStream;

View File

@ -0,0 +1,22 @@
use crate::attribute::YaSerdeAttribute;
use proc_macro2::TokenStream;
pub fn generate_namespaces_definition(attributes: &YaSerdeAttribute) -> TokenStream {
attributes
.namespaces
.iter()
.map(|(prefix, namespace)| {
if let Some(dn) = &attributes.default_namespace {
if dn == prefix {
return Some(quote!(
.default_ns(#namespace)
));
}
}
Some(quote!(
.ns(#prefix, #namespace)
))
})
.filter_map(|x| x)
.collect()
}