Move parameter parsing to associated methods
This commit is contained in:
parent
8db9faf5f0
commit
a72d3e5fa7
|
@ -5835,9 +5835,8 @@
|
|||
ReturnTypeParameter {
|
||||
name: "results",
|
||||
description: "Array of result objects- see table below",
|
||||
return_type: ObjectArray(
|
||||
TypeWithRef {
|
||||
type_info: TypeInfo {
|
||||
return_type: StringArray(
|
||||
TypeInfo {
|
||||
name: "results",
|
||||
is_optional: false,
|
||||
is_list: false,
|
||||
|
@ -5846,8 +5845,6 @@
|
|||
),
|
||||
type_description: None,
|
||||
},
|
||||
ref_type: "result",
|
||||
},
|
||||
),
|
||||
},
|
||||
ReturnTypeParameter {
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
ApiMethod {
|
||||
name: "results",
|
||||
description: Some(
|
||||
"The response is a JSON object with the following fields\n\n\n\n\nExample:\n\n```JSON\n{\n \"results\": [\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",\n \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",\n \"nbLeechers\": 1,\n \"nbSeeders\": 0,\n \"siteUrl\": \"http://www.legittorrents.info\"\n },\n {\n \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",\n \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",\n \"fileSize\": -1,\n \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",\n \"nbLeechers\": 0,\n \"nbSeeders\": 59,\n \"siteUrl\": \"http://www.legittorrents.info\"\n }\n ],\n \"status\": \"Running\",\n \"total\": 2\n}\n```",
|
||||
),
|
||||
parameters: Some(
|
||||
ApiParameters {
|
||||
mandatory: [
|
||||
Number(
|
||||
TypeInfo {
|
||||
name: "id",
|
||||
is_optional: false,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"ID of the search job",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
],
|
||||
optional: [
|
||||
Number(
|
||||
TypeInfo {
|
||||
name: "limit",
|
||||
is_optional: true,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"max number of results to return. 0 or negative means no limit",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
Number(
|
||||
TypeInfo {
|
||||
name: "offset",
|
||||
is_optional: true,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
],
|
||||
},
|
||||
),
|
||||
return_type: Some(
|
||||
ReturnType {
|
||||
is_list: false,
|
||||
parameters: [
|
||||
ReturnTypeParameter {
|
||||
name: "results",
|
||||
description: "Array of result objects- see table below",
|
||||
return_type: StringArray(
|
||||
TypeInfo {
|
||||
name: "results",
|
||||
is_optional: false,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"Array of result objects- see table below",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
},
|
||||
ReturnTypeParameter {
|
||||
name: "status",
|
||||
description: "Current status of the search job (either Running or Stopped)",
|
||||
return_type: String(
|
||||
TypeInfo {
|
||||
name: "status",
|
||||
is_optional: false,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"Current status of the search job (either Running or Stopped)",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
},
|
||||
ReturnTypeParameter {
|
||||
name: "total",
|
||||
description: "Total number of results. If the status is Running this number may continue to increase",
|
||||
return_type: Number(
|
||||
TypeInfo {
|
||||
name: "total",
|
||||
is_optional: false,
|
||||
is_list: false,
|
||||
description: Some(
|
||||
"Total number of results. If the status is Running this number may continue to increase",
|
||||
),
|
||||
type_description: None,
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
url: "results",
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
## Get search results ##
|
||||
|
||||
Name: `results`
|
||||
|
||||
**Parameters:**
|
||||
|
||||
Parameter | Type | Description
|
||||
----------------------------------|---------|------------
|
||||
`id` | number | ID of the search job
|
||||
`limit` _optional_ | number | max number of results to return. 0 or negative means no limit
|
||||
`offset` _optional_ | number | result to start at. A negative number means count backwards (e.g. `-2` returns the 2 most recent results)
|
||||
|
||||
**Returns:**
|
||||
|
||||
HTTP Status Code | Scenario
|
||||
----------------------------------|---------------------
|
||||
404 | Search job was not found
|
||||
409 | Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)
|
||||
200 | All other scenarios- see JSON below
|
||||
|
||||
The response is a JSON object with the following fields
|
||||
|
||||
Field | Type | Description
|
||||
----------------------------------|---------|------------
|
||||
`results` | array | Array of `result` objects- see table below
|
||||
`status` | string | Current status of the search job (either `Running` or `Stopped`)
|
||||
`total` | number | Total number of results. If the status is `Running` this number may continue to increase
|
||||
|
||||
**Result object:**
|
||||
|
||||
Field | Type | Description
|
||||
----------------------------------|---------|------------
|
||||
`descrLink` | string | URL of the torrent's description page
|
||||
`fileName` | string | Name of the file
|
||||
`fileSize` | number | Size of the file in Bytes
|
||||
`fileUrl` | string | Torrent download link (usually either .torrent file or magnet link)
|
||||
`nbLeechers` | number | Number of leechers
|
||||
`nbSeeders` | number | Number of seeders
|
||||
`siteUrl` | string | URL of the torrent site
|
||||
|
||||
Example:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"descrLink": "http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41",
|
||||
"fileName": "Ubuntu-10.04-32bit-NeTV.ova",
|
||||
"fileSize": -1,
|
||||
"fileUrl": "http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent",
|
||||
"nbLeechers": 1,
|
||||
"nbSeeders": 0,
|
||||
"siteUrl": "http://www.legittorrents.info"
|
||||
},
|
||||
{
|
||||
"descrLink": "http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475",
|
||||
"fileName": "mangOH-Legato-17_06-Ubuntu-16_04.ova",
|
||||
"fileSize": -1,
|
||||
"fileUrl": "http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent",
|
||||
"nbLeechers": 0,
|
||||
"nbSeeders": 59,
|
||||
"siteUrl": "http://www.legittorrents.info"
|
||||
}
|
||||
],
|
||||
"status": "Running",
|
||||
"total": 2
|
||||
}
|
||||
```
|
|
@ -0,0 +1,327 @@
|
|||
TokenTree {
|
||||
title: None,
|
||||
content: [],
|
||||
children: [
|
||||
TokenTree {
|
||||
title: Some(
|
||||
"Get search results",
|
||||
),
|
||||
content: [
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Text(
|
||||
"Name: `results`",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Asterisk(
|
||||
"Parameters:",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Table(
|
||||
Table {
|
||||
header: TableRow {
|
||||
raw: "Parameter | Type | Description",
|
||||
columns: [
|
||||
"Parameter",
|
||||
"Type",
|
||||
"Description",
|
||||
],
|
||||
},
|
||||
split: "----------------------------------|---------|------------",
|
||||
rows: [
|
||||
TableRow {
|
||||
raw: "`id` | number | ID of the search job",
|
||||
columns: [
|
||||
"id",
|
||||
"number",
|
||||
"ID of the search job",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`limit` _optional_ | number | max number of results to return. 0 or negative means no limit",
|
||||
columns: [
|
||||
"limit _optional_",
|
||||
"number",
|
||||
"max number of results to return. 0 or negative means no limit",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`offset` _optional_ | number | result to start at. A negative number means count backwards (e.g. `-2` returns the 2 most recent results)",
|
||||
columns: [
|
||||
"offset _optional_",
|
||||
"number",
|
||||
"result to start at. A negative number means count backwards (e.g. -2 returns the 2 most recent results)",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Asterisk(
|
||||
"Returns:",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Table(
|
||||
Table {
|
||||
header: TableRow {
|
||||
raw: "HTTP Status Code | Scenario",
|
||||
columns: [
|
||||
"HTTP Status Code",
|
||||
"Scenario",
|
||||
],
|
||||
},
|
||||
split: "----------------------------------|---------------------",
|
||||
rows: [
|
||||
TableRow {
|
||||
raw: "404 | Search job was not found",
|
||||
columns: [
|
||||
"404",
|
||||
"Search job was not found",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "409 | Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)",
|
||||
columns: [
|
||||
"409",
|
||||
"Offset is too large, or too small (e.g. absolute value of negative number is greater than # results)",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "200 | All other scenarios- see JSON below",
|
||||
columns: [
|
||||
"200",
|
||||
"All other scenarios- see JSON below",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Text(
|
||||
"The response is a JSON object with the following fields",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Table(
|
||||
Table {
|
||||
header: TableRow {
|
||||
raw: "Field | Type | Description",
|
||||
columns: [
|
||||
"Field",
|
||||
"Type",
|
||||
"Description",
|
||||
],
|
||||
},
|
||||
split: "----------------------------------|---------|------------",
|
||||
rows: [
|
||||
TableRow {
|
||||
raw: "`results` | array | Array of `result` objects- see table below",
|
||||
columns: [
|
||||
"results",
|
||||
"array",
|
||||
"Array of result objects- see table below",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`status` | string | Current status of the search job (either `Running` or `Stopped`)",
|
||||
columns: [
|
||||
"status",
|
||||
"string",
|
||||
"Current status of the search job (either Running or Stopped)",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`total` | number | Total number of results. If the status is `Running` this number may continue to increase",
|
||||
columns: [
|
||||
"total",
|
||||
"number",
|
||||
"Total number of results. If the status is Running this number may continue to increase",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Asterisk(
|
||||
"Result object:",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Table(
|
||||
Table {
|
||||
header: TableRow {
|
||||
raw: "Field | Type | Description",
|
||||
columns: [
|
||||
"Field",
|
||||
"Type",
|
||||
"Description",
|
||||
],
|
||||
},
|
||||
split: "----------------------------------|---------|------------",
|
||||
rows: [
|
||||
TableRow {
|
||||
raw: "`descrLink` | string | URL of the torrent's description page",
|
||||
columns: [
|
||||
"descrLink",
|
||||
"string",
|
||||
"URL of the torrent's description page",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`fileName` | string | Name of the file",
|
||||
columns: [
|
||||
"fileName",
|
||||
"string",
|
||||
"Name of the file",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`fileSize` | number | Size of the file in Bytes",
|
||||
columns: [
|
||||
"fileSize",
|
||||
"number",
|
||||
"Size of the file in Bytes",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`fileUrl` | string | Torrent download link (usually either .torrent file or magnet link)",
|
||||
columns: [
|
||||
"fileUrl",
|
||||
"string",
|
||||
"Torrent download link (usually either .torrent file or magnet link)",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`nbLeechers` | number | Number of leechers",
|
||||
columns: [
|
||||
"nbLeechers",
|
||||
"number",
|
||||
"Number of leechers",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`nbSeeders` | number | Number of seeders",
|
||||
columns: [
|
||||
"nbSeeders",
|
||||
"number",
|
||||
"Number of seeders",
|
||||
],
|
||||
},
|
||||
TableRow {
|
||||
raw: "`siteUrl` | string | URL of the torrent site",
|
||||
columns: [
|
||||
"siteUrl",
|
||||
"string",
|
||||
"URL of the torrent site",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Text(
|
||||
"Example:",
|
||||
),
|
||||
Text(
|
||||
"",
|
||||
),
|
||||
Text(
|
||||
"```JSON",
|
||||
),
|
||||
Text(
|
||||
"{",
|
||||
),
|
||||
Text(
|
||||
" \"results\": [",
|
||||
),
|
||||
Text(
|
||||
" {",
|
||||
),
|
||||
Text(
|
||||
" \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41\",",
|
||||
),
|
||||
Text(
|
||||
" \"fileName\": \"Ubuntu-10.04-32bit-NeTV.ova\",",
|
||||
),
|
||||
Text(
|
||||
" \"fileSize\": -1,",
|
||||
),
|
||||
Text(
|
||||
" \"fileUrl\": \"http://www.legittorrents.info/download.php?id=8d5f512e1acb687029b8d7cc6c5a84dce51d7a41&f=Ubuntu-10.04-32bit-NeTV.ova.torrent\",",
|
||||
),
|
||||
Text(
|
||||
" \"nbLeechers\": 1,",
|
||||
),
|
||||
Text(
|
||||
" \"nbSeeders\": 0,",
|
||||
),
|
||||
Text(
|
||||
" \"siteUrl\": \"http://www.legittorrents.info\"",
|
||||
),
|
||||
Text(
|
||||
" },",
|
||||
),
|
||||
Text(
|
||||
" {",
|
||||
),
|
||||
Text(
|
||||
" \"descrLink\": \"http://www.legittorrents.info/index.php?page=torrent-details&id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475\",",
|
||||
),
|
||||
Text(
|
||||
" \"fileName\": \"mangOH-Legato-17_06-Ubuntu-16_04.ova\",",
|
||||
),
|
||||
Text(
|
||||
" \"fileSize\": -1,",
|
||||
),
|
||||
Text(
|
||||
" \"fileUrl\": \"http://www.legittorrents.info/download.php?id=d5179f53e105dc2c2401bcfaa0c2c4936a6aa475&f=mangOH-Legato-17_06-Ubuntu-16_04.ova.torrent\",",
|
||||
),
|
||||
Text(
|
||||
" \"nbLeechers\": 0,",
|
||||
),
|
||||
Text(
|
||||
" \"nbSeeders\": 59,",
|
||||
),
|
||||
Text(
|
||||
" \"siteUrl\": \"http://www.legittorrents.info\"",
|
||||
),
|
||||
Text(
|
||||
" }",
|
||||
),
|
||||
Text(
|
||||
" ],",
|
||||
),
|
||||
Text(
|
||||
" \"status\": \"Running\",",
|
||||
),
|
||||
Text(
|
||||
" \"total\": 2",
|
||||
),
|
||||
Text(
|
||||
"}",
|
||||
),
|
||||
Text(
|
||||
"```",
|
||||
),
|
||||
],
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
mod description;
|
||||
mod parameters;
|
||||
mod return_type;
|
||||
mod url;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{md_parser, parser::util, types};
|
||||
|
||||
pub use return_type::ReturnType;
|
||||
|
||||
use self::{
|
||||
description::parse_method_description, parameters::parse_parameters,
|
||||
return_type::parse_return_type, url::get_method_url,
|
||||
description::parse_method_description, return_type::parse_return_type, url::get_method_url,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -60,9 +60,10 @@ pub fn parse_api_method(child: &md_parser::TokenTree) -> Option<ApiMethod> {
|
|||
}
|
||||
|
||||
fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod {
|
||||
let tables = child.to_tables();
|
||||
let method_description = parse_method_description(&child.content);
|
||||
let return_type = parse_return_type(&child.content);
|
||||
let parameters = parse_parameters(&child.content).map(ApiParameters::new);
|
||||
let parameters = tables.parameters().map(ApiParameters::new);
|
||||
let method_url = get_method_url(&child.content);
|
||||
|
||||
ApiMethod {
|
||||
|
@ -73,3 +74,152 @@ fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod {
|
|||
url: method_url,
|
||||
}
|
||||
}
|
||||
|
||||
impl md_parser::TokenTree {
|
||||
fn to_tables(&self) -> Tables<'_> {
|
||||
let mut tables = HashMap::new();
|
||||
let mut prev_prev: Option<&md_parser::MdContent> = None;
|
||||
let mut prev: Option<&md_parser::MdContent> = None;
|
||||
|
||||
for content in &self.content {
|
||||
if let md_parser::MdContent::Table(table) = content {
|
||||
let title = match prev_prev {
|
||||
Some(md_parser::MdContent::Text(text)) => text.clone(),
|
||||
Some(md_parser::MdContent::Asterisk(text)) => text.clone(),
|
||||
_ => panic!("Expected table title, found: {:?}", prev_prev),
|
||||
};
|
||||
|
||||
tables.insert(title.replace(':', ""), table);
|
||||
}
|
||||
|
||||
prev_prev = prev;
|
||||
prev = Some(content);
|
||||
}
|
||||
|
||||
Tables { tables }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Tables<'a> {
|
||||
tables: HashMap<String, &'a md_parser::Table>,
|
||||
}
|
||||
|
||||
impl<'a> Tables<'a> {
|
||||
fn parameters(&self) -> Option<Vec<types::Type>> {
|
||||
self.get_type_containing("Parameters")
|
||||
}
|
||||
|
||||
// fn return_type(&self) -> Option<Vec<types::Type>> {
|
||||
// self.get_type_containing("Returns")
|
||||
// }
|
||||
|
||||
fn get_type_containing(&self, name: &str) -> Option<Vec<types::Type>> {
|
||||
self.tables
|
||||
.iter()
|
||||
.find(|(key, _)| key.contains(name))
|
||||
.map(|(_, table)| table.to_types())
|
||||
}
|
||||
}
|
||||
|
||||
impl md_parser::Table {
|
||||
fn to_types(&self) -> Vec<types::Type> {
|
||||
self.rows
|
||||
.iter()
|
||||
.flat_map(|table_row| table_row.to_type())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl md_parser::TableRow {
|
||||
fn to_type(&self) -> Option<types::Type> {
|
||||
let columns = &self.columns;
|
||||
let type_map = HashMap::new();
|
||||
let description = columns.get(2).cloned();
|
||||
|
||||
match &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!("{} {}", columns[0], types::OPTIONAL);
|
||||
types::Type::from(&columns[1], &name_with_optional, description, &type_map)
|
||||
}
|
||||
_ => types::Type::from(&columns[1], &columns[0], description, &type_map),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use md_parser::TokenTreeFactory;
|
||||
|
||||
macro_rules! TEST_DIR {
|
||||
() => {
|
||||
"method_tests"
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! run_test {
|
||||
($test_file:expr) => {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
// given
|
||||
let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md"));
|
||||
|
||||
// when
|
||||
let tree = TokenTreeFactory::create(input);
|
||||
let api_method = parse_api_method(&tree.children[0]).unwrap();
|
||||
|
||||
// then
|
||||
let api_method_as_str = format!("{api_method:#?}");
|
||||
let should_be = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".check"));
|
||||
assert_eq!(api_method_as_str, should_be);
|
||||
};
|
||||
}
|
||||
|
||||
// use this macro when creating/updating as test
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! update_test {
|
||||
($test_file:expr) => {
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
let input = include_str!(concat!(TEST_DIR!(), "/", $test_file, ".md"));
|
||||
let tree = TokenTreeFactory::create(input);
|
||||
let api_method = parse_api_method(&tree.children[0]).unwrap();
|
||||
|
||||
let tree_as_str = format!("{tree:#?}");
|
||||
let api_method_as_str = format!("{api_method:#?}");
|
||||
|
||||
let tree_file = concat!(
|
||||
"src/parser/group/method/",
|
||||
TEST_DIR!(),
|
||||
"/",
|
||||
$test_file,
|
||||
".tree"
|
||||
);
|
||||
let file = concat!(
|
||||
"src/parser/group/method/",
|
||||
TEST_DIR!(),
|
||||
"/",
|
||||
$test_file,
|
||||
".check"
|
||||
);
|
||||
|
||||
// prevent user from accidentally leaving the current macro in a test
|
||||
if Path::new(file).exists() {
|
||||
panic!("Test case already exists: {file}");
|
||||
}
|
||||
|
||||
fs::write(file, api_method_as_str).unwrap();
|
||||
fs::write(tree_file, tree_as_str).unwrap();
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search_result() {
|
||||
run_test!("search_result");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::{md_parser, parser::types};
|
||||
|
||||
pub fn parse_parameters(content: &[md_parser::MdContent]) -> Option<Vec<types::Type>> {
|
||||
let mut it = content
|
||||
.iter()
|
||||
.skip_while(|row| match row {
|
||||
md_parser::MdContent::Asterisk(content) | md_parser::MdContent::Text(content) => {
|
||||
!content.starts_with("Parameters:")
|
||||
}
|
||||
_ => true,
|
||||
})
|
||||
// Parameters: <-- skip
|
||||
// <-- skip
|
||||
// table with parameters <-- take
|
||||
.skip(2);
|
||||
|
||||
let parameter_table = match it.next() {
|
||||
Some(md_parser::MdContent::Table(table)) => table,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// empty for now
|
||||
let type_map = HashMap::default();
|
||||
|
||||
let table = parameter_table
|
||||
.rows
|
||||
.iter()
|
||||
.flat_map(|row| parse_parameter(row, &type_map))
|
||||
.collect();
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
use regex::RegexBuilder;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -45,6 +44,12 @@ pub struct TypeWithRef {
|
|||
pub ref_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ComplexObject {
|
||||
pub type_info: TypeInfo,
|
||||
pub fields: Vec<Type>,
|
||||
}
|
||||
|
||||
pub const OPTIONAL: &str = "_optional_";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -54,8 +59,8 @@ pub enum Type {
|
|||
Bool(TypeInfo),
|
||||
String(TypeInfo),
|
||||
StringArray(TypeInfo),
|
||||
ObjectArray(TypeWithRef),
|
||||
Object(TypeInfo),
|
||||
// ComplexObject(ComplexObject),
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -67,7 +72,7 @@ impl Type {
|
|||
Type::String(_) => "String".into(),
|
||||
Type::StringArray(_) => "String".into(),
|
||||
Type::Object(_) => "String".into(),
|
||||
Type::ObjectArray(_) => panic!("Not implemented for ObjectArray"),
|
||||
// Type::ComplexObject(_) => panic!("Not implemented for ComplexObject"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +88,7 @@ impl Type {
|
|||
Type::String(_) => "str".into(),
|
||||
Type::StringArray(_) => "&[str]".into(),
|
||||
Type::Object(_) => "str".into(),
|
||||
Type::ObjectArray(_) => panic!("Not implemented for ObjectArray"),
|
||||
// Type::ComplexObject(_) => panic!("Not implemented for ComplexObject"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +104,7 @@ impl Type {
|
|||
Type::String(t) => t,
|
||||
Type::StringArray(t) => t,
|
||||
Type::Object(t) => t,
|
||||
Type::ObjectArray(TypeWithRef { type_info, .. }) => type_info,
|
||||
// Type::ComplexObject(ComplexObject { type_info, .. }) => type_info,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,16 +136,17 @@ impl Type {
|
|||
"bool" => Some(Type::Bool(create_type_info())),
|
||||
"integer" | "number" | "int" => Some(Type::Number(create_type_info())),
|
||||
"string" => Some(Type::String(create_type_info())),
|
||||
"array" => description
|
||||
.clone()
|
||||
.and_then(|ref desc| get_ref_type(desc))
|
||||
.map(|ref_type| {
|
||||
Type::ObjectArray(TypeWithRef {
|
||||
type_info: create_type_info(),
|
||||
ref_type,
|
||||
})
|
||||
})
|
||||
.or_else(|| Some(Type::StringArray(create_type_info()))),
|
||||
"array" => Some(Type::StringArray(create_type_info())),
|
||||
// "array" => description
|
||||
// .clone()
|
||||
// .and_then(|ref desc| get_ref_type(desc))
|
||||
// .map(|ref_type| {
|
||||
// Type::ObjectArray(TypeWithRef {
|
||||
// type_info: create_type_info(),
|
||||
// ref_type,
|
||||
// })
|
||||
// })
|
||||
// .or_else(|| Some(Type::StringArray(create_type_info()))),
|
||||
"object" => Some(Type::Object(create_type_info())),
|
||||
"float" => Some(Type::Float(create_type_info())),
|
||||
_ => None,
|
||||
|
@ -148,24 +154,24 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_ref_type(desc: &str) -> Option<String> {
|
||||
let re = RegexBuilder::new(r".*array of (\w+)\s?.*")
|
||||
.case_insensitive(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
// fn get_ref_type(desc: &str) -> Option<String> {
|
||||
// let re = RegexBuilder::new(r".*array of (\w+)\s?.*")
|
||||
// .case_insensitive(true)
|
||||
// .build()
|
||||
// .unwrap();
|
||||
|
||||
re.captures(desc)
|
||||
.and_then(|captures| captures.get(1))
|
||||
.map(|m| m.as_str().to_owned())
|
||||
}
|
||||
// re.captures(desc)
|
||||
// .and_then(|captures| captures.get(1))
|
||||
// .map(|m| m.as_str().to_owned())
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
// use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_parse_object_array() {
|
||||
let ref_type = get_ref_type("Array of result objects- see table below");
|
||||
assert_eq!("result", ref_type.unwrap());
|
||||
}
|
||||
// #[test]
|
||||
// fn should_parse_object_array() {
|
||||
// let ref_type = get_ref_type("Array of result objects- see table below");
|
||||
// assert_eq!("result", ref_type.unwrap());
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user