Remove unused files

This commit is contained in:
Joel Wachsler 2022-07-23 00:27:30 +00:00
parent fb1327a140
commit d4b4661e02
5 changed files with 0 additions and 728 deletions

View File

@ -1,328 +0,0 @@
use std::rc::Rc;
use case::CaseExt;
use proc_macro2::TokenStream;
use quote::quote;
use crate::{
generate::util,
parser::{self, ApiMethod, ApiParameters},
types,
};
use super::{
return_type::create_return_type, send_method_builder::SendMethodBuilder, MethodsAndExtra,
};
pub fn create_method_with_params(
group: &parser::ApiGroup,
method: &parser::ApiMethod,
params: &parser::ApiParameters,
method_name: &proc_macro2::Ident,
url: &str,
) -> MethodsAndExtra {
let param_type = util::to_ident(&format!(
"{}{}Parameters",
group.name.to_camel(),
method.name.to_camel()
));
let parameters = Parameters::new(params);
let has_optional_parameters = !parameters.optional.is_empty();
let generator = MethodGenerator {
group,
url,
parameters,
param_type,
method,
method_name,
};
if has_optional_parameters {
generator.generate_method_with_builder()
} else {
generator.generate_method_without_builder()
}
}
#[derive(Debug)]
struct MethodGenerator<'a> {
group: &'a parser::ApiGroup,
url: &'a str,
parameters: Parameters<'a>,
param_type: proc_macro2::Ident,
method: &'a ApiMethod,
method_name: &'a proc_macro2::Ident,
}
impl<'a> MethodGenerator<'a> {
fn generate_method_without_builder(&self) -> MethodsAndExtra {
let form_builder = self.parameters.mandatory.form_builder();
let form_attributes =
quote! { .multipart(reqwest::multipart::Form::new()#(#form_builder)*) };
let builder = SendMethodBuilder::new(self.method_name, self.url, quote! { self.auth })
.description(&self.method.description)
.with_args(&self.parameters.mandatory.generate_params())
.with_extra_form_args(&[form_attributes]);
match create_return_type(self.group, self.method) {
Some((return_type_name, return_type)) => {
MethodsAndExtra::new(builder.return_type(&return_type_name).build())
.with_structs(return_type)
}
None => MethodsAndExtra::new(builder.build()),
}
}
fn generate_method_with_builder(&self) -> MethodsAndExtra {
let group_name = self.group_name();
let send_builder = self.send_builder(&util::to_ident("send"));
let send_impl_generator =
SendImplGenerator::new(&group_name, &self.parameters, &self.param_type);
let send = match create_return_type(self.group, self.method) {
Some((return_type_name, return_type)) => {
let send_impl =
send_impl_generator.generate(send_builder.return_type(&return_type_name));
quote! {
#send_impl
#return_type
}
}
None => send_impl_generator.generate(send_builder),
};
let builder = generate_builder(
&self.parameters,
self.method,
self.method_name,
&self.param_type,
);
let param_type = &self.param_type;
let group_impl = quote! {
pub struct #param_type<'a> {
group: &'a #group_name<'a>,
form: reqwest::multipart::Form,
}
#send
};
MethodsAndExtra::new(builder).with_structs(group_impl)
}
fn group_name(&self) -> proc_macro2::Ident {
util::to_ident(&self.group.name.to_camel())
}
fn send_builder(&self, name: &proc_macro2::Ident) -> SendMethodBuilder {
SendMethodBuilder::new(name, self.url, quote! { self.group.auth }).with_form()
}
}
fn generate_builder(
parameters: &Parameters,
method: &ApiMethod,
method_name: &proc_macro2::Ident,
param_type: &proc_macro2::Ident,
) -> proc_macro2::TokenStream {
let mandatory_param_names = parameters.mandatory.names();
let mandatory_param_args = parameters.mandatory.generate_params();
util::add_docs(
&method.description,
quote! {
pub fn #method_name(&self, #(#mandatory_param_args),*) -> #param_type {
#param_type::new(self, #(#mandatory_param_names),*)
}
},
)
}
#[derive(Debug)]
struct SendImplGenerator<'a> {
group_name: &'a proc_macro2::Ident,
parameters: &'a Parameters<'a>,
param_type: &'a proc_macro2::Ident,
}
impl<'a> SendImplGenerator<'a> {
fn new(
group_name: &'a proc_macro2::Ident,
parameters: &'a Parameters<'a>,
param_type: &'a proc_macro2::Ident,
) -> Self {
Self {
group_name,
parameters,
param_type,
}
}
fn generate(&self, send_method_builder: SendMethodBuilder) -> TokenStream {
let parameters = self.parameters;
let optional_builder_methods = parameters.optional.generate_builder_methods();
let mandatory_param_form_build = parameters.mandatory.form_builder();
let mandatory_param_args = parameters.mandatory.generate_params();
let param_type = self.param_type;
let group_name = self.group_name;
let send_method = send_method_builder.build();
quote! {
impl<'a> #param_type<'a> {
fn new(group: &'a #group_name, #(#mandatory_param_args),*) -> Self {
let form = reqwest::multipart::Form::new()#(#mandatory_param_form_build)*;
Self { group, form }
}
#(#optional_builder_methods)*
#send_method
}
}
}
}
#[derive(Debug)]
struct Parameters<'a> {
mandatory: MandatoryParams<'a>,
optional: OptionalParams<'a>,
}
impl<'a> Parameters<'a> {
fn new(api_parameters: &'a ApiParameters) -> Self {
let rc_params = Rc::new(api_parameters);
let mandatory = MandatoryParams::new(&rc_params);
let optional = OptionalParams::new(&rc_params);
Self {
mandatory,
optional,
}
}
}
#[derive(Debug)]
struct MandatoryParams<'a> {
params: Vec<Parameter<'a>>,
}
impl<'a> MandatoryParams<'a> {
fn new(params: &'a ApiParameters) -> Self {
Self {
params: Parameter::from(&params.mandatory),
}
}
fn generate_params(&self) -> Vec<TokenStream> {
self.params
.iter()
.map(|p| p.generate_param_with_name())
.collect()
}
fn form_builder(&self) -> Vec<TokenStream> {
self.params
.iter()
.map(|param| {
let name_ident = param.name_ident();
let name = param.name();
quote! { .text(#name, #name_ident.to_string()) }
})
.collect()
}
fn names(&self) -> Vec<TokenStream> {
self.params
.iter()
.map(|p| p.name_ident())
.map(|name_ident| quote! { #name_ident })
.collect()
}
}
#[derive(Debug)]
struct OptionalParams<'a> {
params: Vec<Parameter<'a>>,
}
impl<'a> OptionalParams<'a> {
fn new(params: &'a ApiParameters) -> Self {
Self {
params: Parameter::from(&params.optional),
}
}
fn is_empty(&self) -> bool {
self.params.is_empty()
}
fn generate_builder_methods(&self) -> Vec<TokenStream> {
self.params
.iter()
.map(Self::generate_builder_method)
.collect()
}
fn generate_builder_method(param: &Parameter) -> TokenStream {
let name = param.name();
let name_ident = param.name_ident();
let param_type = util::to_ident(&param.p_type.to_borrowed_type());
let builder_param = if param.p_type.should_borrow() {
quote! { &#param_type }
} else {
quote! { #param_type }
};
util::add_docs(
&param.p_type.get_type_info().description,
quote! {
pub fn #name_ident(mut self, value: #builder_param) -> Self {
self.form = self.form.text(#name, value.to_string());
self
}
},
)
}
}
#[derive(Debug)]
struct Parameter<'a> {
p_type: &'a types::Type,
}
impl<'a> Parameter<'a> {
fn new(p_type: &'a types::Type) -> Self {
Self { p_type }
}
fn from(parameters: &[types::Type]) -> Vec<Parameter<'_>> {
parameters.iter().map(Parameter::new).collect()
}
fn name(&self) -> String {
self.p_type.get_type_info().name.to_snake()
}
fn name_ident(&self) -> proc_macro2::Ident {
util::to_ident(&self.name())
}
fn generate_param_with_name(&self) -> TokenStream {
let t = util::to_ident(&self.p_type.to_borrowed_type());
let name_ident = self.name_ident();
let t = if self.p_type.should_borrow() {
quote! { &#t }
} else {
quote! { #t }
};
quote! { #name_ident: #t }
}
}

View File

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

View File

@ -1,72 +0,0 @@
mod method_with_params;
mod method_without_params;
mod return_type;
mod send_method_builder;
use crate::{generate::util, parser};
use case::CaseExt;
use quote::quote;
use self::{
method_with_params::create_method_with_params,
method_without_params::create_method_without_params,
};
pub fn generate_methods(
group: &parser::ApiGroup,
auth: &syn::Ident,
group_name_camel: &syn::Ident,
) -> proc_macro2::TokenStream {
let methods_and_extra = group
.methods
.iter()
.map(|method| generate_method(group, method));
let methods = methods_and_extra
.clone()
.map(|MethodsAndExtra { methods, .. }| methods);
let extra = methods_and_extra.flat_map(|MethodsAndExtra { extra: structs, .. }| structs);
quote! {
impl <'a> #group_name_camel<'a> {
pub fn new(auth: &'a #auth) -> Self {
Self { auth }
}
#(#methods)*
}
#(#extra)*
}
}
#[derive(Debug)]
pub struct MethodsAndExtra {
methods: 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 url = format!("/api/v2/{}/{}", group.url, method.url);
match &method.parameters {
Some(params) => create_method_with_params(group, method, params, &method_name, &url),
None => create_method_without_params(group, method, method_name, &url),
}
}

View File

@ -1,203 +0,0 @@
use std::collections::HashMap;
use case::CaseExt;
use quote::{format_ident, quote};
use regex::Regex;
use crate::{generate::util, parser, types};
pub fn create_return_type(
group: &parser::ApiGroup,
method: &parser::ApiMethod,
) -> Option<(proc_macro2::TokenStream, proc_macro2::TokenStream)> {
let return_type = match &method.return_type {
Some(t) => t,
None => return None,
};
let to_enum_name = |name: &str| to_enum_name(&group.name, &method.name, name);
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
.iter()
.map(|(enum_name, _)| (enum_name.clone(), to_enum_name(enum_name)))
.collect();
let enum_types = enum_types_with_names.iter().map(|(_, enum_type)| enum_type);
let builder_fields = return_type
.parameters
.iter()
.map(|parameter| generate_builder_field(parameter, &enum_names));
let return_type_name = util::to_ident(&format!(
"{}{}Result",
&group.name.to_camel(),
&method.name.to_camel()
));
let result_type = if return_type.is_list {
quote! { std::vec::Vec<#return_type_name> }
} else {
quote! { #return_type_name }
};
Some((
result_type,
quote! {
#[derive(Debug, Deserialize)]
pub struct #return_type_name {
#(#builder_fields,)*
}
#(#enum_types)*
},
))
}
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 &parameter.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 name_string = &parameter.name;
let name = util::to_ident(&name_string.to_snake().replace("__", "_"));
let enum_name = match enum_names.get(name_string) {
Some(enum_type) => enum_type.to_owned(),
None => parameter.return_type.to_owned_type(),
};
let return_type = util::to_ident(&enum_name);
let return_type_as_quote = if parameter.return_type.is_list() {
quote! { std::vec::Vec<#return_type> }
} else {
quote! { #return_type }
};
let generate_field = |field_name| {
quote! {
#[serde(rename = #name_string)]
pub #field_name: #return_type_as_quote
}
};
// "type" is a reserved keyword in Rust, so we just add "t_" to it.
if name_string == "type" {
generate_field(format_ident!("t_{}", name))
} else {
generate_field(name)
}
}
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 {
let value = &type_description.value;
let value_as_ident = util::to_ident(&value.to_camel());
create_enum_field(&value_as_ident, value, &type_description.description)
}
fn create_number_enum_value(value: &types::TypeDescriptions) -> proc_macro2::TokenStream {
let v = &value.value;
let re = Regex::new(r#"\(.*\)"#).unwrap();
let desc = &value
.description
.replace(' ', "_")
.replace('-', "_")
.replace(',', "_");
let desc_without_parentheses = re.replace_all(desc, "");
let ident = util::to_ident(&desc_without_parentheses.to_camel());
create_enum_field(&ident, v, &value.description)
}
fn create_enum_field(
ident: &syn::Ident,
rename: &str,
description: &str,
) -> proc_macro2::TokenStream {
util::add_docs(
&Some(description.to_string()),
quote! {
#[serde(rename = #rename)]
#ident
},
)
}
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()
)
}

View File

@ -1,98 +0,0 @@
use quote::quote;
use crate::generate::util;
pub struct SendMethodBuilder {
method_name: syn::Ident,
url: String,
auth_module_path: proc_macro2::TokenStream,
return_type: Option<proc_macro2::TokenStream>,
description: Option<String>,
args: Vec<proc_macro2::TokenStream>,
extra_form_args: Vec<proc_macro2::TokenStream>,
form: bool,
}
impl SendMethodBuilder {
pub fn new(
method_name: &syn::Ident,
url: &str,
auth_module_path: proc_macro2::TokenStream,
) -> Self {
Self {
method_name: method_name.clone(),
url: url.to_string(),
auth_module_path,
return_type: None,
description: None,
form: false,
args: vec![],
extra_form_args: vec![],
}
}
pub fn return_type(mut self, value: &proc_macro2::TokenStream) -> Self {
self.return_type = Some(value.clone());
self
}
pub fn description(mut self, value: &Option<String>) -> Self {
self.description = value.clone();
self
}
pub fn with_form(mut self) -> Self {
self.form = true;
self
}
pub fn with_args(mut self, value: &[proc_macro2::TokenStream]) -> Self {
self.args = value.to_vec();
self
}
pub fn with_extra_form_args(mut self, value: &[proc_macro2::TokenStream]) -> Self {
self.extra_form_args = value.to_vec();
self
}
pub fn build(&self) -> proc_macro2::TokenStream {
let method_name = &self.method_name;
let (return_type, parse_type) = match &self.return_type {
Some(t) => (t.clone(), quote! { .json::<#t>() }),
None => (quote! { String }, quote! { .text() }),
};
let url = &self.url;
let auth_module_path = &self.auth_module_path;
let form = if self.form {
quote! { .multipart(self.form) }
} else {
quote! {}
};
let arg_list = &self.args;
let args = if !arg_list.is_empty() {
quote! { , #(#arg_list),* }
} else {
quote! {}
};
let extra_form_args = &self.extra_form_args;
util::add_docs(
&self.description,
quote! {
pub async fn #method_name(self #args) -> Result<#return_type> {
let res = #auth_module_path
.authenticated_client(#url)
#form
#(#extra_form_args)*
.send()
.await?
#parse_type
.await?;
Ok(res)
}
},
)
}
}