From aaf315320526578a79ed2946e05bc8c929c151f1 Mon Sep 17 00:00:00 2001 From: Joel Wachsler Date: Tue, 12 Jul 2022 11:35:11 +0000 Subject: [PATCH] Group by function --- qbittorrent-web-api-gen/src/generate/mod.rs | 5 +- .../src/parser/api_group.rs | 32 ------------ .../src/parser/group/description.rs | 17 +++++++ .../parser/{ => group/method}/description.rs | 16 ------ .../{api_method.rs => group/method/mod.rs} | 30 ++++++++--- .../parser/{ => group/method}/return_type.rs | 8 ++- .../src/parser/group/method/url.rs | 9 ++++ .../src/parser/group/mod.rs | 40 +++++++++++++++ .../src/parser/group/url.rs | 14 +++++ qbittorrent-web-api-gen/src/parser/mod.rs | 51 +++++-------------- .../src/parser/url_parser.rs | 22 -------- qbittorrent-web-api-gen/src/parser/util.rs | 16 +----- 12 files changed, 130 insertions(+), 130 deletions(-) delete mode 100644 qbittorrent-web-api-gen/src/parser/api_group.rs create mode 100644 qbittorrent-web-api-gen/src/parser/group/description.rs rename qbittorrent-web-api-gen/src/parser/{ => group/method}/description.rs (73%) rename qbittorrent-web-api-gen/src/parser/{api_method.rs => group/method/mod.rs} (53%) rename qbittorrent-web-api-gen/src/parser/{ => group/method}/return_type.rs (92%) create mode 100644 qbittorrent-web-api-gen/src/parser/group/method/url.rs create mode 100644 qbittorrent-web-api-gen/src/parser/group/mod.rs create mode 100644 qbittorrent-web-api-gen/src/parser/group/url.rs delete mode 100644 qbittorrent-web-api-gen/src/parser/url_parser.rs diff --git a/qbittorrent-web-api-gen/src/generate/mod.rs b/qbittorrent-web-api-gen/src/generate/mod.rs index 6ef8cad..2a29a99 100644 --- a/qbittorrent-web-api-gen/src/generate/mod.rs +++ b/qbittorrent-web-api-gen/src/generate/mod.rs @@ -7,14 +7,15 @@ use proc_macro2::TokenStream; use quote::{format_ident, quote}; use regex::Regex; -use crate::{parser, types, util}; +use crate::{md_parser, 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 token_tree = md_parser::TokenTreeFactory::create(api_content); + let api_groups = parser::parse_api_groups(token_tree); let skeleton = generate_skeleton(ident); let groups = generate_groups(api_groups); diff --git a/qbittorrent-web-api-gen/src/parser/api_group.rs b/qbittorrent-web-api-gen/src/parser/api_group.rs deleted file mode 100644 index cdb605f..0000000 --- a/qbittorrent-web-api-gen/src/parser/api_group.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::md_parser; - -use super::{ - api_method::parse_api_method, description::parse_group_description, url_parser::get_group_url, - ApiGroup, -}; - -pub fn parse_api_group(tree: md_parser::TokenTree) -> ApiGroup { - let methods = tree - .children - .into_iter() - .flat_map(parse_api_method) - .collect(); - - let group_description = parse_group_description(&tree.content); - let group_url = get_group_url(&tree.content); - - let name = tree - .title - .unwrap() - .to_lowercase() - .trim_end_matches("(experimental)") - .trim() - .replace(' ', "_"); - - ApiGroup { - name, - methods, - description: group_description, - url: group_url, - } -} diff --git a/qbittorrent-web-api-gen/src/parser/group/description.rs b/qbittorrent-web-api-gen/src/parser/group/description.rs new file mode 100644 index 0000000..c47d531 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/description.rs @@ -0,0 +1,17 @@ +use crate::md_parser; + +pub fn parse_group_description(content: &[md_parser::MdContent]) -> Option { + let return_desc = content + .iter() + .map(|row| row.inner_value_as_string()) + .collect::>() + .join("\n") + .trim() + .to_string(); + + if return_desc.is_empty() { + None + } else { + Some(return_desc) + } +} diff --git a/qbittorrent-web-api-gen/src/parser/description.rs b/qbittorrent-web-api-gen/src/parser/group/method/description.rs similarity index 73% rename from qbittorrent-web-api-gen/src/parser/description.rs rename to qbittorrent-web-api-gen/src/parser/group/method/description.rs index 52577ed..73f3fce 100644 --- a/qbittorrent-web-api-gen/src/parser/description.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/description.rs @@ -1,21 +1,5 @@ use crate::md_parser::MdContent; -pub fn parse_group_description(content: &[MdContent]) -> Option { - let return_desc = content - .iter() - .map(|row| row.inner_value_as_string()) - .collect::>() - .join("\n") - .trim() - .to_string(); - - if return_desc.is_empty() { - None - } else { - Some(return_desc) - } -} - pub fn parse_method_description(content: &[MdContent]) -> Option { let return_desc = content .iter() diff --git a/qbittorrent-web-api-gen/src/parser/api_method.rs b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs similarity index 53% rename from qbittorrent-web-api-gen/src/parser/api_method.rs rename to qbittorrent-web-api-gen/src/parser/group/method/mod.rs index e58dd9c..22e3584 100644 --- a/qbittorrent-web-api-gen/src/parser/api_method.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs @@ -1,18 +1,36 @@ -use crate::md_parser; +mod description; +mod return_type; +mod url; -use super::{ - description::parse_method_description, parameters::parse_parameters, - return_type::parse_return_type, url_parser::get_method_url, util, ApiMethod, +use crate::{ + md_parser, + parser::{parameters::parse_parameters, util}, + types, }; -pub fn parse_api_method(child: md_parser::TokenTree) -> Option { +use self::{ + description::parse_method_description, + return_type::{parse_return_type, ReturnType}, + url::get_method_url, +}; + +#[derive(Debug)] +pub struct ApiMethod { + pub name: String, + pub description: Option, + pub parameters: Option>, + pub return_type: Option, + pub url: String, +} + +pub fn parse_api_method(child: &md_parser::TokenTree) -> Option { util::find_content_starts_with(&child.content, "Name: ") .map(|name| { name.trim_start_matches("Name: ") .trim_matches('`') .to_string() }) - .map(|name| to_api_method(&child, &name)) + .map(|name| to_api_method(child, &name)) } fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod { diff --git a/qbittorrent-web-api-gen/src/parser/return_type.rs b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs similarity index 92% rename from qbittorrent-web-api-gen/src/parser/return_type.rs rename to qbittorrent-web-api-gen/src/parser/group/method/return_type.rs index ab7d491..293f1fa 100644 --- a/qbittorrent-web-api-gen/src/parser/return_type.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs @@ -1,8 +1,14 @@ use crate::{ md_parser::MdContent, - parser::{object_types::parse_object_types, types, ReturnType, ReturnTypeParameter}, + parser::{object_types::parse_object_types, types, ReturnTypeParameter}, }; +#[derive(Debug)] +pub struct ReturnType { + pub is_list: bool, + pub parameters: Vec, +} + pub fn parse_return_type(content: &[MdContent]) -> Option { let table = content .iter() diff --git a/qbittorrent-web-api-gen/src/parser/group/method/url.rs b/qbittorrent-web-api-gen/src/parser/group/method/url.rs new file mode 100644 index 0000000..5358362 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/url.rs @@ -0,0 +1,9 @@ +use crate::{md_parser, parser::util}; + +pub fn get_method_url(content: &[md_parser::MdContent]) -> String { + const START: &str = "Name: "; + + util::find_content_starts_with(content, START) + .map(|text| text.trim_start_matches(START).trim_matches('`').to_string()) + .expect("Could find method url") +} diff --git a/qbittorrent-web-api-gen/src/parser/group/mod.rs b/qbittorrent-web-api-gen/src/parser/group/mod.rs new file mode 100644 index 0000000..9debf71 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/mod.rs @@ -0,0 +1,40 @@ +mod description; +mod method; +mod url; + +use crate::md_parser; + +use self::{description::parse_group_description, method::parse_api_method, url::get_group_url}; + +#[derive(Debug)] +pub struct ApiGroup { + pub name: String, + pub methods: Vec, + pub description: Option, + pub url: String, +} + +pub use method::ApiMethod; + +pub fn parse_api_group(tree: &md_parser::TokenTree) -> ApiGroup { + let methods = tree.children.iter().flat_map(parse_api_method).collect(); + + let group_description = parse_group_description(&tree.content); + let group_url = get_group_url(&tree.content); + + let name = tree + .title + .clone() + .unwrap() + .to_lowercase() + .trim_end_matches("(experimental)") + .trim() + .replace(' ', "_"); + + ApiGroup { + name, + methods, + description: group_description, + url: group_url, + } +} diff --git a/qbittorrent-web-api-gen/src/parser/group/url.rs b/qbittorrent-web-api-gen/src/parser/group/url.rs new file mode 100644 index 0000000..993c9b8 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/url.rs @@ -0,0 +1,14 @@ +use regex::Regex; + +use crate::{md_parser, parser::util}; + +pub fn get_group_url(content: &[md_parser::MdContent]) -> String { + let row = util::find_content_contains(content, "API methods are under") + .expect("Could not find api method"); + + let re = Regex::new(r#"All (?:\w+\s?)+ API methods are under "(\w+)", e.g."#) + .expect("Failed to create regex"); + + let res = re.captures(&row).expect("Failed find capture"); + res[1].to_string() +} diff --git a/qbittorrent-web-api-gen/src/parser/mod.rs b/qbittorrent-web-api-gen/src/parser/mod.rs index c198ff6..a386430 100644 --- a/qbittorrent-web-api-gen/src/parser/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/mod.rs @@ -1,39 +1,12 @@ use crate::{md_parser, types}; -use self::api_group::parse_api_group; +use self::group::parse_api_group; -mod api_group; -mod api_method; -mod description; +mod group; mod object_types; mod parameters; -mod return_type; -mod url_parser; mod util; -#[derive(Debug)] -pub struct ApiGroup { - pub name: String, - pub methods: Vec, - pub description: Option, - pub url: String, -} - -#[derive(Debug)] -pub struct ApiMethod { - pub name: String, - pub description: Option, - pub parameters: Option>, - pub return_type: Option, - pub url: String, -} - -#[derive(Debug)] -pub struct ReturnType { - pub is_list: bool, - pub parameters: Vec, -} - #[derive(Debug)] pub struct ReturnTypeParameter { pub name: String, @@ -41,10 +14,18 @@ pub struct ReturnTypeParameter { pub return_type: types::Type, } -pub fn parse_api_groups(content: &str) -> Vec { - parse_groups(extract_relevant_parts(md_parser::TokenTreeFactory::create( - content, - ))) +pub use group::ApiGroup; +pub use group::ApiMethod; + +pub fn parse_api_groups(token_tree: md_parser::TokenTree) -> Vec { + parse_groups(extract_relevant_parts(token_tree)) +} + +pub fn parse_groups(trees: Vec) -> Vec { + trees + .into_iter() + .map(|tree| parse_api_group(&tree)) + .collect() } fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec { @@ -64,10 +45,6 @@ fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec) -> Vec { - trees.into_iter().map(parse_api_group).collect() -} - #[cfg(test)] mod tests { use super::*; diff --git a/qbittorrent-web-api-gen/src/parser/url_parser.rs b/qbittorrent-web-api-gen/src/parser/url_parser.rs deleted file mode 100644 index 43a5ac7..0000000 --- a/qbittorrent-web-api-gen/src/parser/url_parser.rs +++ /dev/null @@ -1,22 +0,0 @@ -use regex::Regex; - -use crate::{md_parser::MdContent, parser::util}; - -pub fn get_group_url(content: &[MdContent]) -> String { - let row = util::find_content_contains(content, "API methods are under") - .expect("Could not find api method"); - - let re = Regex::new(r#"All (?:\w+\s?)+ API methods are under "(\w+)", e.g."#) - .expect("Failed to create regex"); - - let res = re.captures(&row).expect("Failed find capture"); - res[1].to_string() -} - -pub fn get_method_url(content: &[MdContent]) -> String { - const START: &str = "Name: "; - - util::find_content_starts_with(content, START) - .map(|text| text.trim_start_matches(START).trim_matches('`').to_string()) - .expect("Could find method url") -} diff --git a/qbittorrent-web-api-gen/src/parser/util.rs b/qbittorrent-web-api-gen/src/parser/util.rs index 8cd9b9d..71e9160 100644 --- a/qbittorrent-web-api-gen/src/parser/util.rs +++ b/qbittorrent-web-api-gen/src/parser/util.rs @@ -2,26 +2,14 @@ use crate::md_parser::MdContent; pub fn find_content_starts_with(content: &[MdContent], starts_with: &str) -> Option { content.iter().find_map(|row| match row { - MdContent::Text(content) => { - if content.starts_with(starts_with) { - Some(content.into()) - } else { - None - } - } + MdContent::Text(content) if content.starts_with(starts_with) => Some(content.into()), _ => None, }) } pub fn find_content_contains(content: &[MdContent], contains: &str) -> Option { content.iter().find_map(|row| match row { - MdContent::Text(content) => { - if content.contains(contains) { - Some(content.into()) - } else { - None - } - } + MdContent::Text(content) if content.contains(contains) => Some(content.into()), _ => None, }) }