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, ref name,
type_description: Some(type_description), type_description: Some(type_description),
.. ..
}) => { }) => create_enum_field_value(type_description, name, create_number_enum_value),
let enum_fields: Vec<proc_macro2::TokenStream> = type_description
.values
.iter()
.map(create_number_enum_value)
.collect();
Some((name, enum_fields))
}
types::Type::String(types::TypeInfo { types::Type::String(types::TypeInfo {
ref name, ref name,
type_description: Some(type_description), type_description: Some(type_description),
.. ..
}) => { }) => create_enum_field_value(type_description, name, create_string_enum_value),
let enum_fields: Vec<proc_macro2::TokenStream> = type_description
.values
.iter()
.map(create_string_enum_value)
.collect();
Some((name, enum_fields))
}
_ => None, _ => None,
}) })
.flat_map(|(name, enum_fields)| { .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(( Some((
name, 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() .clone()
.map(|(enum_name, _)| (enum_name, to_enum_name(enum_name))) .map(|(enum_name, _)| (enum_name.clone(), to_enum_name(&enum_name)))
.collect(); .collect();
let enum_types = enum_types_with_names.map(|(_, enum_type)| enum_type); 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 namestr = &parameter.name;
let name = util::to_ident(&namestr.to_snake().replace("__", "_")); let name = util::to_ident(&namestr.to_snake().replace("__", "_"));
let rtype = if let Some(enum_type) = enum_names.get(namestr) { let enum_name = match enum_names.get(namestr) {
util::to_ident(enum_type) Some(enum_type) => enum_type.to_owned(),
} else { None => parameter.return_type.to_owned_type(),
util::to_ident(&parameter.return_type.to_owned_type())
}; };
let type_info = parameter.return_type.get_type_info(); let rtype = util::to_ident(&enum_name);
let rtype_as_quote = if parameter.return_type.get_type_info().is_list {
let rtype_as_quote = if type_info.is_list { quote! { std::vec::Vec<#rtype> }
quote! {
std::vec::Vec<#rtype>
}
} else { } else {
quote! { #rtype }
};
let generate_field = |field_name| {
quote! { 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" { if namestr == "type" {
let non_reserved_name = format_ident!("t_{}", name); generate_field(format_ident!("t_{}", name))
quote! {
#[serde(rename = #namestr)]
pub #non_reserved_name: #rtype_as_quote
}
} else { } else {
quote! { generate_field(name)
#[serde(rename = #namestr)]
pub #name: #rtype_as_quote
}
} }
}); });
@ -134,7 +112,7 @@ pub fn create_return_type(
quote! { quote! {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct #return_type_name { pub struct #return_type_name {
#(#parameters,)* #(#builder_fields,)*
} }
#(#enum_types)* #(#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( fn create_string_enum_value(
type_description: &types::TypeDescriptions, type_description: &types::TypeDescriptions,
) -> proc_macro2::TokenStream { ) -> proc_macro2::TokenStream {