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 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<Vec<types::Type>> {
self.get_type_containing("Parameters")
fn get_type_containing(&self, name: &str) -> Option<Vec<types::Type>> {
self.get_type_containing_as_table(name)
.map(|table| table.to_types())
}
// fn return_type(&self) -> Option<Vec<types::Type>> {
// 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<Vec<types::Type>> {
fn get_all_type_containing_as_table(&self, name: &str) -> HashMap<String, &md_parser::Table> {
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<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 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),
}
}
}

View File

@ -5,39 +5,43 @@ use crate::{
parser::{types, ReturnTypeParameter},
};
use super::Tables;
#[derive(Debug)]
pub struct ReturnType {
pub is_list: bool,
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 {
pub fn parse_return_type(&self) -> Option<ReturnType> {
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<String, types::TypeDescription> {
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()
}
}