Extract common parts

This commit is contained in:
Joel Wachsler 2022-07-12 15:34:27 +00:00
parent 7349f305fb
commit 5f120f39fc

View File

@ -32,32 +32,16 @@ pub fn create_return_type(
ref name,
type_description: Some(type_description),
..
}) => {
let enum_fields: Vec<proc_macro2::TokenStream> = type_description
.values
.iter()
.map(create_number_enum_value)
.collect();
Some((name, enum_fields))
}
}) => create_enum_field_value(type_description, name, create_number_enum_value),
types::Type::String(types::TypeInfo {
ref name,
type_description: Some(type_description),
..
}) => {
let enum_fields: Vec<proc_macro2::TokenStream> = type_description
.values
.iter()
.map(create_string_enum_value)
.collect();
Some((name, enum_fields))
}
}) => create_enum_field_value(type_description, name, create_string_enum_value),
_ => None,
})
.flat_map(|(name, enum_fields)| {
let enum_name = util::to_ident(&to_enum_name(name));
let enum_name = util::to_ident(&to_enum_name(&name));
Some((
name,
@ -71,45 +55,39 @@ pub fn create_return_type(
))
});
let enum_names: HashMap<&String, String> = enum_types_with_names
let enum_names: HashMap<String, String> = enum_types_with_names
.clone()
.map(|(enum_name, _)| (enum_name, to_enum_name(enum_name)))
.map(|(enum_name, _)| (enum_name.clone(), to_enum_name(&enum_name)))
.collect();
let enum_types = enum_types_with_names.map(|(_, enum_type)| enum_type);
let parameters = return_type.parameters.iter().map(|parameter| {
let builder_fields = return_type.parameters.iter().map(|parameter| {
let namestr = &parameter.name;
let name = util::to_ident(&namestr.to_snake().replace("__", "_"));
let rtype = if let Some(enum_type) = enum_names.get(namestr) {
util::to_ident(enum_type)
} else {
util::to_ident(&parameter.return_type.to_owned_type())
let enum_name = match enum_names.get(namestr) {
Some(enum_type) => enum_type.to_owned(),
None => parameter.return_type.to_owned_type(),
};
let type_info = parameter.return_type.get_type_info();
let rtype_as_quote = if type_info.is_list {
quote! {
std::vec::Vec<#rtype>
}
let rtype = util::to_ident(&enum_name);
let rtype_as_quote = if parameter.return_type.get_type_info().is_list {
quote! { std::vec::Vec<#rtype> }
} else {
quote! { #rtype }
};
let generate_field = |field_name| {
quote! {
#rtype
#[serde(rename = #namestr)]
pub #field_name: #rtype_as_quote
}
};
// "type" is a reserved keyword in Rust, so we use a different name.
// "type" is a reserved keyword in Rust, so we just add "t_" to it.
if namestr == "type" {
let non_reserved_name = format_ident!("t_{}", name);
quote! {
#[serde(rename = #namestr)]
pub #non_reserved_name: #rtype_as_quote
}
generate_field(format_ident!("t_{}", name))
} else {
quote! {
#[serde(rename = #namestr)]
pub #name: #rtype_as_quote
}
generate_field(name)
}
});
@ -134,7 +112,7 @@ pub fn create_return_type(
quote! {
#[derive(Debug, Deserialize)]
pub struct #return_type_name {
#(#parameters,)*
#(#builder_fields,)*
}
#(#enum_types)*
@ -142,6 +120,25 @@ pub fn create_return_type(
))
}
fn create_enum_field_value<F>(
type_description: &types::TypeDescription,
name: &str,
f: F,
) -> Option<(String, Vec<proc_macro2::TokenStream>)>
where
F: Fn(&types::TypeDescriptions) -> proc_macro2::TokenStream,
{
let enum_fields: Vec<proc_macro2::TokenStream> = type_description
.values
.iter()
.map(f)
.collect::<Vec<proc_macro2::TokenStream>>();
let nn = name.to_string();
Some((nn, enum_fields))
}
fn create_string_enum_value(
type_description: &types::TypeDescriptions,
) -> proc_macro2::TokenStream {