diff --git a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs index b920f10..e3de6cf 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs @@ -58,7 +58,9 @@ impl ApiMethod { let method_description = child.parse_method_description(); let return_type = child.parse_return_type(); // let return_type = tables.return_type().map(|r| ReturnType::new(r)); - let parameters = tables.parameters().map(ApiParameters::new); + let parameters = tables + .get_type_containing("Parameters") + .map(ApiParameters::new); let method_url = child.get_method_url(); ApiMethod { @@ -108,19 +110,24 @@ struct Tables<'a> { } impl<'a> Tables<'a> { - fn parameters(&self) -> Option> { - self.get_type_containing("Parameters") + fn get_type_containing(&self, name: &str) -> Option> { + self.get_type_containing_as_table(name) + .map(|table| table.to_types()) } - // fn return_type(&self) -> Option> { - // self.get_type_containing("The response is a") - // } + fn get_type_containing_as_table(&self, name: &str) -> Option<&md_parser::Table> { + self.get_all_type_containing_as_table(name) + .iter() + .map(|(_, table)| *table) + .find(|_| true) + } - fn get_type_containing(&self, name: &str) -> Option> { + fn get_all_type_containing_as_table(&self, name: &str) -> HashMap { self.tables .iter() - .find(|(key, _)| key.contains(name)) - .map(|(_, table)| table.to_types()) + .filter(|(key, _)| key.contains(name)) + .map(|(k, table)| (k.clone(), *table)) + .collect() } } @@ -135,8 +142,14 @@ impl md_parser::Table { impl md_parser::TableRow { fn to_type(&self) -> Option { + self.to_types_with_types(&HashMap::new()) + } + + fn to_types_with_types( + &self, + type_map: &HashMap, + ) -> Option { let columns = &self.columns; - let type_map = HashMap::new(); let description = columns.get(2).cloned(); match &columns.get(2) { @@ -144,9 +157,9 @@ impl md_parser::TableRow { Some(desc) if desc.contains("default: ") => { // type defines a variable as default if it contains: _optional_ let name_with_optional = format!("{} {}", columns[0], types::OPTIONAL); - types::Type::from(&columns[1], &name_with_optional, description, &type_map) + types::Type::from(&columns[1], &name_with_optional, description, type_map) } - _ => types::Type::from(&columns[1], &columns[0], description, &type_map), + _ => types::Type::from(&columns[1], &columns[0], description, type_map), } } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs index 0dccc17..72fa7fc 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/return_type.rs @@ -5,39 +5,43 @@ use crate::{ parser::{types, ReturnTypeParameter}, }; +use super::Tables; + #[derive(Debug)] pub struct ReturnType { pub is_list: bool, pub parameters: Vec, } +impl md_parser::Table { + fn to_return_type_parameters( + &self, + types: &HashMap, + ) -> Vec { + self.rows + .iter() + .map(|parameter| parameter.to_return_type_parameter(types)) + .collect() + } +} + impl md_parser::TokenTree { pub fn parse_return_type(&self) -> Option { - let table = self - .content - .iter() - // The response is a ... <-- Trying to find this line - // <-- The next line is empty - // Table with the return type <-- And then extract the following type table - .skip_while(|row| match row { - MdContent::Text(text) => !text.starts_with("The response is a"), - _ => true, - }) - .find_map(|row| match row { - MdContent::Table(table) => Some(table), - _ => None, + let tables: Tables = self.into(); + let table = tables + .get_type_containing_as_table("The response is a") + // these two are special cases not following a pattern + .or_else(|| tables.get_type_containing_as_table("Possible fields")) + .or_else(|| { + tables.get_type_containing_as_table( + "Each element of the array has the following properties", + ) })?; let types = self.parse_object_types(); - let parameters = table - .rows - .iter() - .map(|parameter| parameter.to_return_type_parameter(&types)) - .collect(); - Some(ReturnType { - parameters, + parameters: table.to_return_type_parameters(&types), is_list: self.is_list(), }) } @@ -54,28 +58,21 @@ impl md_parser::TokenTree { } pub fn parse_object_types(&self) -> HashMap { - let mut output = HashMap::new(); - let mut content_it = self.content.iter(); + let tables: Tables = self.into(); + const POSSIBLE_VALUES_OF: &str = "Possible values of "; - while let Some(entry) = content_it.next() { - 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(md_parser::MdContent::Table(table)) = content_it.next() { - let name = content - .trim_start_matches(POSSIBLE_VALUES_OF) - .replace('`', "") - .replace(':', ""); + tables + .get_all_type_containing_as_table(POSSIBLE_VALUES_OF) + .iter() + .map(|(k, table)| { + let name = k + .trim_start_matches(POSSIBLE_VALUES_OF) + .replace('`', "") + .replace(':', ""); - output.insert(name, table.to_type_description()); - } - } - } - } - - output + (name, table.to_type_description()) + }) + .collect() } }