Avoid consts for deserialization field recognition

This commit is contained in:
Dirkjan Ochtman 2022-11-21 20:27:36 -08:00
parent 0be3c92d27
commit 413ec05c52
1 changed files with 24 additions and 44 deletions

View File

@ -115,15 +115,21 @@ fn deserialize_struct(
// Elements // Elements
let elements_enum = elements_tokens.r#enum; let elements_enum = elements_tokens.r#enum;
let elements_consts = elements_tokens.consts; let mut elements_branches = elements_tokens.branches;
let elements_names = elements_tokens.names;
let elem_type_match = elements_tokens.r#match; let elem_type_match = elements_tokens.r#match;
elements_branches.extend(match elements_branches.is_empty() {
true => quote!(__Elements::__Ignore),
false => quote!(else { __Elements::__Ignore }),
});
// Attributes // Attributes
let attributes_enum = attributes_tokens.r#enum; let attributes_enum = attributes_tokens.r#enum;
let attributes_consts = attributes_tokens.consts; let mut attributes_branches = attributes_tokens.branches;
let attributes_names = attributes_tokens.names;
let attr_type_match = attributes_tokens.r#match; let attr_type_match = attributes_tokens.r#match;
attributes_branches.extend(match attributes_branches.is_empty() {
true => quote!(__Attributes::__Ignore),
false => quote!(else { __Attributes::__Ignore }),
});
let ident = &input.ident; let ident = &input.ident;
let name = container_meta.tag(); let name = container_meta.tag();
@ -160,13 +166,7 @@ fn deserialize_struct(
match node { match node {
Node::Attribute(attr) => { Node::Attribute(attr) => {
let id = deserializer.attribute_id(&attr)?; let id = deserializer.attribute_id(&attr)?;
let field = { let field = #attributes_branches;
#attributes_consts
match id {
#attributes_names
_ => __Attributes::__Ignore
}
};
match field { match field {
#attr_type_match #attr_type_match
@ -175,13 +175,7 @@ fn deserialize_struct(
} }
Node::Open(data) => { Node::Open(data) => {
let id = deserializer.element_id(&data)?; let id = deserializer.element_id(&data)?;
let element = { let element = #elements_branches;
#elements_consts
match id {
#elements_names
_ => __Elements::__Ignore
}
};
match element { match element {
#elem_type_match #elem_type_match
@ -229,28 +223,25 @@ fn process_field(
None => quote!(""), None => quote!(""),
}; };
let const_field_var_str = Ident::new(&field_name.to_string().to_uppercase(), Span::call_site());
let mut no_lifetime_type = field.ty.clone(); let mut no_lifetime_type = field.ty.clone();
discard_lifetimes(&mut no_lifetime_type); discard_lifetimes(&mut no_lifetime_type);
let enum_name = Ident::new(&format!("__Value{index}"), Span::call_site()); let enum_name = Ident::new(&format!("__Value{index}"), Span::call_site());
tokens.r#enum.extend(quote!(#enum_name,)); tokens.r#enum.extend(quote!(#enum_name,));
tokens.consts.extend(quote!( if !tokens.branches.is_empty() {
const #const_field_var_str: Id<'static> = <#no_lifetime_type as FromXml<'_>>::KIND.name( tokens.branches.extend(quote!(else));
}
tokens.branches.extend(quote!(
if id == <#no_lifetime_type as FromXml>::KIND.name(
Id { ns: #ns, name: #field_tag } Id { ns: #ns, name: #field_tag }
); )
)); ));
if !field_meta.attribute { tokens.branches.extend(match field_meta.attribute {
tokens.names.extend(quote!( true => quote!({ __Attributes::#enum_name }),
#const_field_var_str => __Elements::#enum_name, false => quote!({ __Elements::#enum_name }),
)); });
} else {
tokens.names.extend(quote!(
#const_field_var_str => __Attributes::#enum_name,
));
}
declare_values.extend(quote!( declare_values.extend(quote!(
let mut #enum_name: Option<#no_lifetime_type> = None; let mut #enum_name: Option<#no_lifetime_type> = None;
@ -288,20 +279,9 @@ fn process_field(
)); ));
} }
#[derive(Default)]
struct Tokens { struct Tokens {
r#enum: TokenStream, r#enum: TokenStream,
consts: TokenStream, branches: TokenStream,
names: TokenStream,
r#match: TokenStream, r#match: TokenStream,
} }
impl Default for Tokens {
fn default() -> Self {
Self {
r#enum: TokenStream::new(),
consts: TokenStream::new(),
names: TokenStream::new(),
r#match: TokenStream::new(),
}
}
}