Use struct for return type

This commit is contained in:
Joel Wachsler 2022-07-14 23:16:59 +00:00
parent 4a862d6e36
commit 9830aa40a6
3 changed files with 76 additions and 44 deletions

View File

@ -10,7 +10,9 @@ use crate::{
types, types,
}; };
use super::{return_type::create_return_type, send_method_builder::SendMethodBuilder}; use super::{
return_type::create_return_type, send_method_builder::SendMethodBuilder, MethodsAndExtra,
};
pub fn create_method_with_params( pub fn create_method_with_params(
group: &parser::ApiGroup, group: &parser::ApiGroup,
@ -18,7 +20,7 @@ pub fn create_method_with_params(
params: &parser::ApiParameters, params: &parser::ApiParameters,
method_name: &proc_macro2::Ident, method_name: &proc_macro2::Ident,
url: &str, url: &str,
) -> (TokenStream, Option<TokenStream>) { ) -> MethodsAndExtra {
let param_type = util::to_ident(&format!( let param_type = util::to_ident(&format!(
"{}{}Parameters", "{}{}Parameters",
group.name.to_camel(), group.name.to_camel(),
@ -27,38 +29,43 @@ pub fn create_method_with_params(
let parameters = Parameters::new(params); let parameters = Parameters::new(params);
let group_name = util::to_ident(&group.name.to_camel()); if parameters.optional.is_empty() {
let send_builder = let fooz = quote! {};
SendMethodBuilder::new(&util::to_ident("send"), url, quote! { self.group.auth }) MethodsAndExtra::new(fooz)
.with_form(); } else {
let group_name = util::to_ident(&group.name.to_camel());
let send_builder =
SendMethodBuilder::new(&util::to_ident("send"), url, quote! { self.group.auth })
.with_form();
let send_impl_generator = SendImplGenerator::new(&group_name, &parameters, &param_type); let send_impl_generator = SendImplGenerator::new(&group_name, &parameters, &param_type);
let send = match create_return_type(group, method) { let send = match create_return_type(group, method) {
Some((return_type_name, return_type)) => { Some((return_type_name, return_type)) => {
let send_impl = let send_impl =
send_impl_generator.generate(send_builder.return_type(&return_type_name)); send_impl_generator.generate(send_builder.return_type(&return_type_name));
quote! { quote! {
#send_impl #send_impl
#return_type #return_type
}
} }
} None => send_impl_generator.generate(send_builder),
None => send_impl_generator.generate(send_builder), };
};
let builder = generate_builder(&parameters, method, method_name, &param_type); let builder = generate_builder(&parameters, method, method_name, &param_type);
let group_impl = quote! { let group_impl = quote! {
pub struct #param_type<'a> { pub struct #param_type<'a> {
group: &'a #group_name<'a>, group: &'a #group_name<'a>,
form: reqwest::multipart::Form, form: reqwest::multipart::Form,
} }
#send #send
}; };
(builder, Some(group_impl)) MethodsAndExtra::new(builder).with_structs(group_impl)
}
} }
fn generate_builder( fn generate_builder(
@ -196,6 +203,10 @@ impl<'a> OptionalParams<'a> {
} }
} }
fn is_empty(&self) -> bool {
self.params.is_empty()
}
fn generate_builder_methods(&self) -> Vec<TokenStream> { fn generate_builder_methods(&self) -> Vec<TokenStream> {
self.params self.params
.iter() .iter()

View File

@ -1,6 +1,8 @@
use quote::quote; use quote::quote;
use super::{return_type::create_return_type, send_method_builder::SendMethodBuilder}; use super::{
return_type::create_return_type, send_method_builder::SendMethodBuilder, MethodsAndExtra,
};
use crate::parser; use crate::parser;
pub fn create_method_without_params( pub fn create_method_without_params(
@ -8,19 +10,18 @@ pub fn create_method_without_params(
method: &parser::ApiMethod, method: &parser::ApiMethod,
method_name: proc_macro2::Ident, method_name: proc_macro2::Ident,
url: &str, url: &str,
) -> (proc_macro2::TokenStream, Option<proc_macro2::TokenStream>) { ) -> MethodsAndExtra {
let builder = SendMethodBuilder::new(&method_name, url, quote! { self.auth }) let builder = SendMethodBuilder::new(&method_name, url, quote! { self.auth })
.description(&method.description); .description(&method.description);
match create_return_type(group, method) { match create_return_type(group, method) {
Some((return_type_name, return_type)) => ( Some((return_type_name, return_type)) => {
builder.return_type(&return_type_name).build(), MethodsAndExtra::new(builder.return_type(&return_type_name).build())
Some(return_type), .with_structs(return_type)
), }
None => ( None => {
builder.build(),
// assume that all methods without a return type returns a string // assume that all methods without a return type returns a string
None, MethodsAndExtra::new(builder.build())
), }
} }
} }

View File

@ -17,13 +17,16 @@ pub fn generate_methods(
auth: &syn::Ident, auth: &syn::Ident,
group_name_camel: &syn::Ident, group_name_camel: &syn::Ident,
) -> proc_macro2::TokenStream { ) -> proc_macro2::TokenStream {
let methods_and_param_structs = group let methods_and_extra = group
.methods .methods
.iter() .iter()
.map(|method| generate_method(group, method)); .map(|method| generate_method(group, method));
let methods = methods_and_param_structs.clone().map(|(method, ..)| method); let methods = methods_and_extra
let structs = methods_and_param_structs.flat_map(|(_, s)| s); .clone()
.map(|MethodsAndExtra { methods, .. }| methods);
let extra = methods_and_extra.flat_map(|MethodsAndExtra { extra: structs, .. }| structs);
quote! { quote! {
impl <'a> #group_name_camel<'a> { impl <'a> #group_name_camel<'a> {
@ -34,14 +37,31 @@ pub fn generate_methods(
#(#methods)* #(#methods)*
} }
#(#structs)* #(#extra)*
} }
} }
fn generate_method( #[derive(Debug)]
group: &parser::ApiGroup, pub struct MethodsAndExtra {
method: &parser::ApiMethod, methods: proc_macro2::TokenStream,
) -> (proc_macro2::TokenStream, Option<proc_macro2::TokenStream>) { extra: Option<proc_macro2::TokenStream>,
}
impl MethodsAndExtra {
pub fn new(methods: proc_macro2::TokenStream) -> Self {
Self {
methods,
extra: None,
}
}
pub fn with_structs(mut self, structs: proc_macro2::TokenStream) -> Self {
self.extra = Some(structs);
self
}
}
fn generate_method(group: &parser::ApiGroup, method: &parser::ApiMethod) -> MethodsAndExtra {
let method_name = util::to_ident(&method.name.to_snake()); let method_name = util::to_ident(&method.name.to_snake());
let url = format!("/api/v2/{}/{}", group.url, method.url); let url = format!("/api/v2/{}/{}", group.url, method.url);