Refactor api parsing

This commit is contained in:
Joel Wachsler 2022-07-12 11:07:28 +00:00
parent bc54877578
commit 3360b2f3bd
4 changed files with 52 additions and 42 deletions

View File

@ -1,6 +1,6 @@
use crate::{md_parser, types}; 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 description;
mod object_types; mod object_types;
@ -39,6 +39,12 @@ pub struct ReturnTypeParameter {
pub return_type: types::Type, pub return_type: types::Type,
} }
pub fn parse_api_groups(content: &str) -> Vec<ApiGroup> {
parse_groups(extract_relevant_parts(md_parser::TokenTreeFactory::create(
content,
)))
}
fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec<md_parser::TokenTree> { fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec<md_parser::TokenTree> {
let relevant: Vec<md_parser::TokenTree> = tree let relevant: Vec<md_parser::TokenTree> = tree
.children .children
@ -56,12 +62,6 @@ fn extract_relevant_parts(tree: md_parser::TokenTree) -> Vec<md_parser::TokenTre
relevant relevant
} }
pub fn parse_api_groups(content: &str) -> Vec<ApiGroup> {
parse_groups(extract_relevant_parts(md_parser::TokenTreeFactory::create(
content,
)))
}
pub fn parse_groups(trees: Vec<md_parser::TokenTree>) -> Vec<ApiGroup> { pub fn parse_groups(trees: Vec<md_parser::TokenTree>) -> Vec<ApiGroup> {
trees.into_iter().map(parse_api_group).collect() trees.into_iter().map(parse_api_group).collect()
} }
@ -105,7 +105,7 @@ fn parse_api_method(child: md_parser::TokenTree) -> Option<ApiMethod> {
fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod { fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod {
let method_description = description::get_method_description(&child.content); let method_description = description::get_method_description(&child.content);
let return_type = get_return_type(&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); let method_url = get_method_url(&child.content);
ApiMethod { ApiMethod {

View File

@ -1,34 +1,28 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{md_parser::MdContent, parser::types}; use crate::{md_parser, parser::types};
use super::types::TypeDescription; pub fn parse_object_types(
content: &[md_parser::MdContent],
pub fn get_object_types(content: &[MdContent]) -> HashMap<String, TypeDescription> { ) -> HashMap<String, types::TypeDescription> {
let mut output = HashMap::new(); let mut output = HashMap::new();
let mut content_it = content.iter(); let mut content_it = content.iter();
while let Some(entry) = content_it.next() { 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 "; const POSSIBLE_VALUES_OF: &str = "Possible values of ";
if content.contains(POSSIBLE_VALUES_OF) { if content.contains(POSSIBLE_VALUES_OF) {
// is empty // is empty
content_it.next(); content_it.next();
if let Some(MdContent::Table(table)) = content_it.next() { if let Some(md_parser::MdContent::Table(table)) = content_it.next() {
let enum_types = table let enum_types = to_type_descriptions(table);
.rows
.iter()
.map(|row| types::TypeDescriptions {
value: row.columns[0].to_string(),
description: row.columns[1].to_string(),
})
.collect();
let name = content let name = content
.trim_start_matches(POSSIBLE_VALUES_OF) .trim_start_matches(POSSIBLE_VALUES_OF)
.replace('`', "") .replace('`', "")
.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<String, TypeDescriptio
output output
} }
fn to_type_descriptions(table: &md_parser::Table) -> Vec<types::TypeDescriptions> {
table
.rows
.iter()
.map(|row| types::TypeDescriptions {
value: row.columns[0].to_string(),
description: row.columns[1].to_string(),
})
.collect()
}

View File

@ -1,12 +1,12 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{md_parser::MdContent, parser::types}; use crate::{md_parser, parser::types};
pub fn get_parameters(content: &[MdContent]) -> Option<Vec<types::Type>> { pub fn parse_parameters(content: &[md_parser::MdContent]) -> Option<Vec<types::Type>> {
let mut it = content let mut it = content
.iter() .iter()
.skip_while(|row| match row { .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:") !content.starts_with("Parameters:")
} }
_ => true, _ => true,
@ -17,7 +17,7 @@ pub fn get_parameters(content: &[MdContent]) -> Option<Vec<types::Type>> {
.skip(2); .skip(2);
let parameter_table = match it.next() { let parameter_table = match it.next() {
Some(MdContent::Table(table)) => table, Some(md_parser::MdContent::Table(table)) => table,
_ => return None, _ => return None,
}; };
@ -27,20 +27,25 @@ pub fn get_parameters(content: &[MdContent]) -> Option<Vec<types::Type>> {
let table = parameter_table let table = parameter_table
.rows .rows
.iter() .iter()
.flat_map(|row| { .flat_map(|row| parse_parameter(row, &type_map))
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),
}
})
.collect(); .collect();
Some(table) Some(table)
} }
fn parse_parameter(
row: &md_parser::TableRow,
type_map: &HashMap<String, types::TypeDescription>,
) -> Option<types::Type> {
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),
}
}

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
md_parser::MdContent, 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<ReturnType> { pub fn get_return_type(content: &[MdContent]) -> Option<ReturnType> {
@ -18,7 +18,7 @@ pub fn get_return_type(content: &[MdContent]) -> Option<ReturnType> {
_ => None, _ => None,
})?; })?;
let types = get_object_types(content); let types = parse_object_types(content);
let parameters = table let parameters = table
.rows .rows