Extract more fields
This commit is contained in:
parent
5f120f39fc
commit
5b70b293b9
|
@ -15,81 +15,22 @@ pub fn create_return_type(
|
||||||
None => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let to_enum_name = |name: &str| {
|
let to_enum_name = |name: &str| to_enum_name(&group.name, &method.name, name);
|
||||||
format!(
|
|
||||||
"{}{}{}",
|
|
||||||
group.name.to_camel(),
|
|
||||||
method.name.to_camel(),
|
|
||||||
name.to_camel()
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let enum_types_with_names = return_type
|
let enum_types_with_names: Vec<(String, proc_macro2::TokenStream)> =
|
||||||
.parameters
|
create_enum_with_names(return_type, &group.name, &method.name);
|
||||||
.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_names: HashMap<String, String> = enum_types_with_names
|
let enum_names: HashMap<String, String> = enum_types_with_names
|
||||||
.clone()
|
.iter()
|
||||||
.map(|(enum_name, _)| (enum_name.clone(), 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.iter().map(|(_, enum_type)| enum_type);
|
||||||
|
|
||||||
let builder_fields = return_type.parameters.iter().map(|parameter| {
|
let builder_fields = return_type
|
||||||
let namestr = ¶meter.name;
|
.parameters
|
||||||
let name = util::to_ident(&namestr.to_snake().replace("__", "_"));
|
.iter()
|
||||||
let enum_name = match enum_names.get(namestr) {
|
.map(|parameter| generate_builder_field(parameter, &enum_names));
|
||||||
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 return_type_name = util::to_ident(&format!(
|
let return_type_name = util::to_ident(&format!(
|
||||||
"{}{}Result",
|
"{}{}Result",
|
||||||
|
@ -98,13 +39,9 @@ pub fn create_return_type(
|
||||||
));
|
));
|
||||||
|
|
||||||
let result_type = if return_type.is_list {
|
let result_type = if return_type.is_list {
|
||||||
quote! {
|
quote! { std::vec::Vec<#return_type_name> }
|
||||||
std::vec::Vec<#return_type_name>
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! { #return_type_name }
|
||||||
#return_type_name
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((
|
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>(
|
fn create_enum_field_value<F>(
|
||||||
type_description: &types::TypeDescription,
|
type_description: &types::TypeDescription,
|
||||||
name: &str,
|
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};
|
use crate::{md_parser, parser::util, types};
|
||||||
|
|
||||||
|
pub use return_type::ReturnType;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
description::parse_method_description,
|
description::parse_method_description, parameters::parse_parameters,
|
||||||
parameters::parse_parameters,
|
return_type::parse_return_type, url::get_method_url,
|
||||||
return_type::{parse_return_type, ReturnType},
|
|
||||||
url::get_method_url,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod url;
|
||||||
use crate::md_parser;
|
use crate::md_parser;
|
||||||
|
|
||||||
use self::{description::parse_group_description, method::parse_api_method, url::get_group_url};
|
use self::{description::parse_group_description, method::parse_api_method, url::get_group_url};
|
||||||
|
pub use method::{ApiMethod, ReturnType};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApiGroup {
|
pub struct ApiGroup {
|
||||||
|
@ -14,8 +15,6 @@ pub struct ApiGroup {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use method::ApiMethod;
|
|
||||||
|
|
||||||
pub fn parse_api_group(tree: &md_parser::TokenTree) -> ApiGroup {
|
pub fn parse_api_group(tree: &md_parser::TokenTree) -> ApiGroup {
|
||||||
let methods = tree.children.iter().flat_map(parse_api_method).collect();
|
let methods = tree.children.iter().flat_map(parse_api_method).collect();
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,7 @@ pub struct ReturnTypeParameter {
|
||||||
pub return_type: types::Type,
|
pub return_type: types::Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use group::ApiGroup;
|
pub use group::{ApiGroup, ApiMethod, ReturnType};
|
||||||
pub use group::ApiMethod;
|
|
||||||
|
|
||||||
pub fn parse_api_groups(token_tree: md_parser::TokenTree) -> Vec<ApiGroup> {
|
pub fn parse_api_groups(token_tree: md_parser::TokenTree) -> Vec<ApiGroup> {
|
||||||
parse_groups(extract_relevant_parts(token_tree))
|
parse_groups(extract_relevant_parts(token_tree))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user