Refactor
This commit is contained in:
parent
3559ac6c27
commit
f0124d7620
|
@ -1,14 +1,32 @@
|
||||||
|
mod skeleton;
|
||||||
|
|
||||||
use std::{collections::HashMap, vec::Vec};
|
use std::{collections::HashMap, vec::Vec};
|
||||||
|
|
||||||
use case::CaseExt;
|
use case::CaseExt;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{parser, types, util};
|
||||||
parser::{self, types::TypeInfo},
|
|
||||||
skeleton::auth_ident,
|
use self::skeleton::{auth_ident, generate_skeleton};
|
||||||
util,
|
|
||||||
};
|
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 {
|
pub fn generate_groups(groups: Vec<parser::ApiGroup>) -> proc_macro2::TokenStream {
|
||||||
let gr = groups
|
let gr = groups
|
||||||
|
@ -138,7 +156,7 @@ fn create_method_without_params(
|
||||||
fn create_method_with_params(
|
fn create_method_with_params(
|
||||||
group: &parser::ApiGroup,
|
group: &parser::ApiGroup,
|
||||||
method: &parser::ApiMethod,
|
method: &parser::ApiMethod,
|
||||||
params: &[parser::types::Type],
|
params: &[types::Type],
|
||||||
method_name: &proc_macro2::Ident,
|
method_name: &proc_macro2::Ident,
|
||||||
url: &str,
|
url: &str,
|
||||||
) -> (proc_macro2::TokenStream, Option<proc_macro2::TokenStream>) {
|
) -> (proc_macro2::TokenStream, Option<proc_macro2::TokenStream>) {
|
||||||
|
@ -314,7 +332,7 @@ fn create_return_type(
|
||||||
.parameters
|
.parameters
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|parameter| match ¶meter.return_type {
|
.flat_map(|parameter| match ¶meter.return_type {
|
||||||
parser::types::Type::Number(TypeInfo {
|
types::Type::Number(types::TypeInfo {
|
||||||
ref name,
|
ref name,
|
||||||
type_description: Some(type_description),
|
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,
|
ref name,
|
||||||
type_description: Some(type_description),
|
type_description: Some(type_description),
|
||||||
..
|
..
|
|
@ -1,35 +1,16 @@
|
||||||
mod group;
|
mod generate;
|
||||||
mod md_parser;
|
mod md_parser;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod skeleton;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
mod types;
|
||||||
|
|
||||||
use case::CaseExt;
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::quote;
|
|
||||||
use skeleton::generate_skeleton;
|
|
||||||
use syn::parse_macro_input;
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
use crate::group::generate_groups;
|
|
||||||
|
|
||||||
const API_CONTENT: &str = include_str!("../api-4_1.md");
|
const API_CONTENT: &str = include_str!("../api-4_1.md");
|
||||||
|
|
||||||
#[proc_macro_derive(QBittorrentApiGen, attributes(api_gen))]
|
#[proc_macro_derive(QBittorrentApiGen, attributes(api_gen))]
|
||||||
pub fn derive(input: TokenStream) -> TokenStream {
|
pub fn derive(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as syn::DeriveInput);
|
let ast = parse_macro_input!(input as syn::DeriveInput);
|
||||||
let ident = &ast.ident;
|
generate::generate(&ast, API_CONTENT).into()
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{
|
use crate::{md_parser::MdContent, parser::types};
|
||||||
md_parser::MdContent,
|
|
||||||
parser::types::{Type, OPTIONAL},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn get_parameters(content: &[MdContent]) -> Option<Vec<Type>> {
|
pub fn get_parameters(content: &[MdContent]) -> Option<Vec<types::Type>> {
|
||||||
let mut it = content
|
let mut it = content
|
||||||
.iter()
|
.iter()
|
||||||
.skip_while(|row| match row {
|
.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.
|
// If the description contains a default value it means that the parameter is optional.
|
||||||
Some(desc) if desc.contains("default: ") => {
|
Some(desc) if desc.contains("default: ") => {
|
||||||
// type defines a variable as default if it contains: _optional_
|
// type defines a variable as default if it contains: _optional_
|
||||||
let name_with_optional = format!("{} {}", row.columns[0], OPTIONAL);
|
let name_with_optional = format!("{} {}", row.columns[0], types::OPTIONAL);
|
||||||
Type::from(&row.columns[1], &name_with_optional, description, &type_map)
|
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();
|
.collect();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
md_parser::MdContent,
|
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> {
|
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 {
|
.map(|parameter| ReturnTypeParameter {
|
||||||
name: parameter.columns[0].clone(),
|
name: parameter.columns[0].clone(),
|
||||||
description: parameter.columns[2].clone(),
|
description: parameter.columns[2].clone(),
|
||||||
return_type: Type::from(
|
return_type: types::Type::from(
|
||||||
¶meter.columns[1],
|
¶meter.columns[1],
|
||||||
¶meter.columns[0],
|
¶meter.columns[0],
|
||||||
Some(parameter.columns[2].clone()),
|
Some(parameter.columns[2].clone()),
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
mod group_parser;
|
mod group_parser;
|
||||||
mod object_types;
|
mod object_types;
|
||||||
pub mod types;
|
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
use group_parser::parse_groups;
|
use group_parser::parse_groups;
|
||||||
use types::Type;
|
|
||||||
|
|
||||||
use crate::md_parser::{self, TokenTree};
|
use crate::{
|
||||||
|
md_parser::{self, TokenTree},
|
||||||
|
types,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApiGroup {
|
pub struct ApiGroup {
|
||||||
|
@ -20,7 +21,7 @@ pub struct ApiGroup {
|
||||||
pub struct ApiMethod {
|
pub struct ApiMethod {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub parameters: Option<Vec<Type>>,
|
pub parameters: Option<Vec<types::Type>>,
|
||||||
pub return_type: Option<ReturnType>,
|
pub return_type: Option<ReturnType>,
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
@ -35,7 +36,7 @@ pub struct ReturnType {
|
||||||
pub struct ReturnTypeParameter {
|
pub struct ReturnTypeParameter {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub return_type: Type,
|
pub return_type: types::Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_relevant_parts(tree: TokenTree) -> Vec<TokenTree> {
|
fn extract_relevant_parts(tree: TokenTree) -> Vec<TokenTree> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{md_parser::MdContent, parser::types::TypeDescriptions};
|
use crate::{md_parser::MdContent, parser::types};
|
||||||
|
|
||||||
use super::types::TypeDescription;
|
use super::types::TypeDescription;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ pub fn get_object_types(content: &[MdContent]) -> HashMap<String, TypeDescriptio
|
||||||
let enum_types = table
|
let enum_types = table
|
||||||
.rows
|
.rows
|
||||||
.iter()
|
.iter()
|
||||||
.map(|row| TypeDescriptions {
|
.map(|row| types::TypeDescriptions {
|
||||||
value: row.columns[0].to_string(),
|
value: row.columns[0].to_string(),
|
||||||
description: row.columns[1].to_string(),
|
description: row.columns[1].to_string(),
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user