reorgonize some code

This commit is contained in:
Marc-Antoine Arnaud 2020-04-19 16:23:11 +02:00
parent 158bf492f7
commit fbc329e2be
6 changed files with 134 additions and 137 deletions

View File

@ -1,5 +1,9 @@
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 +16,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());
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 +236,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,11 @@
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 +27,7 @@ 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 +206,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 +223,7 @@ 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 +365,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,25 @@
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 label;
pub mod implement_deserializer;
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()
}