This commit is contained in:
Joel Wachsler 2022-07-12 10:28:03 +00:00
parent 3559ac6c27
commit f0124d7620
8 changed files with 44 additions and 47 deletions

View File

@ -1,14 +1,32 @@
mod skeleton;
use std::{collections::HashMap, vec::Vec};
use case::CaseExt;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use regex::Regex;
use crate::{
parser::{self, types::TypeInfo},
skeleton::auth_ident,
util,
};
use crate::{parser, types, util};
use self::skeleton::{auth_ident, generate_skeleton};
pub fn generate(ast: &syn::DeriveInput, api_content: &str) -> TokenStream {
let ident = &ast.ident;
let api_groups = parser::parse_api_groups(api_content);
let skeleton = generate_skeleton(ident);
let groups = generate_groups(api_groups);
let impl_ident = syn::Ident::new(&format!("{}_impl", ident).to_snake(), ident.span());
quote! {
pub mod #impl_ident {
#skeleton
#groups
}
}
}
pub fn generate_groups(groups: Vec<parser::ApiGroup>) -> proc_macro2::TokenStream {
let gr = groups
@ -138,7 +156,7 @@ fn create_method_without_params(
fn create_method_with_params(
group: &parser::ApiGroup,
method: &parser::ApiMethod,
params: &[parser::types::Type],
params: &[types::Type],
method_name: &proc_macro2::Ident,
url: &str,
) -> (proc_macro2::TokenStream, Option<proc_macro2::TokenStream>) {
@ -314,7 +332,7 @@ fn create_return_type(
.parameters
.iter()
.flat_map(|parameter| match &parameter.return_type {
parser::types::Type::Number(TypeInfo {
types::Type::Number(types::TypeInfo {
ref name,
type_description: Some(type_description),
..
@ -352,7 +370,7 @@ fn create_return_type(
},
))
}
parser::types::Type::String(TypeInfo {
types::Type::String(types::TypeInfo {
ref name,
type_description: Some(type_description),
..

View File

@ -1,35 +1,16 @@
mod group;
mod generate;
mod md_parser;
mod parser;
mod skeleton;
mod util;
mod types;
use case::CaseExt;
use proc_macro::TokenStream;
use quote::quote;
use skeleton::generate_skeleton;
use syn::parse_macro_input;
use crate::group::generate_groups;
const API_CONTENT: &str = include_str!("../api-4_1.md");
#[proc_macro_derive(QBittorrentApiGen, attributes(api_gen))]
pub fn derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as syn::DeriveInput);
let ident = &ast.ident;
let api_groups = parser::parse_api_groups(API_CONTENT);
let skeleton = generate_skeleton(ident);
let groups = generate_groups(api_groups);
let impl_ident = syn::Ident::new(&format!("{}_impl", ident).to_snake(), ident.span());
quote! {
pub mod #impl_ident {
#skeleton
#groups
}
}
.into()
generate::generate(&ast, API_CONTENT).into()
}

View File

@ -1,11 +1,8 @@
use std::collections::HashMap;
use crate::{
md_parser::MdContent,
parser::types::{Type, OPTIONAL},
};
use crate::{md_parser::MdContent, parser::types};
pub fn get_parameters(content: &[MdContent]) -> Option<Vec<Type>> {
pub fn get_parameters(content: &[MdContent]) -> Option<Vec<types::Type>> {
let mut it = content
.iter()
.skip_while(|row| match row {
@ -37,10 +34,10 @@ pub fn get_parameters(content: &[MdContent]) -> Option<Vec<Type>> {
// If the description contains a default value it means that the parameter is optional.
Some(desc) if desc.contains("default: ") => {
// type defines a variable as default if it contains: _optional_
let name_with_optional = format!("{} {}", row.columns[0], OPTIONAL);
Type::from(&row.columns[1], &name_with_optional, description, &type_map)
let name_with_optional = format!("{} {}", row.columns[0], types::OPTIONAL);
types::Type::from(&row.columns[1], &name_with_optional, description, &type_map)
}
_ => Type::from(&row.columns[1], &row.columns[0], description, &type_map),
_ => types::Type::from(&row.columns[1], &row.columns[0], description, &type_map),
}
})
.collect();

View File

@ -1,6 +1,6 @@
use crate::{
md_parser::MdContent,
parser::{object_types::get_object_types, types::Type, ReturnType, ReturnTypeParameter},
parser::{object_types::get_object_types, types, ReturnType, ReturnTypeParameter},
};
pub fn get_return_type(content: &[MdContent]) -> Option<ReturnType> {
@ -26,7 +26,7 @@ pub fn get_return_type(content: &[MdContent]) -> Option<ReturnType> {
.map(|parameter| ReturnTypeParameter {
name: parameter.columns[0].clone(),
description: parameter.columns[2].clone(),
return_type: Type::from(
return_type: types::Type::from(
&parameter.columns[1],
&parameter.columns[0],
Some(parameter.columns[2].clone()),

View File

@ -1,12 +1,13 @@
mod group_parser;
mod object_types;
pub mod types;
mod util;
use group_parser::parse_groups;
use types::Type;
use crate::md_parser::{self, TokenTree};
use crate::{
md_parser::{self, TokenTree},
types,
};
#[derive(Debug)]
pub struct ApiGroup {
@ -20,7 +21,7 @@ pub struct ApiGroup {
pub struct ApiMethod {
pub name: String,
pub description: Option<String>,
pub parameters: Option<Vec<Type>>,
pub parameters: Option<Vec<types::Type>>,
pub return_type: Option<ReturnType>,
pub url: String,
}
@ -35,7 +36,7 @@ pub struct ReturnType {
pub struct ReturnTypeParameter {
pub name: String,
pub description: String,
pub return_type: Type,
pub return_type: types::Type,
}
fn extract_relevant_parts(tree: TokenTree) -> Vec<TokenTree> {

View File

@ -1,6 +1,6 @@
use std::collections::HashMap;
use crate::{md_parser::MdContent, parser::types::TypeDescriptions};
use crate::{md_parser::MdContent, parser::types};
use super::types::TypeDescription;
@ -17,7 +17,7 @@ pub fn get_object_types(content: &[MdContent]) -> HashMap<String, TypeDescriptio
let enum_types = table
.rows
.iter()
.map(|row| TypeDescriptions {
.map(|row| types::TypeDescriptions {
value: row.columns[0].to_string(),
description: row.columns[1].to_string(),
})