commit
1595d3c641
@ -8,7 +8,12 @@ pub fn build_default_value(
|
|||||||
default: &Option<String>,
|
default: &Option<String>,
|
||||||
) -> Option<TokenStream> {
|
) -> Option<TokenStream> {
|
||||||
if let Some(d) = default {
|
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! {
|
Some(quote! {
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
use attribute::*;
|
use attribute::*;
|
||||||
use field_type::*;
|
use field_type::*;
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::TokenStream;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use syn::spanned::Spanned;
|
||||||
use syn::DataEnum;
|
use syn::DataEnum;
|
||||||
use syn::Fields;
|
use syn::Fields;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
@ -133,7 +134,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, field)| {
|
.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 =
|
let make_visitor =
|
||||||
|visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| {
|
|visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| {
|
||||||
@ -151,7 +152,8 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let simple_type_visitor = |simple_type| {
|
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(
|
make_visitor(
|
||||||
&visitor,
|
&visitor,
|
||||||
@ -200,10 +202,11 @@ fn build_unnamed_visitor_calls(
|
|||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, field)| {
|
.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 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);
|
let label_name = format!("field_{}", idx);
|
||||||
|
|
||||||
@ -288,21 +291,3 @@ fn build_unnamed_visitor_calls(
|
|||||||
.filter_map(|f| f)
|
.filter_map(|f| f)
|
||||||
.collect()
|
.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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@ pub mod expand_enum;
|
|||||||
pub mod expand_struct;
|
pub mod expand_struct;
|
||||||
|
|
||||||
use attribute;
|
use attribute;
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::TokenStream;
|
||||||
use syn;
|
use syn;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|
||||||
@ -29,10 +29,7 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream,
|
|||||||
syn::Data::Union(ref _data_union) => unimplemented!(),
|
syn::Data::Union(ref _data_union) => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let dummy_const = Ident::new(
|
let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span());
|
||||||
&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name),
|
|
||||||
Span::call_site(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let generated = quote! {
|
let generated = quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
|||||||
@ -73,3 +73,32 @@ fn get_sub_type(t: &syn::PathSegment) -> Option<syn::PathSegment> {
|
|||||||
|
|
||||||
None
|
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) -> proc_macro2::TokenStream {
|
||||||
|
let ident = format_ident!(
|
||||||
|
"visit_{}",
|
||||||
|
get_simple_type_token(field_type)
|
||||||
|
.to_string()
|
||||||
|
.replace("String", "str")
|
||||||
|
);
|
||||||
|
|
||||||
|
quote! {#ident}
|
||||||
|
}
|
||||||
|
|||||||
@ -50,7 +50,13 @@ pub fn serialize_element(
|
|||||||
let inner = enclose_characters(label, label_name);
|
let inner = enclose_characters(label, label_name);
|
||||||
|
|
||||||
if let Some(ref d) = default {
|
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! {
|
Some(quote! {
|
||||||
if self.#label != #default_function() {
|
if self.#label != #default_function() {
|
||||||
#inner
|
#inner
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use attribute::*;
|
use attribute::*;
|
||||||
use field_type::*;
|
use field_type::*;
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::TokenStream;
|
||||||
use quote::TokenStreamExt;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use syn::spanned::Spanned;
|
||||||
use syn::DataEnum;
|
use syn::DataEnum;
|
||||||
use syn::Fields;
|
use syn::Fields;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
@ -36,7 +36,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Fields::Named(ref fields) => {
|
Fields::Named(ref fields) => {
|
||||||
let enum_fields = fields
|
let enum_fields: TokenStream = fields
|
||||||
.named
|
.named
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
@ -54,7 +54,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let renamed_field_label = match field_attrs.rename {
|
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(),
|
None => field.ident.clone(),
|
||||||
};
|
};
|
||||||
let field_label_name = renamed_field_label.unwrap().to_string();
|
let field_label_name = renamed_field_label.unwrap().to_string();
|
||||||
@ -100,12 +100,8 @@ pub fn serialize(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
&#name::#label{..} => {
|
&#name::#label{..} => {
|
||||||
@ -210,12 +206,8 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
let add_namespaces: TokenStream = namespaces
|
let add_namespaces: TokenStream = namespaces
|
||||||
.iter()
|
.iter()
|
||||||
@ -224,12 +216,8 @@ pub fn serialize(
|
|||||||
.ns(#prefix, #namespace)
|
.ns(#prefix, #namespace)
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
use xml::writer::XmlEvent;
|
use xml::writer::XmlEvent;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use attribute::*;
|
use attribute::*;
|
||||||
use field_type::*;
|
use field_type::*;
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::TokenStream;
|
||||||
use quote::TokenStreamExt;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
|
use syn::spanned::Spanned;
|
||||||
use syn::DataStruct;
|
use syn::DataStruct;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|
||||||
@ -28,21 +28,21 @@ pub fn serialize(
|
|||||||
|
|
||||||
let label_name = build_label_name(&field, &field_attrs);
|
let label_name = build_label_name(&field, &field_attrs);
|
||||||
|
|
||||||
match get_field_type(field) {
|
get_field_type(field).and_then(|f| match f {
|
||||||
Some(FieldType::FieldTypeString)
|
FieldType::FieldTypeString
|
||||||
| Some(FieldType::FieldTypeBool)
|
| FieldType::FieldTypeBool
|
||||||
| Some(FieldType::FieldTypeI8)
|
| FieldType::FieldTypeI8
|
||||||
| Some(FieldType::FieldTypeU8)
|
| FieldType::FieldTypeU8
|
||||||
| Some(FieldType::FieldTypeI16)
|
| FieldType::FieldTypeI16
|
||||||
| Some(FieldType::FieldTypeU16)
|
| FieldType::FieldTypeU16
|
||||||
| Some(FieldType::FieldTypeI32)
|
| FieldType::FieldTypeI32
|
||||||
| Some(FieldType::FieldTypeU32)
|
| FieldType::FieldTypeU32
|
||||||
| Some(FieldType::FieldTypeI64)
|
| FieldType::FieldTypeI64
|
||||||
| Some(FieldType::FieldTypeU64)
|
| FieldType::FieldTypeU64
|
||||||
| Some(FieldType::FieldTypeF32)
|
| FieldType::FieldTypeF32
|
||||||
| Some(FieldType::FieldTypeF64) => {
|
| FieldType::FieldTypeF64 => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
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! {
|
Some(quote! {
|
||||||
let struct_start_event =
|
let struct_start_event =
|
||||||
if self.#label != #default_function() {
|
if self.#label != #default_function() {
|
||||||
@ -73,71 +73,49 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeOption { data_type }) => {
|
FieldType::FieldTypeOption { data_type } => match *data_type {
|
||||||
let dt = Box::into_raw(data_type);
|
FieldType::FieldTypeString => {
|
||||||
match unsafe { dt.as_ref() } {
|
if let Some(ref d) = field_attrs.default {
|
||||||
Some(&FieldType::FieldTypeString) => {
|
let default_function = Ident::new(&d, field.span());
|
||||||
if let Some(ref d) = field_attrs.default {
|
Some(quote! {
|
||||||
let default_function = Ident::new(&d, Span::call_site());
|
let struct_start_event =
|
||||||
Some(quote! {
|
if self.#label != #default_function() {
|
||||||
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 {
|
if let Some(ref value) = self.#label {
|
||||||
struct_start_event.attr(#label_name, &value)
|
struct_start_event.attr(#label_name, &value)
|
||||||
} else {
|
} else {
|
||||||
struct_start_event
|
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)
|
FieldType::FieldTypeBool
|
||||||
| Some(&FieldType::FieldTypeU8)
|
| FieldType::FieldTypeI8
|
||||||
| Some(&FieldType::FieldTypeI16)
|
| FieldType::FieldTypeU8
|
||||||
| Some(&FieldType::FieldTypeU16)
|
| FieldType::FieldTypeI16
|
||||||
| Some(&FieldType::FieldTypeI32)
|
| FieldType::FieldTypeU16
|
||||||
| Some(&FieldType::FieldTypeU32)
|
| FieldType::FieldTypeI32
|
||||||
| Some(&FieldType::FieldTypeI64)
|
| FieldType::FieldTypeU32
|
||||||
| Some(&FieldType::FieldTypeU64)
|
| FieldType::FieldTypeI64
|
||||||
| Some(&FieldType::FieldTypeF32)
|
| FieldType::FieldTypeU64
|
||||||
| Some(&FieldType::FieldTypeF64) => {
|
| FieldType::FieldTypeF32
|
||||||
if let Some(ref d) = field_attrs.default {
|
| FieldType::FieldTypeF64 => {
|
||||||
let default_function = Ident::new(&d, Span::call_site());
|
if let Some(ref d) = field_attrs.default {
|
||||||
Some(quote! {
|
let default_function = Ident::new(&d, field.span());
|
||||||
let struct_start_event =
|
Some(quote! {
|
||||||
if self.#label != #default_function() {
|
let struct_start_event =
|
||||||
if let Some(ref value) = self.#label {
|
if self.#label != #default_function() {
|
||||||
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 =
|
|
||||||
if let Some(ref value) = self.#label {
|
if let Some(ref value) = self.#label {
|
||||||
struct_start_event.attr(#label_name, &*{
|
struct_start_event.attr(#label_name, &*{
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@ -150,40 +128,59 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
struct_start_event
|
struct_start_event
|
||||||
};
|
}
|
||||||
})
|
} else {
|
||||||
}
|
struct_start_event
|
||||||
}
|
};
|
||||||
Some(&FieldType::FieldTypeVec { .. }) => {
|
})
|
||||||
let item_ident = Ident::new("yas_item", Span::call_site());
|
} else {
|
||||||
let inner = enclose_formatted_characters(&item_ident, label_name);
|
Some(quote! {
|
||||||
|
let struct_start_event =
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref value) = self.#label {
|
||||||
let default_function = Ident::new(&d, Span::call_site());
|
struct_start_event.attr(#label_name, &*{
|
||||||
|
use std::mem;
|
||||||
Some(quote! {
|
unsafe {
|
||||||
if self.#label != #default_function() {
|
let content = format!("{}", value);
|
||||||
if let Some(ref yas_list) = self.#label {
|
let ret : &'static str = mem::transmute(&content as &str);
|
||||||
for yas_item in yas_list.iter() {
|
mem::forget(content);
|
||||||
#inner
|
ret
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
struct_start_event
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FieldType::FieldTypeVec { .. } => {
|
||||||
|
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, field.span());
|
||||||
|
|
||||||
|
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! {
|
} else {
|
||||||
for yas_item in &self.#label {
|
Some(quote! {
|
||||||
#inner
|
for yas_item in &self.#label {
|
||||||
}
|
#inner
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
}
|
||||||
}
|
_ => unimplemented!(),
|
||||||
Some(FieldType::FieldTypeStruct { .. }) => {
|
},
|
||||||
|
FieldType::FieldTypeStruct { .. } => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
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! {
|
Some(quote! {
|
||||||
let struct_start_event =
|
let struct_start_event =
|
||||||
if self.#label != #default_function() {
|
if self.#label != #default_function() {
|
||||||
@ -223,14 +220,10 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
let add_namespaces: TokenStream = namespaces
|
let add_namespaces: TokenStream = namespaces
|
||||||
.iter()
|
.iter()
|
||||||
@ -239,12 +232,8 @@ pub fn serialize(
|
|||||||
.ns(#prefix, #namespace)
|
.ns(#prefix, #namespace)
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.filter(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
let struct_inspector: TokenStream = data_struct
|
let struct_inspector: TokenStream = data_struct
|
||||||
.fields
|
.fields
|
||||||
@ -265,164 +254,148 @@ pub fn serialize(
|
|||||||
|
|
||||||
let label_name = build_label_name(&field, &field_attrs);
|
let label_name = build_label_name(&field, &field_attrs);
|
||||||
|
|
||||||
match get_field_type(field) {
|
get_field_type(field).and_then(|f| match f {
|
||||||
Some(FieldType::FieldTypeString)
|
FieldType::FieldTypeString
|
||||||
| Some(FieldType::FieldTypeBool)
|
| FieldType::FieldTypeBool
|
||||||
| Some(FieldType::FieldTypeI8)
|
| FieldType::FieldTypeI8
|
||||||
| Some(FieldType::FieldTypeU8)
|
| FieldType::FieldTypeU8
|
||||||
| Some(FieldType::FieldTypeI16)
|
| FieldType::FieldTypeI16
|
||||||
| Some(FieldType::FieldTypeU16)
|
| FieldType::FieldTypeU16
|
||||||
| Some(FieldType::FieldTypeI32)
|
| FieldType::FieldTypeI32
|
||||||
| Some(FieldType::FieldTypeU32)
|
| FieldType::FieldTypeU32
|
||||||
| Some(FieldType::FieldTypeI64)
|
| FieldType::FieldTypeI64
|
||||||
| Some(FieldType::FieldTypeU64)
|
| FieldType::FieldTypeU64
|
||||||
| Some(FieldType::FieldTypeF32)
|
| FieldType::FieldTypeF32
|
||||||
| Some(FieldType::FieldTypeF64) => {
|
| FieldType::FieldTypeF64 => serialize_element(label, label_name, &field_attrs.default),
|
||||||
serialize_element(label, label_name, &field_attrs.default)
|
FieldType::FieldTypeOption { data_type } => match *data_type {
|
||||||
}
|
FieldType::FieldTypeString
|
||||||
Some(FieldType::FieldTypeOption { data_type }) => {
|
| FieldType::FieldTypeBool
|
||||||
let dt = Box::into_raw(data_type);
|
| FieldType::FieldTypeI8
|
||||||
match unsafe { dt.as_ref() } {
|
| FieldType::FieldTypeU8
|
||||||
Some(&FieldType::FieldTypeString)
|
| FieldType::FieldTypeI16
|
||||||
| Some(&FieldType::FieldTypeBool)
|
| FieldType::FieldTypeU16
|
||||||
| Some(&FieldType::FieldTypeI8)
|
| FieldType::FieldTypeI32
|
||||||
| Some(&FieldType::FieldTypeU8)
|
| FieldType::FieldTypeU32
|
||||||
| Some(&FieldType::FieldTypeI16)
|
| FieldType::FieldTypeI64
|
||||||
| Some(&FieldType::FieldTypeU16)
|
| FieldType::FieldTypeU64
|
||||||
| Some(&FieldType::FieldTypeI32)
|
| FieldType::FieldTypeF32
|
||||||
| Some(&FieldType::FieldTypeU32)
|
| FieldType::FieldTypeF64 => {
|
||||||
| Some(&FieldType::FieldTypeI64)
|
let item_ident = Ident::new("yas_item", field.span());
|
||||||
| Some(&FieldType::FieldTypeU64)
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
| 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);
|
|
||||||
|
|
||||||
if let Some(ref d) = field_attrs.default {
|
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! {
|
Some(quote! {
|
||||||
if self.#label != #default_function() {
|
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 {
|
if let Some(ref yas_item) = self.#label {
|
||||||
#inner
|
#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());
|
FieldType::FieldTypeVec { .. } => {
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
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 {
|
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! {
|
Some(quote! {
|
||||||
if self.#label != #default_function() {
|
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 {
|
if let Some(ref yas_items) = &self.#label {
|
||||||
for yas_item in yas_items.iter() {
|
for yas_item in yas_items.iter() {
|
||||||
#inner
|
#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!(),
|
|
||||||
}
|
}
|
||||||
}
|
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
||||||
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!(),
|
||||||
|
},
|
||||||
|
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
||||||
writer.set_start_event_name(Some(#label_name.to_string()));
|
writer.set_start_event_name(Some(#label_name.to_string()));
|
||||||
writer.set_skip_start_end(false);
|
writer.set_skip_start_end(false);
|
||||||
self.#label.serialize(writer)?;
|
self.#label.serialize(writer)?;
|
||||||
}),
|
}),
|
||||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
FieldType::FieldTypeVec { data_type } => match *data_type {
|
||||||
let dt = Box::into_raw(data_type);
|
FieldType::FieldTypeString => {
|
||||||
match unsafe { dt.as_ref() } {
|
let item_ident = Ident::new("yas_item", field.span());
|
||||||
Some(&FieldType::FieldTypeString) => {
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
let item_ident = Ident::new("yas_item", Span::call_site());
|
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
for yas_item in &self.#label {
|
for yas_item in &self.#label {
|
||||||
#inner
|
#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(&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", field.span());
|
||||||
|
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_start_event_name(None);
|
||||||
writer.set_skip_start_end(false);
|
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(|x| x.is_some())
|
.filter_map(|x| x)
|
||||||
.map(|x| x.unwrap())
|
.collect();
|
||||||
.fold(TokenStream::new(), |mut tokens, token| {
|
|
||||||
tokens.append_all(token);
|
|
||||||
tokens
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
use xml::writer::XmlEvent;
|
use xml::writer::XmlEvent;
|
||||||
|
|||||||
@ -3,7 +3,7 @@ pub mod expand_enum;
|
|||||||
pub mod expand_struct;
|
pub mod expand_struct;
|
||||||
|
|
||||||
use attribute;
|
use attribute;
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::TokenStream;
|
||||||
use syn;
|
use syn;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|
||||||
@ -31,10 +31,7 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result<TokenStream, St
|
|||||||
syn::Data::Union(ref _data_union) => unimplemented!(),
|
syn::Data::Union(ref _data_union) => unimplemented!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let dummy_const = Ident::new(
|
let dummy_const = Ident::new(&format!("_IMPL_YA_SERIALIZE_FOR_{}", name), name.span());
|
||||||
&format!("_IMPL_YA_SERIALIZE_FOR_{}", name),
|
|
||||||
Span::call_site(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let generated = quote! {
|
let generated = quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user