Simplify return type parsing

This commit is contained in:
Joel Wachsler 2022-07-19 22:10:43 +00:00
parent f430e82b7a
commit af49a83034
2 changed files with 62 additions and 52 deletions

View File

@ -58,7 +58,9 @@ impl ApiMethod {
let method_description = child.parse_method_description(); let method_description = child.parse_method_description();
let return_type = child.parse_return_type(); let return_type = child.parse_return_type();
// let return_type = tables.return_type().map(|r| ReturnType::new(r)); // 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(); let method_url = child.get_method_url();
ApiMethod { ApiMethod {
@ -108,19 +110,24 @@ struct Tables<'a> {
} }
impl<'a> Tables<'a> { impl<'a> Tables<'a> {
fn parameters(&self) -> Option<Vec<types::Type>> { fn get_type_containing(&self, name: &str) -> Option<Vec<types::Type>> {
self.get_type_containing("Parameters") self.get_type_containing_as_table(name)
.map(|table| table.to_types())
} }
// fn return_type(&self) -> Option<Vec<types::Type>> { fn get_type_containing_as_table(&self, name: &str) -> Option<&md_parser::Table> {
// self.get_type_containing("The response is a") self.get_all_type_containing_as_table(name)
// } .iter()
.map(|(_, table)| *table)
.find(|_| true)
}
fn get_type_containing(&self, name: &str) -> Option<Vec<types::Type>> { fn get_all_type_containing_as_table(&self, name: &str) -> HashMap<String, &md_parser::Table> {
self.tables self.tables
.iter() .iter()
.find(|(key, _)| key.contains(name)) .filter(|(key, _)| key.contains(name))
.map(|(_, table)| table.to_types()) .map(|(k, table)| (k.clone(), *table))
.collect()
} }
} }
@ -135,8 +142,14 @@ impl md_parser::Table {
impl md_parser::TableRow { impl md_parser::TableRow {
fn to_type(&self) -> Option<types::Type> { fn to_type(&self) -> Option<types::Type> {
self.to_types_with_types(&HashMap::new())
}
fn to_types_with_types(
&self,
type_map: &HashMap<String, types::TypeDescription>,
) -> Option<types::Type> {
let columns = &self.columns; let columns = &self.columns;
let type_map = HashMap::new();
let description = columns.get(2).cloned(); let description = columns.get(2).cloned();
match &columns.get(2) { match &columns.get(2) {
@ -144,9 +157,9 @@ impl md_parser::TableRow {
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!("{} {}", columns[0], types::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),
} }
} }
} }

View File

@ -5,39 +5,43 @@ use crate::{
parser::{types, ReturnTypeParameter}, parser::{types, ReturnTypeParameter},
}; };
use super::Tables;
#[derive(Debug)] #[derive(Debug)]
pub struct ReturnType { pub struct ReturnType {
pub is_list: bool, pub is_list: bool,
pub parameters: Vec<ReturnTypeParameter>, pub parameters: Vec<ReturnTypeParameter>,
} }
impl md_parser::Table {
fn to_return_type_parameters(
&self,
types: &HashMap<String, types::TypeDescription>,
) -> Vec<ReturnTypeParameter> {
self.rows
.iter()
.map(|parameter| parameter.to_return_type_parameter(types))
.collect()
}
}
impl md_parser::TokenTree { impl md_parser::TokenTree {
pub fn parse_return_type(&self) -> Option<ReturnType> { pub fn parse_return_type(&self) -> Option<ReturnType> {
let table = self let tables: Tables = self.into();
.content let table = tables
.iter() .get_type_containing_as_table("The response is a")
// The response is a ... <-- Trying to find this line // these two are special cases not following a pattern
// <-- The next line is empty .or_else(|| tables.get_type_containing_as_table("Possible fields"))
// Table with the return type <-- And then extract the following type table .or_else(|| {
.skip_while(|row| match row { tables.get_type_containing_as_table(
MdContent::Text(text) => !text.starts_with("The response is a"), "Each element of the array has the following properties",
_ => true, )
})
.find_map(|row| match row {
MdContent::Table(table) => Some(table),
_ => None,
})?; })?;
let types = self.parse_object_types(); let types = self.parse_object_types();
let parameters = table
.rows
.iter()
.map(|parameter| parameter.to_return_type_parameter(&types))
.collect();
Some(ReturnType { Some(ReturnType {
parameters, parameters: table.to_return_type_parameters(&types),
is_list: self.is_list(), is_list: self.is_list(),
}) })
} }
@ -54,28 +58,21 @@ impl md_parser::TokenTree {
} }
pub fn parse_object_types(&self) -> HashMap<String, types::TypeDescription> { pub fn parse_object_types(&self) -> HashMap<String, types::TypeDescription> {
let mut output = HashMap::new(); let tables: Tables = self.into();
let mut content_it = self.content.iter(); const POSSIBLE_VALUES_OF: &str = "Possible values of ";
while let Some(entry) = content_it.next() { tables
if let md_parser::MdContent::Text(content) = entry { .get_all_type_containing_as_table(POSSIBLE_VALUES_OF)
const POSSIBLE_VALUES_OF: &str = "Possible values of "; .iter()
if content.contains(POSSIBLE_VALUES_OF) { .map(|(k, table)| {
// is empty let name = k
content_it.next(); .trim_start_matches(POSSIBLE_VALUES_OF)
if let Some(md_parser::MdContent::Table(table)) = content_it.next() { .replace('`', "")
let name = content .replace(':', "");
.trim_start_matches(POSSIBLE_VALUES_OF)
.replace('`', "")
.replace(':', "");
output.insert(name, table.to_type_description()); (name, table.to_type_description())
} })
} .collect()
}
}
output
} }
} }