restructure code
This commit is contained in:
parent
ccf353ce6b
commit
04ddaa29dc
168
yaserde_derive/src/common/field.rs
Normal file
168
yaserde_derive/src/common/field.rs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
use crate::common::attribute::YaSerdeAttribute;
|
||||||
|
use proc_macro2::{Ident, TokenStream};
|
||||||
|
use std::fmt;
|
||||||
|
use syn;
|
||||||
|
use syn::Type::Path;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Field {
|
||||||
|
FieldString,
|
||||||
|
FieldBool,
|
||||||
|
FieldI8,
|
||||||
|
FieldU8,
|
||||||
|
FieldI16,
|
||||||
|
FieldU16,
|
||||||
|
FieldI32,
|
||||||
|
FieldU32,
|
||||||
|
FieldI64,
|
||||||
|
FieldU64,
|
||||||
|
FieldF32,
|
||||||
|
FieldF64,
|
||||||
|
FieldOption { data_type: Box<Field> },
|
||||||
|
FieldVec { data_type: Box<Field> },
|
||||||
|
FieldStruct { struct_name: syn::Path },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Field {
|
||||||
|
pub fn is_attribute(token_field: &syn::Field) -> bool {
|
||||||
|
YaSerdeAttribute::parse(&token_field.attrs).attribute
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_text_content(token_field: &syn::Field) -> bool {
|
||||||
|
YaSerdeAttribute::parse(&token_field.attrs).text
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn label(token_field: &syn::Field) -> Option<Ident> {
|
||||||
|
token_field.ident.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn renamed_label(token_field: &syn::Field, root_attributes: &YaSerdeAttribute) -> String {
|
||||||
|
let attributes = YaSerdeAttribute::parse(&token_field.attrs);
|
||||||
|
|
||||||
|
let prefix = if root_attributes.default_namespace == attributes.prefix {
|
||||||
|
"".to_string()
|
||||||
|
} else {
|
||||||
|
attributes
|
||||||
|
.prefix
|
||||||
|
.clone()
|
||||||
|
.map_or("".to_string(), |prefix| prefix + ":")
|
||||||
|
};
|
||||||
|
|
||||||
|
let label = attributes
|
||||||
|
.rename
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| token_field.ident.as_ref().unwrap().to_string());
|
||||||
|
|
||||||
|
format!("{}{}", prefix, label)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_simple_type_visitor(&self) -> TokenStream {
|
||||||
|
let ident = format_ident!("visit_{}", self.to_string());
|
||||||
|
quote! {#ident}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&syn::Path> for Field {
|
||||||
|
fn from(path: &syn::Path) -> Self {
|
||||||
|
let result = if let Some(segment) = path.segments.last() {
|
||||||
|
match segment.ident.to_string().as_str() {
|
||||||
|
"String" => Some(Field::FieldString),
|
||||||
|
"bool" => Some(Field::FieldBool),
|
||||||
|
"i8" => Some(Field::FieldI8),
|
||||||
|
"u8" => Some(Field::FieldU8),
|
||||||
|
"i16" => Some(Field::FieldI16),
|
||||||
|
"u16" => Some(Field::FieldU16),
|
||||||
|
"i32" => Some(Field::FieldI32),
|
||||||
|
"u32" => Some(Field::FieldU32),
|
||||||
|
"i64" => Some(Field::FieldI64),
|
||||||
|
"u64" => Some(Field::FieldU64),
|
||||||
|
"f32" => Some(Field::FieldF32),
|
||||||
|
"f64" => Some(Field::FieldF64),
|
||||||
|
"Option" => Some(Field::FieldOption {
|
||||||
|
data_type: Box::new(Field::from(segment)),
|
||||||
|
}),
|
||||||
|
"Vec" => Some(Field::FieldVec {
|
||||||
|
data_type: Box::new(Field::from(segment)),
|
||||||
|
}),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
result.unwrap_or_else(|| Field::FieldStruct {
|
||||||
|
struct_name: path.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&syn::Field> for Field {
|
||||||
|
fn from(field: &syn::Field) -> Self {
|
||||||
|
match field.ty {
|
||||||
|
Path(ref path) => Field::from(&path.path),
|
||||||
|
_ => panic!("unable to match {:?}", field.ty),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&syn::PathSegment> for Field {
|
||||||
|
fn from(path_segment: &syn::PathSegment) -> Self {
|
||||||
|
if let syn::PathArguments::AngleBracketed(ref args) = path_segment.arguments {
|
||||||
|
if let Some(tt) = args.args.first() {
|
||||||
|
if let syn::GenericArgument::Type(ref argument) = *tt {
|
||||||
|
if let Path(ref path) = *argument {
|
||||||
|
return Field::from(&path.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<proc_macro2::TokenStream> for Field {
|
||||||
|
fn into(self) -> proc_macro2::TokenStream {
|
||||||
|
match self {
|
||||||
|
Field::FieldString => quote! {String},
|
||||||
|
Field::FieldBool => quote! {bool},
|
||||||
|
Field::FieldI8 => quote! {i8},
|
||||||
|
Field::FieldU8 => quote! {u8},
|
||||||
|
Field::FieldI16 => quote! {i16},
|
||||||
|
Field::FieldU16 => quote! {u16},
|
||||||
|
Field::FieldI32 => quote! {i32},
|
||||||
|
Field::FieldU32 => quote! {u32},
|
||||||
|
Field::FieldI64 => quote! {i64},
|
||||||
|
Field::FieldU64 => quote! {u64},
|
||||||
|
Field::FieldF32 => quote! {f32},
|
||||||
|
Field::FieldF64 => quote! {f64},
|
||||||
|
_ => panic!("Not a simple type: {:?}", self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<String> for &Field {
|
||||||
|
fn into(self) -> String {
|
||||||
|
match self {
|
||||||
|
Field::FieldString => "str".to_string(),
|
||||||
|
Field::FieldBool => "bool".to_string(),
|
||||||
|
Field::FieldI8 => "i8".to_string(),
|
||||||
|
Field::FieldU8 => "u8".to_string(),
|
||||||
|
Field::FieldI16 => "i16".to_string(),
|
||||||
|
Field::FieldU16 => "u16".to_string(),
|
||||||
|
Field::FieldI32 => "i32".to_string(),
|
||||||
|
Field::FieldU32 => "u32".to_string(),
|
||||||
|
Field::FieldI64 => "i64".to_string(),
|
||||||
|
Field::FieldU64 => "u64".to_string(),
|
||||||
|
Field::FieldF32 => "f32".to_string(),
|
||||||
|
Field::FieldF64 => "f64".to_string(),
|
||||||
|
_ => panic!("Not a simple type: {:?}", self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Field {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let string_representation: String = self.into();
|
||||||
|
write!(f, "{}", string_representation)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
yaserde_derive/src/common/mod.rs
Normal file
5
yaserde_derive/src/common/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
mod attribute;
|
||||||
|
mod field;
|
||||||
|
|
||||||
|
pub use attribute::YaSerdeAttribute;
|
||||||
|
pub use field::Field;
|
||||||
@ -1,10 +1,11 @@
|
|||||||
use crate::attribute::*;
|
use crate::common::{Field, YaSerdeAttribute};
|
||||||
use crate::field_type::*;
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn::spanned::Spanned;
|
use syn::{
|
||||||
use syn::DataEnum;
|
spanned::Spanned,
|
||||||
use syn::Fields;
|
DataEnum,
|
||||||
use syn::Ident;
|
Fields,
|
||||||
|
Ident,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_enum: &DataEnum,
|
data_enum: &DataEnum,
|
||||||
@ -160,9 +161,9 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let simple_type_visitor = |simple_type| {
|
let simple_type_visitor = |simple_type: Field| {
|
||||||
let field_type = get_simple_type_token(&simple_type);
|
let visitor = simple_type.get_simple_type_visitor();
|
||||||
let visitor = get_simple_type_visitor(&simple_type);
|
let field_type = simple_type.into();
|
||||||
|
|
||||||
make_visitor(
|
make_visitor(
|
||||||
&visitor,
|
&visitor,
|
||||||
@ -171,8 +172,8 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { struct_name } => {
|
Field::FieldStruct { struct_name } => {
|
||||||
let struct_id: String = struct_name
|
let struct_id: String = struct_name
|
||||||
.segments
|
.segments
|
||||||
.iter()
|
.iter()
|
||||||
@ -189,14 +190,12 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeOption { data_type } | FieldType::FieldTypeVec { data_type } => {
|
Field::FieldOption { data_type } | Field::FieldVec { data_type } => match *data_type {
|
||||||
match *data_type {
|
Field::FieldStruct { .. } => None,
|
||||||
FieldType::FieldTypeStruct { .. } => None,
|
simple_type => simple_type_visitor(simple_type),
|
||||||
|
},
|
||||||
simple_type => simple_type_visitor(simple_type),
|
simple_type => simple_type_visitor(simple_type),
|
||||||
}
|
}
|
||||||
}
|
|
||||||
simple_type => simple_type_visitor(simple_type),
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.filter_map(|f| f)
|
.filter_map(|f| f)
|
||||||
.collect()
|
.collect()
|
||||||
@ -213,9 +212,9 @@ fn build_unnamed_visitor_calls(
|
|||||||
.map(|(idx, field)| {
|
.map(|(idx, field)| {
|
||||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span());
|
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: Field, action| {
|
||||||
let field_type = get_simple_type_token(&simple_type);
|
let visitor = simple_type.get_simple_type_visitor();
|
||||||
let visitor = get_simple_type_visitor(&simple_type);
|
let field_type: TokenStream = simple_type.into();
|
||||||
|
|
||||||
let label_name = format!("field_{}", idx);
|
let label_name = format!("field_{}", idx);
|
||||||
|
|
||||||
@ -279,19 +278,19 @@ fn build_unnamed_visitor_calls(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_val),
|
Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_val),
|
||||||
FieldType::FieldTypeOption { data_type } => match *data_type {
|
Field::FieldOption { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_opt),
|
Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_opt),
|
||||||
simple_type => call_simple_type_visitor(simple_type, set_opt),
|
simple_type => call_simple_type_visitor(simple_type, set_opt),
|
||||||
},
|
},
|
||||||
FieldType::FieldTypeVec { data_type } => match *data_type {
|
Field::FieldVec { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { struct_name } => call_struct_visitor(struct_name, set_vec),
|
Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_vec),
|
||||||
simple_type => call_simple_type_visitor(simple_type, set_vec),
|
simple_type => call_simple_type_visitor(simple_type, set_vec),
|
||||||
},
|
},
|
||||||
|
|
||||||
simple_type => call_simple_type_visitor(simple_type, set_val),
|
simple_type => call_simple_type_visitor(simple_type, set_val),
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|f| f)
|
.filter_map(|f| f)
|
||||||
.collect()
|
.collect()
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
use crate::attribute::*;
|
use crate::common::{Field, YaSerdeAttribute};
|
||||||
use crate::de::build_default_value::build_default_value;
|
use crate::de::build_default_value::build_default_value;
|
||||||
use crate::field_type::*;
|
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use syn::spanned::Spanned;
|
use syn::{
|
||||||
use syn::DataStruct;
|
spanned::Spanned,
|
||||||
use syn::Ident;
|
DataStruct,
|
||||||
|
Ident,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn parse(
|
pub fn parse(
|
||||||
data_struct: &DataStruct,
|
data_struct: &DataStruct,
|
||||||
@ -33,14 +34,14 @@ pub fn parse(
|
|||||||
let label = &get_value_label(&field.ident);
|
let label = &get_value_label(&field.ident);
|
||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { struct_name } => build_default_value(
|
Field::FieldStruct { struct_name } => build_default_value(
|
||||||
label,
|
label,
|
||||||
"e! {#struct_name},
|
"e! {#struct_name},
|
||||||
"e! {#struct_name::default()},
|
"e! {#struct_name::default()},
|
||||||
&field_attrs.default,
|
&field_attrs.default,
|
||||||
),
|
),
|
||||||
FieldType::FieldTypeOption { .. } => {
|
Field::FieldOption { .. } => {
|
||||||
if let Some(d) = &field_attrs.default {
|
if let Some(d) = &field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
|
|
||||||
@ -55,18 +56,18 @@ pub fn parse(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeVec { data_type } => match *data_type {
|
Field::FieldVec { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { ref struct_name } => build_default_value(
|
Field::FieldStruct { ref struct_name } => build_default_value(
|
||||||
label,
|
label,
|
||||||
"e! {Vec<#struct_name>},
|
"e! {Vec<#struct_name>},
|
||||||
"e! {vec![]},
|
"e! {vec![]},
|
||||||
&field_attrs.default,
|
&field_attrs.default,
|
||||||
),
|
),
|
||||||
FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => {
|
Field::FieldOption { .. } | Field::FieldVec { .. } => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
simple_type => {
|
simple_type => {
|
||||||
let type_token = get_simple_type_token(&simple_type);
|
let type_token: TokenStream = simple_type.into();
|
||||||
|
|
||||||
build_default_value(
|
build_default_value(
|
||||||
label,
|
label,
|
||||||
@ -77,7 +78,8 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
simple_type => {
|
simple_type => {
|
||||||
let type_token = get_simple_type_token(&simple_type);
|
let type_token: TokenStream = simple_type.into();
|
||||||
|
|
||||||
build_default_value(
|
build_default_value(
|
||||||
label,
|
label,
|
||||||
&type_token,
|
&type_token,
|
||||||
@ -85,7 +87,7 @@ pub fn parse(
|
|||||||
&field_attrs.default,
|
&field_attrs.default,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -123,10 +125,10 @@ pub fn parse(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let simple_type_visitor = |simple_type: FieldType| {
|
let simple_type_visitor = |simple_type: Field| {
|
||||||
let field_type = get_simple_type_token(&simple_type);
|
let visitor = simple_type.get_simple_type_visitor();
|
||||||
let visitor = get_simple_type_visitor(&simple_type);
|
|
||||||
let visitor_label = build_visitor_ident(&label_name, field.span(), None);
|
let visitor_label = build_visitor_ident(&label_name, field.span(), None);
|
||||||
|
let field_type: TokenStream = simple_type.into();
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
#[allow(non_snake_case, non_camel_case_types)]
|
#[allow(non_snake_case, non_camel_case_types)]
|
||||||
@ -141,20 +143,20 @@ pub fn parse(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name),
|
Field::FieldStruct { struct_name } => struct_visitor(struct_name),
|
||||||
FieldType::FieldTypeOption { data_type } => match *data_type {
|
Field::FieldOption { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name),
|
Field::FieldStruct { struct_name } => struct_visitor(struct_name),
|
||||||
FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None,
|
Field::FieldOption { .. } | Field::FieldVec { .. } => None,
|
||||||
simple_type => simple_type_visitor(simple_type),
|
simple_type => simple_type_visitor(simple_type),
|
||||||
},
|
},
|
||||||
FieldType::FieldTypeVec { data_type } => match *data_type {
|
Field::FieldVec { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { struct_name } => struct_visitor(struct_name),
|
Field::FieldStruct { struct_name } => struct_visitor(struct_name),
|
||||||
FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => None,
|
Field::FieldOption { .. } | Field::FieldVec { .. } => None,
|
||||||
simple_type => simple_type_visitor(simple_type),
|
simple_type => simple_type_visitor(simple_type),
|
||||||
},
|
},
|
||||||
simple_type => simple_type_visitor(simple_type),
|
simple_type => simple_type_visitor(simple_type),
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -192,10 +194,12 @@ pub fn parse(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_simple = |simple_type: FieldType, action: TokenStream| {
|
let visit_simple = |simple_type: Field, action: TokenStream| {
|
||||||
|
let field_visitor = simple_type.get_simple_type_visitor();
|
||||||
|
let field_type: TokenStream = simple_type.into();
|
||||||
build_call_visitor(
|
build_call_visitor(
|
||||||
&get_simple_type_token(&simple_type),
|
&field_type,
|
||||||
&get_simple_type_visitor(&simple_type),
|
&field_visitor,
|
||||||
&action,
|
&action,
|
||||||
&field_attrs,
|
&field_attrs,
|
||||||
label,
|
label,
|
||||||
@ -204,18 +208,18 @@ pub fn parse(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_sub = |sub_type: Box<FieldType>, action: TokenStream| match *sub_type {
|
let visit_sub = |sub_type: Box<Field>, action: TokenStream| match *sub_type {
|
||||||
FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(),
|
Field::FieldOption { .. } | Field::FieldVec { .. } => unimplemented!(),
|
||||||
FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, action),
|
Field::FieldStruct { struct_name } => visit_struct(struct_name, action),
|
||||||
simple_type => visit_simple(simple_type, action),
|
simple_type => visit_simple(simple_type, action),
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
||||||
FieldType::FieldTypeOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||||
FieldType::FieldTypeVec { data_type } => visit_sub(data_type, quote! {.push(value)}),
|
Field::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}),
|
||||||
simple_type => visit_simple(simple_type, quote! {= value}),
|
simple_type => visit_simple(simple_type, quote! {= value}),
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -231,18 +235,18 @@ pub fn parse(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
Field::FieldStruct { .. } => Some(quote! {
|
||||||
#value_label = yaserde::de::from_str(&unused_xml_elements)?;
|
#value_label = yaserde::de::from_str(&unused_xml_elements)?;
|
||||||
}),
|
}),
|
||||||
FieldType::FieldTypeOption { data_type } => match *data_type {
|
Field::FieldOption { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
Field::FieldStruct { .. } => Some(quote! {
|
||||||
#value_label = yaserde::de::from_str(&unused_xml_elements).ok();
|
#value_label = yaserde::de::from_str(&unused_xml_elements).ok();
|
||||||
}),
|
}),
|
||||||
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
||||||
},
|
},
|
||||||
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -294,27 +298,27 @@ pub fn parse(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_simple = |simple_type: FieldType, action: TokenStream| {
|
let visit_simple = |simple_type: Field, action: TokenStream| {
|
||||||
visit(
|
visit(
|
||||||
&action,
|
&action,
|
||||||
&get_simple_type_visitor(&simple_type),
|
&simple_type.get_simple_type_visitor(),
|
||||||
&visitor_label,
|
&visitor_label,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let visit_sub = |sub_type: Box<FieldType>, action: TokenStream| match *sub_type {
|
let visit_sub = |sub_type: Box<Field>, action: TokenStream| match *sub_type {
|
||||||
FieldType::FieldTypeOption { .. } | FieldType::FieldTypeVec { .. } => unimplemented!(),
|
Field::FieldOption { .. } | Field::FieldVec { .. } => unimplemented!(),
|
||||||
FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, action),
|
Field::FieldStruct { struct_name } => visit_struct(struct_name, action),
|
||||||
simple_type => visit_simple(simple_type, action),
|
simple_type => visit_simple(simple_type, action),
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeString => visit_string(),
|
Field::FieldString => visit_string(),
|
||||||
FieldType::FieldTypeOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||||
FieldType::FieldTypeVec { .. } => unimplemented!(),
|
Field::FieldVec { .. } => unimplemented!(),
|
||||||
FieldType::FieldTypeStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
||||||
simple_type => visit_simple(simple_type, quote! {= value}),
|
simple_type => visit_simple(simple_type, quote! {= value}),
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -334,16 +338,14 @@ pub fn parse(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
get_field_type(field).and_then(|f| match f {
|
match Field::from(field) {
|
||||||
FieldType::FieldTypeString => set_text("e! {text_content.to_owned()}),
|
Field::FieldString => set_text("e! {text_content.to_owned()}),
|
||||||
FieldType::FieldTypeStruct { .. }
|
Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None,
|
||||||
| FieldType::FieldTypeOption { .. }
|
|
||||||
| FieldType::FieldTypeVec { .. } => None,
|
|
||||||
simple_type => {
|
simple_type => {
|
||||||
let type_token = get_simple_type_token(&simple_type);
|
let type_token: TokenStream = simple_type.into();
|
||||||
set_text("e! {#type_token::from_str(text_content).unwrap()})
|
set_text("e! {#type_token::from_str(text_content).unwrap()})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -355,11 +357,8 @@ pub fn parse(
|
|||||||
let label = &field.ident;
|
let label = &field.ident;
|
||||||
let value_label = &get_value_label(&field.ident);
|
let value_label = &get_value_label(&field.ident);
|
||||||
|
|
||||||
get_field_type(field).map(|_| {
|
|
||||||
quote! { #label: #value_label, }
|
quote! { #label: #value_label, }
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.filter_map(|x| x)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let (init_unused, write_unused, visit_unused) = if call_flatten_visitors.is_empty() {
|
let (init_unused, write_unused, visit_unused) = if call_flatten_visitors.is_empty() {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ pub mod build_default_value;
|
|||||||
pub mod expand_enum;
|
pub mod expand_enum;
|
||||||
pub mod expand_struct;
|
pub mod expand_struct;
|
||||||
|
|
||||||
use crate::attribute;
|
use crate::common::YaSerdeAttribute;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn;
|
use syn;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
@ -12,7 +12,7 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result<TokenStream,
|
|||||||
let attrs = &ast.attrs;
|
let attrs = &ast.attrs;
|
||||||
let data = &ast.data;
|
let data = &ast.data;
|
||||||
|
|
||||||
let root_attrs = attribute::YaSerdeAttribute::parse(attrs);
|
let root_attrs = YaSerdeAttribute::parse(attrs);
|
||||||
let root = root_attrs.clone().root.unwrap_or_else(|| name.to_string());
|
let root = root_attrs.clone().root.unwrap_or_else(|| name.to_string());
|
||||||
|
|
||||||
let impl_block = match *data {
|
let impl_block = match *data {
|
||||||
|
|||||||
@ -1,102 +0,0 @@
|
|||||||
use syn;
|
|
||||||
use syn::Type::Path;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum FieldType {
|
|
||||||
FieldTypeString,
|
|
||||||
FieldTypeBool,
|
|
||||||
FieldTypeI8,
|
|
||||||
FieldTypeU8,
|
|
||||||
FieldTypeI16,
|
|
||||||
FieldTypeU16,
|
|
||||||
FieldTypeI32,
|
|
||||||
FieldTypeU32,
|
|
||||||
FieldTypeI64,
|
|
||||||
FieldTypeU64,
|
|
||||||
FieldTypeF32,
|
|
||||||
FieldTypeF64,
|
|
||||||
FieldTypeOption { data_type: Box<FieldType> },
|
|
||||||
FieldTypeVec { data_type: Box<FieldType> },
|
|
||||||
FieldTypeStruct { struct_name: syn::Path },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FieldType {
|
|
||||||
fn from_ident(path: &syn::Path) -> Option<FieldType> {
|
|
||||||
match path.segments.last() {
|
|
||||||
Some(t) => match t.ident.to_string().as_str() {
|
|
||||||
"String" => Some(FieldType::FieldTypeString),
|
|
||||||
"bool" => Some(FieldType::FieldTypeBool),
|
|
||||||
"i8" => Some(FieldType::FieldTypeI8),
|
|
||||||
"u8" => Some(FieldType::FieldTypeU8),
|
|
||||||
"i16" => Some(FieldType::FieldTypeI16),
|
|
||||||
"u16" => Some(FieldType::FieldTypeU16),
|
|
||||||
"i32" => Some(FieldType::FieldTypeI32),
|
|
||||||
"u32" => Some(FieldType::FieldTypeU32),
|
|
||||||
"i64" => Some(FieldType::FieldTypeI64),
|
|
||||||
"u64" => Some(FieldType::FieldTypeU64),
|
|
||||||
"f32" => Some(FieldType::FieldTypeF32),
|
|
||||||
"f64" => Some(FieldType::FieldTypeF64),
|
|
||||||
"Option" => get_sub_type(t).map(|data_type| FieldType::FieldTypeOption {
|
|
||||||
data_type: Box::new(FieldType::from_ident(&data_type).unwrap()),
|
|
||||||
}),
|
|
||||||
"Vec" => get_sub_type(t).map(|data_type| FieldType::FieldTypeVec {
|
|
||||||
data_type: Box::new(FieldType::from_ident(&data_type).unwrap()),
|
|
||||||
}),
|
|
||||||
_ => Some(FieldType::FieldTypeStruct {
|
|
||||||
struct_name: path.clone(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_field_type(field: &syn::Field) -> Option<FieldType> {
|
|
||||||
match field.ty {
|
|
||||||
Path(ref path) => FieldType::from_ident(&path.path),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_sub_type(t: &syn::PathSegment) -> Option<syn::Path> {
|
|
||||||
if let syn::PathArguments::AngleBracketed(ref args) = t.arguments {
|
|
||||||
if let Some(tt) = args.args.first() {
|
|
||||||
if let syn::GenericArgument::Type(ref argument) = *tt {
|
|
||||||
if let Path(ref path) = *argument {
|
|
||||||
return Some(path.path.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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}
|
|
||||||
}
|
|
||||||
@ -6,9 +6,8 @@ extern crate proc_macro2;
|
|||||||
extern crate quote;
|
extern crate quote;
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
|
|
||||||
mod attribute;
|
mod common;
|
||||||
mod de;
|
mod de;
|
||||||
mod field_type;
|
|
||||||
mod ser;
|
mod ser;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::attribute::*;
|
use crate::common::YaSerdeAttribute;
|
||||||
use proc_macro2::{Ident, Span, TokenStream};
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
|
|
||||||
pub fn enclose_formatted_characters(label: &Ident, label_name: String) -> TokenStream {
|
pub fn enclose_formatted_characters(label: &Ident, label_name: String) -> TokenStream {
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
use crate::attribute::*;
|
use crate::common::{Field, YaSerdeAttribute};
|
||||||
use crate::field_type::*;
|
|
||||||
use crate::ser::{implement_deserializer::implement_deserializer, label::build_label_name};
|
use crate::ser::{implement_deserializer::implement_deserializer, label::build_label_name};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn::spanned::Spanned;
|
|
||||||
use syn::DataEnum;
|
use syn::DataEnum;
|
||||||
use syn::Fields;
|
use syn::Fields;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
@ -52,38 +50,34 @@ fn inner_enum_inspector(
|
|||||||
.named
|
.named
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
if Field::is_attribute(field) {
|
||||||
if field_attrs.attribute {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let field_label = &field.ident;
|
let field_label = Field::label(field);
|
||||||
if field_attrs.text {
|
|
||||||
|
if Field::is_text_content(field) {
|
||||||
return Some(quote!(
|
return Some(quote!(
|
||||||
let data_event = XmlEvent::characters(&self.#field_label);
|
let data_event = XmlEvent::characters(&self.#field_label);
|
||||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let renamed_field_label = match field_attrs.rename {
|
let field_label_name = Field::renamed_label(field, root_attributes);
|
||||||
Some(value) => Some(Ident::new(&value.replace("\"", ""), field.span())),
|
|
||||||
None => field.ident.clone(),
|
|
||||||
};
|
|
||||||
let field_label_name = renamed_field_label.unwrap().to_string();
|
|
||||||
|
|
||||||
match get_field_type(field) {
|
match Field::from(field) {
|
||||||
Some(FieldType::FieldTypeString)
|
Field::FieldString
|
||||||
| Some(FieldType::FieldTypeBool)
|
| Field::FieldBool
|
||||||
| Some(FieldType::FieldTypeU8)
|
| Field::FieldU8
|
||||||
| Some(FieldType::FieldTypeI8)
|
| Field::FieldI8
|
||||||
| Some(FieldType::FieldTypeU16)
|
| Field::FieldU16
|
||||||
| Some(FieldType::FieldTypeI16)
|
| Field::FieldI16
|
||||||
| Some(FieldType::FieldTypeU32)
|
| Field::FieldU32
|
||||||
| Some(FieldType::FieldTypeI32)
|
| Field::FieldI32
|
||||||
| Some(FieldType::FieldTypeF32)
|
| Field::FieldF32
|
||||||
| Some(FieldType::FieldTypeU64)
|
| Field::FieldU64
|
||||||
| Some(FieldType::FieldTypeI64)
|
| Field::FieldI64
|
||||||
| Some(FieldType::FieldTypeF64) => Some({
|
| Field::FieldF64 => Some({
|
||||||
quote! {
|
quote! {
|
||||||
match self {
|
match self {
|
||||||
&#name::#label{ref #field_label, ..} => {
|
&#name::#label{ref #field_label, ..} => {
|
||||||
@ -101,7 +95,7 @@ fn inner_enum_inspector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Some(FieldType::FieldTypeStruct { .. }) => Some(quote! {
|
Field::FieldStruct { .. } => Some(quote! {
|
||||||
match self {
|
match self {
|
||||||
&#name::#label{ref #field_label, ..} => {
|
&#name::#label{ref #field_label, ..} => {
|
||||||
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
writer.set_start_event_name(Some(#field_label_name.to_string()));
|
||||||
@ -111,7 +105,7 @@ fn inner_enum_inspector(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Some(FieldType::FieldTypeVec { .. }) => Some(quote! {
|
Field::FieldVec { .. } => Some(quote! {
|
||||||
match self {
|
match self {
|
||||||
&#name::#label{ref #field_label, ..} => {
|
&#name::#label{ref #field_label, ..} => {
|
||||||
for item in #field_label {
|
for item in #field_label {
|
||||||
@ -123,7 +117,7 @@ fn inner_enum_inspector(
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
_ => None,
|
Field::FieldOption { .. } => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
@ -139,9 +133,8 @@ fn inner_enum_inspector(
|
|||||||
let enum_fields: TokenStream = fields
|
let enum_fields: TokenStream = fields
|
||||||
.unnamed
|
.unnamed
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|token_field| {
|
||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
if Field::is_attribute(token_field) {
|
||||||
if field_attrs.attribute {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +169,7 @@ fn inner_enum_inspector(
|
|||||||
|
|
||||||
let write_sub_type = |data_type| {
|
let write_sub_type = |data_type| {
|
||||||
write_element(match data_type {
|
write_element(match data_type {
|
||||||
FieldType::FieldTypeString => &write_string_chars,
|
Field::FieldString => &write_string_chars,
|
||||||
_ => &serialize,
|
_ => &serialize,
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -192,8 +185,8 @@ fn inner_enum_inspector(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match get_field_type(field) {
|
match Field::from(token_field) {
|
||||||
Some(FieldType::FieldTypeOption { data_type }) => {
|
Field::FieldOption { data_type } => {
|
||||||
let write = write_sub_type(*data_type);
|
let write = write_sub_type(*data_type);
|
||||||
|
|
||||||
Some(match_field("e! {
|
Some(match_field("e! {
|
||||||
@ -202,7 +195,7 @@ fn inner_enum_inspector(
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeVec { data_type }) => {
|
Field::FieldVec { data_type } => {
|
||||||
let write = write_sub_type(*data_type);
|
let write = write_sub_type(*data_type);
|
||||||
|
|
||||||
Some(match_field("e! {
|
Some(match_field("e! {
|
||||||
@ -211,14 +204,9 @@ fn inner_enum_inspector(
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Some(FieldType::FieldTypeStruct { .. }) => {
|
Field::FieldStruct { .. } => Some(write_element(&match_field(&serialize))),
|
||||||
Some(write_element(&match_field(&serialize)))
|
Field::FieldString => Some(match_field(&write_element(&write_string_chars))),
|
||||||
}
|
_simple_type => Some(match_field(&write_simple_type)),
|
||||||
Some(FieldType::FieldTypeString) => {
|
|
||||||
Some(match_field(&write_element(&write_string_chars)))
|
|
||||||
}
|
|
||||||
Some(_simple_type) => Some(match_field(&write_simple_type)),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
use crate::attribute::*;
|
use crate::common::{Field, YaSerdeAttribute};
|
||||||
use crate::field_type::*;
|
|
||||||
use crate::ser::{
|
use crate::ser::{element::*, implement_deserializer::implement_deserializer};
|
||||||
element::*, implement_deserializer::implement_deserializer, label::build_label_name,
|
|
||||||
};
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::DataStruct;
|
use syn::DataStruct;
|
||||||
@ -19,31 +17,26 @@ pub fn serialize(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
if !field_attrs.attribute {
|
if !Field::is_attribute(field) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let label = &field.ident;
|
let label = Field::label(field);
|
||||||
|
let label_name = Field::renamed_label(field, root_attributes);
|
||||||
|
|
||||||
let label_name = build_label_name(
|
match Field::from(field) {
|
||||||
&label.as_ref().unwrap(),
|
Field::FieldString
|
||||||
&field_attrs,
|
| Field::FieldBool
|
||||||
&root_attributes.default_namespace,
|
| Field::FieldI8
|
||||||
);
|
| Field::FieldU8
|
||||||
|
| Field::FieldI16
|
||||||
get_field_type(field).and_then(|f| match f {
|
| Field::FieldU16
|
||||||
FieldType::FieldTypeString
|
| Field::FieldI32
|
||||||
| FieldType::FieldTypeBool
|
| Field::FieldU32
|
||||||
| FieldType::FieldTypeI8
|
| Field::FieldI64
|
||||||
| FieldType::FieldTypeU8
|
| Field::FieldU64
|
||||||
| FieldType::FieldTypeI16
|
| Field::FieldF32
|
||||||
| FieldType::FieldTypeU16
|
| Field::FieldF64 => {
|
||||||
| FieldType::FieldTypeI32
|
|
||||||
| FieldType::FieldTypeU32
|
|
||||||
| FieldType::FieldTypeI64
|
|
||||||
| FieldType::FieldTypeU64
|
|
||||||
| FieldType::FieldTypeF32
|
|
||||||
| FieldType::FieldTypeF64 => {
|
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref d) = field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
@ -62,8 +55,8 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeOption { data_type } => match *data_type {
|
Field::FieldOption { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeString => {
|
Field::FieldString => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref d) = field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
@ -89,17 +82,17 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeBool
|
Field::FieldBool
|
||||||
| FieldType::FieldTypeI8
|
| Field::FieldI8
|
||||||
| FieldType::FieldTypeU8
|
| Field::FieldU8
|
||||||
| FieldType::FieldTypeI16
|
| Field::FieldI16
|
||||||
| FieldType::FieldTypeU16
|
| Field::FieldU16
|
||||||
| FieldType::FieldTypeI32
|
| Field::FieldI32
|
||||||
| FieldType::FieldTypeU32
|
| Field::FieldU32
|
||||||
| FieldType::FieldTypeI64
|
| Field::FieldI64
|
||||||
| FieldType::FieldTypeU64
|
| Field::FieldU64
|
||||||
| FieldType::FieldTypeF32
|
| Field::FieldF32
|
||||||
| FieldType::FieldTypeF64 => {
|
| Field::FieldF64 => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref d) = field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
@ -127,7 +120,7 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeVec { .. } => {
|
Field::FieldVec { .. } => {
|
||||||
let item_ident = Ident::new("yaserde_item", field.span());
|
let item_ident = Ident::new("yaserde_item", field.span());
|
||||||
let inner = enclose_formatted_characters(&item_ident, label_name);
|
let inner = enclose_formatted_characters(&item_ident, label_name);
|
||||||
|
|
||||||
@ -151,7 +144,7 @@ pub fn serialize(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeStruct { .. } => {
|
Field::FieldStruct { .. } => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref d) = field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
@ -183,7 +176,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
},
|
},
|
||||||
FieldType::FieldTypeStruct { .. } => {
|
Field::FieldStruct { .. } => {
|
||||||
if let Some(ref d) = field_attrs.default {
|
if let Some(ref d) = field_attrs.default {
|
||||||
let default_function = Ident::new(&d, field.span());
|
let default_function = Ident::new(&d, field.span());
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
@ -203,7 +196,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
@ -213,51 +206,49 @@ pub fn serialize(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||||
if field_attrs.attribute {
|
if Field::is_attribute(field) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let label = &field.ident;
|
let label = Field::label(field);
|
||||||
if field_attrs.text {
|
if Field::is_text_content(field) {
|
||||||
return Some(quote!(
|
return Some(quote!(
|
||||||
let data_event = XmlEvent::characters(&self.#label);
|
let data_event = XmlEvent::characters(&self.#label);
|
||||||
writer.write(data_event).map_err(|e| e.to_string())?;
|
writer.write(data_event).map_err(|e| e.to_string())?;
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let label_name = build_label_name(
|
let label_name = Field::renamed_label(field, root_attributes);
|
||||||
&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 {
|
let conditions = condition_generator(&label, &field_attrs);
|
||||||
FieldType::FieldTypeString
|
|
||||||
| FieldType::FieldTypeBool
|
match Field::from(field) {
|
||||||
| FieldType::FieldTypeI8
|
Field::FieldString
|
||||||
| FieldType::FieldTypeU8
|
| Field::FieldBool
|
||||||
| FieldType::FieldTypeI16
|
| Field::FieldI8
|
||||||
| FieldType::FieldTypeU16
|
| Field::FieldU8
|
||||||
| FieldType::FieldTypeI32
|
| Field::FieldI16
|
||||||
| FieldType::FieldTypeU32
|
| Field::FieldU16
|
||||||
| FieldType::FieldTypeI64
|
| Field::FieldI32
|
||||||
| FieldType::FieldTypeU64
|
| Field::FieldU32
|
||||||
| FieldType::FieldTypeF32
|
| Field::FieldI64
|
||||||
| FieldType::FieldTypeF64 => serialize_element(label, label_name, &conditions),
|
| Field::FieldU64
|
||||||
FieldType::FieldTypeOption { data_type } => match *data_type {
|
| Field::FieldF32
|
||||||
FieldType::FieldTypeString
|
| Field::FieldF64 => serialize_element(&label, label_name, &conditions),
|
||||||
| FieldType::FieldTypeBool
|
|
||||||
| FieldType::FieldTypeI8
|
Field::FieldOption { data_type } => match *data_type {
|
||||||
| FieldType::FieldTypeU8
|
Field::FieldString
|
||||||
| FieldType::FieldTypeI16
|
| Field::FieldBool
|
||||||
| FieldType::FieldTypeU16
|
| Field::FieldI8
|
||||||
| FieldType::FieldTypeI32
|
| Field::FieldU8
|
||||||
| FieldType::FieldTypeU32
|
| Field::FieldI16
|
||||||
| FieldType::FieldTypeI64
|
| Field::FieldU16
|
||||||
| FieldType::FieldTypeU64
|
| Field::FieldI32
|
||||||
| FieldType::FieldTypeF32
|
| Field::FieldU32
|
||||||
| FieldType::FieldTypeF64 => {
|
| Field::FieldI64
|
||||||
|
| Field::FieldU64
|
||||||
|
| Field::FieldF32
|
||||||
|
| Field::FieldF64 => {
|
||||||
let item_ident = Ident::new("yaserde_item", field.span());
|
let item_ident = Ident::new("yaserde_item", field.span());
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
|
|
||||||
@ -269,7 +260,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeVec { .. } => {
|
Field::FieldVec { .. } => {
|
||||||
let item_ident = Ident::new("yaserde_item", field.span());
|
let item_ident = Ident::new("yaserde_item", field.span());
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
|
|
||||||
@ -283,7 +274,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeStruct { .. } => Some(if field_attrs.flatten {
|
Field::FieldStruct { .. } => Some(if field_attrs.flatten {
|
||||||
quote! {
|
quote! {
|
||||||
if let Some(ref item) = &self.#label {
|
if let Some(ref item) = &self.#label {
|
||||||
writer.set_start_event_name(None);
|
writer.set_start_event_name(None);
|
||||||
@ -302,7 +293,7 @@ pub fn serialize(
|
|||||||
}),
|
}),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
},
|
},
|
||||||
FieldType::FieldTypeStruct { .. } => {
|
Field::FieldStruct { .. } => {
|
||||||
let (start_event, skip_start) = if field_attrs.flatten {
|
let (start_event, skip_start) = if field_attrs.flatten {
|
||||||
(quote!(None), true)
|
(quote!(None), true)
|
||||||
} else {
|
} else {
|
||||||
@ -315,8 +306,8 @@ pub fn serialize(
|
|||||||
self.#label.serialize(writer)?;
|
self.#label.serialize(writer)?;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeVec { data_type } => match *data_type {
|
Field::FieldVec { data_type } => match *data_type {
|
||||||
FieldType::FieldTypeString => {
|
Field::FieldString => {
|
||||||
let item_ident = Ident::new("yaserde_item", field.span());
|
let item_ident = Ident::new("yaserde_item", field.span());
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
|
|
||||||
@ -326,17 +317,17 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeBool
|
Field::FieldBool
|
||||||
| FieldType::FieldTypeI8
|
| Field::FieldI8
|
||||||
| FieldType::FieldTypeU8
|
| Field::FieldU8
|
||||||
| FieldType::FieldTypeI16
|
| Field::FieldI16
|
||||||
| FieldType::FieldTypeU16
|
| Field::FieldU16
|
||||||
| FieldType::FieldTypeI32
|
| Field::FieldI32
|
||||||
| FieldType::FieldTypeU32
|
| Field::FieldU32
|
||||||
| FieldType::FieldTypeI64
|
| Field::FieldI64
|
||||||
| FieldType::FieldTypeU64
|
| Field::FieldU64
|
||||||
| FieldType::FieldTypeF32
|
| Field::FieldF32
|
||||||
| FieldType::FieldTypeF64 => {
|
| Field::FieldF64 => {
|
||||||
let item_ident = Ident::new("yaserde_item", field.span());
|
let item_ident = Ident::new("yaserde_item", field.span());
|
||||||
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
let inner = enclose_formatted_characters_for_value(&item_ident, label_name);
|
||||||
|
|
||||||
@ -346,7 +337,7 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
FieldType::FieldTypeOption { .. } => Some(quote! {
|
Field::FieldOption { .. } => Some(quote! {
|
||||||
for item in &self.#label {
|
for item in &self.#label {
|
||||||
if let Some(value) = item {
|
if let Some(value) = item {
|
||||||
writer.set_start_event_name(None);
|
writer.set_start_event_name(None);
|
||||||
@ -355,18 +346,18 @@ pub fn serialize(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
FieldType::FieldTypeStruct { .. } => Some(quote! {
|
Field::FieldStruct { .. } => Some(quote! {
|
||||||
for item in &self.#label {
|
for item in &self.#label {
|
||||||
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)?;
|
item.serialize(writer)?;
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
FieldType::FieldTypeVec { .. } => {
|
Field::FieldVec { .. } => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
}
|
||||||
})
|
})
|
||||||
.filter_map(|x| x)
|
.filter_map(|x| x)
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::attribute::YaSerdeAttribute;
|
use crate::common::YaSerdeAttribute;
|
||||||
use crate::ser::namespace::generate_namespaces_definition;
|
use crate::ser::namespace::generate_namespaces_definition;
|
||||||
use proc_macro2::Ident;
|
use proc_macro2::Ident;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::attribute::YaSerdeAttribute;
|
use crate::common::YaSerdeAttribute;
|
||||||
use proc_macro2::Ident;
|
use proc_macro2::Ident;
|
||||||
|
|
||||||
pub fn build_label_name(
|
pub fn build_label_name(
|
||||||
|
|||||||
@ -5,7 +5,7 @@ pub mod implement_deserializer;
|
|||||||
pub mod label;
|
pub mod label;
|
||||||
pub mod namespace;
|
pub mod namespace;
|
||||||
|
|
||||||
use crate::attribute::YaSerdeAttribute;
|
use crate::common::YaSerdeAttribute;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn;
|
use syn;
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::attribute::YaSerdeAttribute;
|
use crate::common::YaSerdeAttribute;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
pub fn generate_namespaces_definition(attributes: &YaSerdeAttribute) -> TokenStream {
|
pub fn generate_namespaces_definition(attributes: &YaSerdeAttribute) -> TokenStream {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user