From 3360b2f3bd854ea03c48355e6a52beb015543fe9 Mon Sep 17 00:00:00 2001 From: Joel Wachsler Date: Tue, 12 Jul 2022 11:07:28 +0000 Subject: [PATCH] Refactor api parsing --- qbittorrent-web-api-gen/src/parser/mod.rs | 16 ++++---- .../src/parser/object_types.rs | 35 ++++++++++------- .../src/parser/parameters.rs | 39 +++++++++++-------- .../src/parser/return_type.rs | 4 +- 4 files changed, 52 insertions(+), 42 deletions(-) diff --git a/qbittorrent-web-api-gen/src/parser/mod.rs b/qbittorrent-web-api-gen/src/parser/mod.rs index ebca428..d1f9b2d 100644 --- a/qbittorrent-web-api-gen/src/parser/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/mod.rs @@ -1,6 +1,6 @@ use crate::{md_parser, types}; -use self::{parameters::get_parameters, return_type::get_return_type, url_parser::get_method_url}; +use self::{parameters::parse_parameters, return_type::get_return_type, url_parser::get_method_url}; mod description; mod object_types; @@ -39,6 +39,12 @@ 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, + ))) +} + fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec { let relevant: Vec = tree .children @@ -56,12 +62,6 @@ fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec Vec { - parse_groups(extract_relevant_parts(md_parser::TokenTreeFactory::create( - content, - ))) -} - pub fn parse_groups(trees: Vec) -> Vec { trees.into_iter().map(parse_api_group).collect() } @@ -105,7 +105,7 @@ fn parse_api_method(child: md_parser::TokenTree) -> Option { fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod { let method_description = description::get_method_description(&child.content); let return_type = get_return_type(&child.content); - let parameters = get_parameters(&child.content); + let parameters = parse_parameters(&child.content); let method_url = get_method_url(&child.content); ApiMethod { diff --git a/qbittorrent-web-api-gen/src/parser/object_types.rs b/qbittorrent-web-api-gen/src/parser/object_types.rs index 1c013ad..1dd6d72 100644 --- a/qbittorrent-web-api-gen/src/parser/object_types.rs +++ b/qbittorrent-web-api-gen/src/parser/object_types.rs @@ -1,34 +1,28 @@ use std::collections::HashMap; -use crate::{md_parser::MdContent, parser::types}; +use crate::{md_parser, parser::types}; -use super::types::TypeDescription; - -pub fn get_object_types(content: &[MdContent]) -> HashMap { +pub fn parse_object_types( + content: &[md_parser::MdContent], +) -> HashMap { let mut output = HashMap::new(); let mut content_it = content.iter(); + while let Some(entry) = content_it.next() { - if let MdContent::Text(content) = entry { + if let md_parser::MdContent::Text(content) = entry { const POSSIBLE_VALUES_OF: &str = "Possible values of "; if content.contains(POSSIBLE_VALUES_OF) { // is empty content_it.next(); - if let Some(MdContent::Table(table)) = content_it.next() { - let enum_types = table - .rows - .iter() - .map(|row| types::TypeDescriptions { - value: row.columns[0].to_string(), - description: row.columns[1].to_string(), - }) - .collect(); + if let Some(md_parser::MdContent::Table(table)) = content_it.next() { + let enum_types = to_type_descriptions(table); let name = content .trim_start_matches(POSSIBLE_VALUES_OF) .replace('`', "") .replace(':', ""); - output.insert(name, TypeDescription { values: enum_types }); + output.insert(name, types::TypeDescription { values: enum_types }); } } } @@ -36,3 +30,14 @@ pub fn get_object_types(content: &[MdContent]) -> HashMap Vec { + table + .rows + .iter() + .map(|row| types::TypeDescriptions { + value: row.columns[0].to_string(), + description: row.columns[1].to_string(), + }) + .collect() +} diff --git a/qbittorrent-web-api-gen/src/parser/parameters.rs b/qbittorrent-web-api-gen/src/parser/parameters.rs index 4b65682..ebbfb07 100644 --- a/qbittorrent-web-api-gen/src/parser/parameters.rs +++ b/qbittorrent-web-api-gen/src/parser/parameters.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; -use crate::{md_parser::MdContent, parser::types}; +use crate::{md_parser, parser::types}; -pub fn get_parameters(content: &[MdContent]) -> Option> { +pub fn parse_parameters(content: &[md_parser::MdContent]) -> Option> { let mut it = content .iter() .skip_while(|row| match row { - MdContent::Asterix(content) | MdContent::Text(content) => { + md_parser::MdContent::Asterix(content) | md_parser::MdContent::Text(content) => { !content.starts_with("Parameters:") } _ => true, @@ -17,7 +17,7 @@ pub fn get_parameters(content: &[MdContent]) -> Option> { .skip(2); let parameter_table = match it.next() { - Some(MdContent::Table(table)) => table, + Some(md_parser::MdContent::Table(table)) => table, _ => return None, }; @@ -27,20 +27,25 @@ pub fn get_parameters(content: &[MdContent]) -> Option> { let table = parameter_table .rows .iter() - .flat_map(|row| { - let description = row.columns.get(2).cloned(); - - match &row.columns.get(2) { - // 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], types::OPTIONAL); - types::Type::from(&row.columns[1], &name_with_optional, description, &type_map) - } - _ => types::Type::from(&row.columns[1], &row.columns[0], description, &type_map), - } - }) + .flat_map(|row| parse_parameter(row, &type_map)) .collect(); Some(table) } + +fn parse_parameter( + row: &md_parser::TableRow, + type_map: &HashMap, +) -> Option { + let description = row.columns.get(2).cloned(); + + match &row.columns.get(2) { + // 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], types::OPTIONAL); + types::Type::from(&row.columns[1], &name_with_optional, description, type_map) + } + _ => types::Type::from(&row.columns[1], &row.columns[0], description, type_map), + } +} diff --git a/qbittorrent-web-api-gen/src/parser/return_type.rs b/qbittorrent-web-api-gen/src/parser/return_type.rs index 940bd99..8c3fda3 100644 --- a/qbittorrent-web-api-gen/src/parser/return_type.rs +++ b/qbittorrent-web-api-gen/src/parser/return_type.rs @@ -1,6 +1,6 @@ use crate::{ md_parser::MdContent, - parser::{object_types::get_object_types, types, ReturnType, ReturnTypeParameter}, + parser::{object_types::parse_object_types, types, ReturnType, ReturnTypeParameter}, }; pub fn get_return_type(content: &[MdContent]) -> Option { @@ -18,7 +18,7 @@ pub fn get_return_type(content: &[MdContent]) -> Option { _ => None, })?; - let types = get_object_types(content); + let types = parse_object_types(content); let parameters = table .rows