continue to refactor code using common Field structure
This commit is contained in:
@@ -1,28 +1,24 @@
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use syn::Ident;
|
||||
use crate::common::YaSerdeField;
|
||||
use proc_macro2::TokenStream;
|
||||
|
||||
pub fn build_default_value(
|
||||
label: &Option<Ident>,
|
||||
field_type: &TokenStream,
|
||||
value: &TokenStream,
|
||||
default: &Option<String>,
|
||||
field: &YaSerdeField,
|
||||
field_type: Option<TokenStream>,
|
||||
value: TokenStream,
|
||||
) -> Option<TokenStream> {
|
||||
let value = default
|
||||
.as_ref()
|
||||
.map(|d| {
|
||||
let default_function = Ident::new(
|
||||
&d,
|
||||
label
|
||||
.as_ref()
|
||||
.map_or(Span::call_site(), |ident| ident.span()),
|
||||
);
|
||||
let label = field.get_value_label();
|
||||
|
||||
quote!(#default_function())
|
||||
})
|
||||
let default_value = field
|
||||
.get_default_function()
|
||||
.map(|default_function| quote!(#default_function()))
|
||||
.unwrap_or_else(|| quote!(#value));
|
||||
|
||||
let field_type = field_type
|
||||
.map(|field_type| quote!(: #field_type))
|
||||
.unwrap_or(quote!());
|
||||
|
||||
Some(quote! {
|
||||
#[allow(unused_mut)]
|
||||
let mut #label : #field_type = #value;
|
||||
let mut #label #field_type = #default_value;
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
use crate::common::{Field, YaSerdeAttribute};
|
||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
use proc_macro2::TokenStream;
|
||||
use syn::{
|
||||
spanned::Spanned,
|
||||
DataEnum,
|
||||
Fields,
|
||||
Ident,
|
||||
};
|
||||
use syn::{DataEnum, Fields, Ident};
|
||||
|
||||
pub fn parse(
|
||||
data_enum: &DataEnum,
|
||||
@@ -142,9 +137,10 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
||||
fields
|
||||
.unnamed
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.enumerate()
|
||||
.map(|(idx, field)| {
|
||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span());
|
||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span());
|
||||
|
||||
let make_visitor =
|
||||
|visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| {
|
||||
@@ -172,7 +168,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream {
|
||||
)
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => {
|
||||
let struct_id: String = struct_name
|
||||
.segments
|
||||
@@ -208,9 +204,10 @@ fn build_unnamed_visitor_calls(
|
||||
fields
|
||||
.unnamed
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.enumerate()
|
||||
.map(|(idx, field)| {
|
||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span());
|
||||
let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.get_span());
|
||||
|
||||
let call_simple_type_visitor = |simple_type: Field, action| {
|
||||
let visitor = simple_type.get_simple_type_visitor();
|
||||
@@ -278,7 +275,7 @@ fn build_unnamed_visitor_calls(
|
||||
}
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_val),
|
||||
Field::FieldOption { data_type } => match *data_type {
|
||||
Field::FieldStruct { struct_name } => call_struct_visitor(struct_name, set_opt),
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
use crate::common::{Field, YaSerdeAttribute};
|
||||
use crate::common::{Field, YaSerdeAttribute, YaSerdeField};
|
||||
use crate::de::build_default_value::build_default_value;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use std::collections::BTreeMap;
|
||||
use syn::{
|
||||
spanned::Spanned,
|
||||
DataStruct,
|
||||
Ident,
|
||||
};
|
||||
use syn::{DataStruct, Ident};
|
||||
|
||||
pub fn parse(
|
||||
data_struct: &DataStruct,
|
||||
@@ -17,9 +12,9 @@ pub fn parse(
|
||||
let namespaces_matches: TokenStream = root_attributes
|
||||
.namespaces
|
||||
.iter()
|
||||
.map(|(p, ns)| {
|
||||
if root_attributes.prefix.as_ref() == Some(p) {
|
||||
Some(quote!(#ns => {}))
|
||||
.map(|(prefix, namespace)| {
|
||||
if root_attributes.prefix.as_ref() == Some(prefix) {
|
||||
Some(quote!(#namespace => {}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -30,63 +25,32 @@ pub fn parse(
|
||||
let variables: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
let label = &get_value_label(&field.ident);
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
|
||||
match Field::from(field) {
|
||||
Field::FieldStruct { struct_name } => build_default_value(
|
||||
label,
|
||||
"e! {#struct_name},
|
||||
"e! {#struct_name::default()},
|
||||
&field_attrs.default,
|
||||
),
|
||||
Field::FieldOption { .. } => {
|
||||
if let Some(d) = &field_attrs.default {
|
||||
let default_function = Ident::new(&d, field.span());
|
||||
|
||||
Some(quote! {
|
||||
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
|
||||
let mut #label = #default_function();
|
||||
})
|
||||
} else {
|
||||
Some(quote! {
|
||||
#[allow(unused_mut, non_snake_case, non_camel_case_types)]
|
||||
let mut #label = None;
|
||||
})
|
||||
}
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.map(|field| match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => build_default_value(
|
||||
&field,
|
||||
Some(quote!(#struct_name)),
|
||||
quote!(#struct_name::default()),
|
||||
),
|
||||
Field::FieldOption { .. } => build_default_value(&field, None, quote!(None)),
|
||||
Field::FieldVec { data_type } => match *data_type {
|
||||
Field::FieldStruct { ref struct_name } => {
|
||||
build_default_value(&field, Some(quote!(Vec<#struct_name>)), quote!(vec![]))
|
||||
}
|
||||
Field::FieldOption { .. } | Field::FieldVec { .. } => {
|
||||
unimplemented!();
|
||||
}
|
||||
Field::FieldVec { data_type } => match *data_type {
|
||||
Field::FieldStruct { ref struct_name } => build_default_value(
|
||||
label,
|
||||
"e! {Vec<#struct_name>},
|
||||
"e! {vec![]},
|
||||
&field_attrs.default,
|
||||
),
|
||||
Field::FieldOption { .. } | Field::FieldVec { .. } => {
|
||||
unimplemented!();
|
||||
}
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
|
||||
build_default_value(
|
||||
label,
|
||||
"e! {Vec<#type_token>},
|
||||
"e! {vec![]},
|
||||
&field_attrs.default,
|
||||
)
|
||||
}
|
||||
},
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
|
||||
build_default_value(
|
||||
label,
|
||||
&type_token,
|
||||
"e! {#type_token::default()},
|
||||
&field_attrs.default,
|
||||
)
|
||||
build_default_value(&field, Some(quote!(Vec<#type_token>)), quote!(vec![]))
|
||||
}
|
||||
},
|
||||
simple_type => {
|
||||
let type_token: TokenStream = simple_type.into();
|
||||
let value_builder = quote!(#type_token::default());
|
||||
|
||||
build_default_value(&field, Some(type_token), value_builder)
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
@@ -95,12 +59,8 @@ pub fn parse(
|
||||
let field_visitors: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.map(|field| {
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
let label_name = field_attrs
|
||||
.rename
|
||||
.unwrap_or_else(|| field.ident.as_ref().unwrap().to_string());
|
||||
|
||||
let struct_visitor = |struct_name: syn::Path| {
|
||||
let struct_id: String = struct_name
|
||||
.segments
|
||||
@@ -108,7 +68,7 @@ pub fn parse(
|
||||
.map(|s| s.ident.to_string())
|
||||
.collect();
|
||||
|
||||
let visitor_label = build_visitor_ident(&label_name, field.span(), Some(&struct_name));
|
||||
let visitor_label = field.get_visitor_ident(Some(&struct_name));
|
||||
|
||||
Some(quote! {
|
||||
#[allow(non_snake_case, non_camel_case_types)]
|
||||
@@ -127,7 +87,7 @@ pub fn parse(
|
||||
|
||||
let simple_type_visitor = |simple_type: Field| {
|
||||
let visitor = simple_type.get_simple_type_visitor();
|
||||
let visitor_label = build_visitor_ident(&label_name, field.span(), None);
|
||||
let visitor_label = field.get_visitor_ident(None);
|
||||
let field_type: TokenStream = simple_type.into();
|
||||
|
||||
Some(quote! {
|
||||
@@ -143,7 +103,7 @@ pub fn parse(
|
||||
})
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => struct_visitor(struct_name),
|
||||
Field::FieldOption { data_type } => match *data_type {
|
||||
Field::FieldStruct { struct_name } => struct_visitor(struct_name),
|
||||
@@ -164,19 +124,11 @@ pub fn parse(
|
||||
let call_visitors: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.filter(|field| !field.is_attribute() || !field.is_flatten())
|
||||
.map(|field| {
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
let label = &field.ident;
|
||||
let value_label = &get_value_label(&field.ident);
|
||||
|
||||
if field_attrs.attribute || field_attrs.flatten {
|
||||
return None;
|
||||
}
|
||||
|
||||
let label_name = field_attrs
|
||||
.rename
|
||||
.clone()
|
||||
.unwrap_or_else(|| label.as_ref().unwrap().to_string());
|
||||
let value_label = field.get_value_label();
|
||||
let label_name = field.renamed_label_without_namespace();
|
||||
|
||||
let visit_struct = |struct_name: syn::Path, action: TokenStream| {
|
||||
Some(quote! {
|
||||
@@ -201,10 +153,8 @@ pub fn parse(
|
||||
&field_type,
|
||||
&field_visitor,
|
||||
&action,
|
||||
&field_attrs,
|
||||
label,
|
||||
&root_attributes.namespaces,
|
||||
field.span(),
|
||||
&field,
|
||||
&root_attributes,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -214,7 +164,7 @@ pub fn parse(
|
||||
simple_type => visit_simple(simple_type, action),
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { struct_name } => visit_struct(struct_name, quote! {= value}),
|
||||
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||
Field::FieldVec { data_type } => visit_sub(data_type, quote! {.push(value)}),
|
||||
@@ -227,15 +177,12 @@ pub fn parse(
|
||||
let call_flatten_visitors: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.filter(|field| !field.is_attribute() && field.is_flatten())
|
||||
.map(|field| {
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
let value_label = &get_value_label(&field.ident);
|
||||
let value_label = field.get_value_label();
|
||||
|
||||
if field_attrs.attribute || !field_attrs.flatten {
|
||||
return None;
|
||||
}
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldStruct { .. } => Some(quote! {
|
||||
#value_label = yaserde::de::from_str(&unused_xml_elements)?;
|
||||
}),
|
||||
@@ -243,9 +190,9 @@ pub fn parse(
|
||||
Field::FieldStruct { .. } => Some(quote! {
|
||||
#value_label = yaserde::de::from_str(&unused_xml_elements).ok();
|
||||
}),
|
||||
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
||||
field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type),
|
||||
},
|
||||
field_type => unimplemented!("\"flatten\" is not implemented for {:?}", field_type),
|
||||
field_type => unimplemented!(r#""flatten" is not implemented for {:?}"#, field_type),
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
@@ -254,19 +201,12 @@ pub fn parse(
|
||||
let attributes_loading: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.filter(|field| field.is_attribute())
|
||||
.map(|field| {
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
if !field_attrs.attribute {
|
||||
return None;
|
||||
}
|
||||
|
||||
let label = &get_value_label(&field.ident);
|
||||
|
||||
let label_name = field_attrs
|
||||
.rename
|
||||
.unwrap_or_else(|| field.ident.as_ref().unwrap().to_string());
|
||||
|
||||
let visitor_label = build_visitor_ident(&label_name, field.span(), None);
|
||||
let label = field.get_value_label();
|
||||
let label_name = field.renamed_label_without_namespace();
|
||||
let visitor_label = build_visitor_ident(&label_name, field.get_span(), None);
|
||||
|
||||
let visit = |action: &TokenStream, visitor: &TokenStream, visitor_label: &Ident| {
|
||||
Some(quote! {
|
||||
@@ -294,7 +234,7 @@ pub fn parse(
|
||||
visit(
|
||||
&action,
|
||||
"e! {visit_str},
|
||||
&build_visitor_ident(&label_name, field.span(), Some(&struct_name)),
|
||||
&build_visitor_ident(&label_name, field.get_span(), Some(&struct_name)),
|
||||
)
|
||||
};
|
||||
|
||||
@@ -312,7 +252,7 @@ pub fn parse(
|
||||
simple_type => visit_simple(simple_type, action),
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldString => visit_string(),
|
||||
Field::FieldOption { data_type } => visit_sub(data_type, quote! {= Some(value)}),
|
||||
Field::FieldVec { .. } => unimplemented!(),
|
||||
@@ -326,19 +266,19 @@ pub fn parse(
|
||||
let set_text: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.map(|field| {
|
||||
let label = &get_value_label(&field.ident);
|
||||
let field_attrs = YaSerdeAttribute::parse(&field.attrs);
|
||||
let label = field.get_value_label();
|
||||
|
||||
let set_text = |action: &TokenStream| {
|
||||
if field_attrs.text {
|
||||
if field.is_text_content() {
|
||||
Some(quote! {#label = #action;})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
match Field::from(field) {
|
||||
match field.get_type() {
|
||||
Field::FieldString => set_text("e! {text_content.to_owned()}),
|
||||
Field::FieldStruct { .. } | Field::FieldOption { .. } | Field::FieldVec { .. } => None,
|
||||
simple_type => {
|
||||
@@ -353,9 +293,10 @@ pub fn parse(
|
||||
let struct_builder: TokenStream = data_struct
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| YaSerdeField::new(field.clone()))
|
||||
.map(|field| {
|
||||
let label = &field.ident;
|
||||
let value_label = &get_value_label(&field.ident);
|
||||
let label = &field.label();
|
||||
let value_label = field.get_value_label();
|
||||
|
||||
quote! { #label: #value_label, }
|
||||
})
|
||||
@@ -471,33 +412,14 @@ fn build_call_visitor(
|
||||
field_type: &TokenStream,
|
||||
visitor: &TokenStream,
|
||||
action: &TokenStream,
|
||||
field_attrs: &YaSerdeAttribute,
|
||||
label: &Option<Ident>,
|
||||
namespaces: &BTreeMap<String, String>,
|
||||
span: Span,
|
||||
field: &YaSerdeField,
|
||||
root_attributes: &YaSerdeAttribute,
|
||||
) -> Option<TokenStream> {
|
||||
let prefix = field_attrs.prefix.clone();
|
||||
let value_label = field.get_value_label();
|
||||
let label_name = field.renamed_label_without_namespace();
|
||||
let visitor_label = build_visitor_ident(&label_name, field.get_span(), None);
|
||||
|
||||
// let label = &field.ident;
|
||||
let value_label = get_value_label(label);
|
||||
let label_name = field_attrs
|
||||
.rename
|
||||
.clone()
|
||||
.unwrap_or_else(|| label.as_ref().unwrap().to_string());
|
||||
|
||||
let visitor_label = build_visitor_ident(&label_name, span, None);
|
||||
|
||||
let namespaces_matches: TokenStream = namespaces
|
||||
.iter()
|
||||
.map(|(p, ns)| {
|
||||
if prefix == Some(p.to_string()) {
|
||||
Some(quote!(#ns => {}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(|x| x)
|
||||
.collect();
|
||||
let namespaces_matches = field.get_namespace_matching(root_attributes);
|
||||
|
||||
Some(quote! {
|
||||
#label_name => {
|
||||
@@ -530,12 +452,6 @@ fn build_call_visitor(
|
||||
})
|
||||
}
|
||||
|
||||
fn get_value_label(ident: &Option<syn::Ident>) -> Option<syn::Ident> {
|
||||
ident
|
||||
.clone()
|
||||
.map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span()))
|
||||
}
|
||||
|
||||
fn build_visitor_ident(label: &str, span: Span, struct_name: Option<&syn::Path>) -> Ident {
|
||||
let struct_id = struct_name.map_or_else(
|
||||
|| "".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user