Extract more fields
This commit is contained in:
parent
5f120f39fc
commit
5b70b293b9
|
@ -15,81 +15,22 @@ pub fn create_return_type(
|
|||
None => return None,
|
||||
};
|
||||
|
||||
let to_enum_name = |name: &str| {
|
||||
format!(
|
||||
"{}{}{}",
|
||||
group.name.to_camel(),
|
||||
method.name.to_camel(),
|
||||
name.to_camel()
|
||||
)
|
||||
};
|
||||
let to_enum_name = |name: &str| to_enum_name(&group.name, &method.name, name);
|
||||
|
||||
let enum_types_with_names = return_type
|
||||
.parameters
|
||||
.iter()
|
||||
.flat_map(|parameter| match ¶meter.return_type {
|
||||
types::Type::Number(types::TypeInfo {
|
||||
ref name,
|
||||
type_description: Some(type_description),
|
||||
..
|
||||
}) => create_enum_field_value(type_description, name, create_number_enum_value),
|
||||
types::Type::String(types::TypeInfo {
|
||||
ref name,
|
||||
type_description: Some(type_description),
|
||||
..
|
||||
}) => 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));
|
||||
|
||||
Some((
|
||||
name,
|
||||
quote! {
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub enum #enum_name {
|
||||
#(#enum_fields,)*
|
||||
}
|
||||
},
|
||||
))
|
||||
});
|
||||
let enum_types_with_names: Vec<(String, proc_macro2::TokenStream)> =
|
||||
create_enum_with_names(return_type, &group.name, &method.name);
|
||||
|
||||
let enum_names: HashMap<String, String> = enum_types_with_names
|
||||
.clone()
|
||||
.map(|(enum_name, _)| (enum_name.clone(), to_enum_name(&enum_name)))
|
||||
.iter()
|
||||
.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 enum_types = enum_types_with_names.iter().map(|(_, enum_type)| enum_type);
|
||||
|
||||
let builder_fields = return_type.parameters.iter().map(|parameter| {
|
||||
let namestr = ¶meter.name;
|
||||
let name = util::to_ident(&namestr.to_snake().replace("__", "_"));
|
||||
let enum_name = match enum_names.get(namestr) {
|
||||
Some(enum_type) => enum_type.to_owned(),
|
||||
None => parameter.return_type.to_owned_type(),
|
||||
};
|
||||
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! {
|
||||
#[serde(rename = #namestr)]
|
||||
pub #field_name: #rtype_as_quote
|
||||
}
|
||||
};
|
||||
|
||||
// "type" is a reserved keyword in Rust, so we just add "t_" to it.
|
||||
if namestr == "type" {
|
||||
generate_field(format_ident!("t_{}", name))
|
||||
} else {
|
||||
generate_field(name)
|
||||
}
|
||||
});
|
||||
let builder_fields = return_type
|
||||
.parameters
|
||||
.iter()
|
||||
.map(|parameter| generate_builder_field(parameter, &enum_names));
|
||||
|
||||
let return_type_name = util::to_ident(&format!(
|
||||
"{}{}Result",
|
||||
|
@ -98,13 +39,9 @@ pub fn create_return_type(
|
|||
));
|
||||
|
||||
let result_type = if return_type.is_list {
|
||||
quote! {
|
||||
std::vec::Vec<#return_type_name>
|
||||
}
|
||||
quote! { std::vec::Vec<#return_type_name> }
|
||||
} else {
|
||||
quote! {
|
||||
#return_type_name
|
||||
}
|
||||
quote! { #return_type_name }
|
||||
};
|
||||
|
||||
Some((
|
||||
|
@ -120,6 +57,87 @@ pub fn create_return_type(
|
|||
))
|
||||
}
|
||||
|
||||
fn create_enum_with_names(
|
||||
return_type: &parser::ReturnType,
|
||||
group_name: &str,
|
||||
method_name: &str,
|
||||
) -> Vec<(String, proc_macro2::TokenStream)> {
|
||||
return_type
|
||||
.parameters
|
||||
.iter()
|
||||
.flat_map(create_enum_fields)
|
||||
.map(|(name, enum_fields)| create_enum(enum_fields, group_name, method_name, name))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn create_enum(
|
||||
enum_fields: Vec<proc_macro2::TokenStream>,
|
||||
group_name: &str,
|
||||
method_name: &str,
|
||||
name: String,
|
||||
) -> (String, proc_macro2::TokenStream) {
|
||||
let enum_name = util::to_ident(&to_enum_name(group_name, method_name, &name));
|
||||
(
|
||||
name,
|
||||
quote! {
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub enum #enum_name {
|
||||
#(#enum_fields,)*
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn create_enum_fields(
|
||||
parameter: &parser::ReturnTypeParameter,
|
||||
) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
|
||||
match ¶meter.return_type {
|
||||
types::Type::Number(types::TypeInfo {
|
||||
ref name,
|
||||
type_description: Some(type_description),
|
||||
..
|
||||
}) => create_enum_field_value(type_description, name, create_number_enum_value),
|
||||
types::Type::String(types::TypeInfo {
|
||||
ref name,
|
||||
type_description: Some(type_description),
|
||||
..
|
||||
}) => create_enum_field_value(type_description, name, create_string_enum_value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_builder_field(
|
||||
parameter: &parser::ReturnTypeParameter,
|
||||
enum_names: &HashMap<String, String>,
|
||||
) -> proc_macro2::TokenStream {
|
||||
let namestr = ¶meter.name;
|
||||
let name = util::to_ident(&namestr.to_snake().replace("__", "_"));
|
||||
let enum_name = match enum_names.get(namestr) {
|
||||
Some(enum_type) => enum_type.to_owned(),
|
||||
None => parameter.return_type.to_owned_type(),
|
||||
};
|
||||
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! {
|
||||
#[serde(rename = #namestr)]
|
||||
pub #field_name: #rtype_as_quote
|
||||
}
|
||||
};
|
||||
|
||||
// "type" is a reserved keyword in Rust, so we just add "t_" to it.
|
||||
if namestr == "type" {
|
||||
generate_field(format_ident!("t_{}", name))
|
||||
} else {
|
||||
generate_field(name)
|
||||
}
|
||||
}
|
||||
|
||||
fn create_enum_field_value<F>(
|
||||
type_description: &types::TypeDescription,
|
||||
name: &str,
|
||||
|
@ -174,3 +192,12 @@ fn create_enum_field(
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn to_enum_name(group_name: &str, method_name: &str, name: &str) -> String {
|
||||
format!(
|
||||
"{}{}{}",
|
||||
group_name.to_camel(),
|
||||
method_name.to_camel(),
|
||||
name.to_camel()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ mod url;
|
|||
|
||||
use crate::{md_parser, parser::util, types};
|
||||
|
||||
pub use return_type::ReturnType;
|
||||
|
||||
use self::{
|
||||
description::parse_method_description,
|
||||
parameters::parse_parameters,
|
||||
return_type::{parse_return_type, ReturnType},
|
||||
url::get_method_url,
|
||||
description::parse_method_description, parameters::parse_parameters,
|
||||
return_type::parse_return_type, url::get_method_url,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -5,6 +5,7 @@ mod url;
|
|||
use crate::md_parser;
|
||||
|
||||
use self::{description::parse_group_description, method::parse_api_method, url::get_group_url};
|
||||
pub use method::{ApiMethod, ReturnType};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ApiGroup {
|
||||
|
@ -14,8 +15,6 @@ pub struct ApiGroup {
|
|||
pub url: String,
|
||||
}
|
||||
|
||||
pub use method::ApiMethod;
|
||||
|
||||
pub fn parse_api_group(tree: &md_parser::TokenTree) -> ApiGroup {
|
||||
let methods = tree.children.iter().flat_map(parse_api_method).collect();
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@ pub struct ReturnTypeParameter {
|
|||
pub return_type: types::Type,
|
||||
}
|
||||
|
||||
pub use group::ApiGroup;
|
||||
pub use group::ApiMethod;
|
||||
pub use group::{ApiGroup, ApiMethod, ReturnType};
|
||||
|
||||
pub fn parse_api_groups(token_tree: md_parser::TokenTree) -> Vec<ApiGroup> {
|
||||
parse_groups(extract_relevant_parts(token_tree))
|
||||
|
|
Loading…
Reference in New Issue
Block a user