Move parameter parsing to associated methods
This commit is contained in:
parent
8db9faf5f0
commit
a72d3e5fa7
|
@ -5835,18 +5835,15 @@
|
||||||
ReturnTypeParameter {
|
ReturnTypeParameter {
|
||||||
name: "results",
|
name: "results",
|
||||||
description: "Array of result objects- see table below",
|
description: "Array of result objects- see table below",
|
||||||
return_type: ObjectArray(
|
return_type: StringArray(
|
||||||
TypeWithRef {
|
TypeInfo {
|
||||||
type_info: TypeInfo {
|
name: "results",
|
||||||
name: "results",
|
is_optional: false,
|
||||||
is_optional: false,
|
is_list: false,
|
||||||
is_list: false,
|
description: Some(
|
||||||
description: Some(
|
"Array of result objects- see table below",
|
||||||
"Array of result objects- see table below",
|
),
|
||||||
),
|
type_description: None,
|
||||||
type_description: None,
|
|
||||||
},
|
|
||||||
ref_type: "result",
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 description;
|
||||||
mod parameters;
|
|
||||||
mod return_type;
|
mod return_type;
|
||||||
mod url;
|
mod url;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::{md_parser, parser::util, types};
|
use crate::{md_parser, parser::util, types};
|
||||||
|
|
||||||
pub use return_type::ReturnType;
|
pub use return_type::ReturnType;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
description::parse_method_description, parameters::parse_parameters,
|
description::parse_method_description, return_type::parse_return_type, url::get_method_url,
|
||||||
return_type::parse_return_type, url::get_method_url,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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 {
|
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 method_description = parse_method_description(&child.content);
|
||||||
let return_type = parse_return_type(&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);
|
let method_url = get_method_url(&child.content);
|
||||||
|
|
||||||
ApiMethod {
|
ApiMethod {
|
||||||
|
@ -73,3 +74,152 @@ fn to_api_method(child: &md_parser::TokenTree, name: &str) -> ApiMethod {
|
||||||
url: method_url,
|
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;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -45,6 +44,12 @@ pub struct TypeWithRef {
|
||||||
pub ref_type: String,
|
pub ref_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ComplexObject {
|
||||||
|
pub type_info: TypeInfo,
|
||||||
|
pub fields: Vec<Type>,
|
||||||
|
}
|
||||||
|
|
||||||
pub const OPTIONAL: &str = "_optional_";
|
pub const OPTIONAL: &str = "_optional_";
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -54,8 +59,8 @@ pub enum Type {
|
||||||
Bool(TypeInfo),
|
Bool(TypeInfo),
|
||||||
String(TypeInfo),
|
String(TypeInfo),
|
||||||
StringArray(TypeInfo),
|
StringArray(TypeInfo),
|
||||||
ObjectArray(TypeWithRef),
|
|
||||||
Object(TypeInfo),
|
Object(TypeInfo),
|
||||||
|
// ComplexObject(ComplexObject),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
@ -67,7 +72,7 @@ impl Type {
|
||||||
Type::String(_) => "String".into(),
|
Type::String(_) => "String".into(),
|
||||||
Type::StringArray(_) => "String".into(),
|
Type::StringArray(_) => "String".into(),
|
||||||
Type::Object(_) => "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::String(_) => "str".into(),
|
||||||
Type::StringArray(_) => "&[str]".into(),
|
Type::StringArray(_) => "&[str]".into(),
|
||||||
Type::Object(_) => "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::String(t) => t,
|
||||||
Type::StringArray(t) => t,
|
Type::StringArray(t) => t,
|
||||||
Type::Object(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())),
|
"bool" => Some(Type::Bool(create_type_info())),
|
||||||
"integer" | "number" | "int" => Some(Type::Number(create_type_info())),
|
"integer" | "number" | "int" => Some(Type::Number(create_type_info())),
|
||||||
"string" => Some(Type::String(create_type_info())),
|
"string" => Some(Type::String(create_type_info())),
|
||||||
"array" => description
|
"array" => Some(Type::StringArray(create_type_info())),
|
||||||
.clone()
|
// "array" => description
|
||||||
.and_then(|ref desc| get_ref_type(desc))
|
// .clone()
|
||||||
.map(|ref_type| {
|
// .and_then(|ref desc| get_ref_type(desc))
|
||||||
Type::ObjectArray(TypeWithRef {
|
// .map(|ref_type| {
|
||||||
type_info: create_type_info(),
|
// Type::ObjectArray(TypeWithRef {
|
||||||
ref_type,
|
// type_info: create_type_info(),
|
||||||
})
|
// ref_type,
|
||||||
})
|
// })
|
||||||
.or_else(|| Some(Type::StringArray(create_type_info()))),
|
// })
|
||||||
|
// .or_else(|| Some(Type::StringArray(create_type_info()))),
|
||||||
"object" => Some(Type::Object(create_type_info())),
|
"object" => Some(Type::Object(create_type_info())),
|
||||||
"float" => Some(Type::Float(create_type_info())),
|
"float" => Some(Type::Float(create_type_info())),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -148,24 +154,24 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ref_type(desc: &str) -> Option<String> {
|
// fn get_ref_type(desc: &str) -> Option<String> {
|
||||||
let re = RegexBuilder::new(r".*array of (\w+)\s?.*")
|
// let re = RegexBuilder::new(r".*array of (\w+)\s?.*")
|
||||||
.case_insensitive(true)
|
// .case_insensitive(true)
|
||||||
.build()
|
// .build()
|
||||||
.unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
re.captures(desc)
|
// re.captures(desc)
|
||||||
.and_then(|captures| captures.get(1))
|
// .and_then(|captures| captures.get(1))
|
||||||
.map(|m| m.as_str().to_owned())
|
// .map(|m| m.as_str().to_owned())
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
// use super::*;
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn should_parse_object_array() {
|
// fn should_parse_object_array() {
|
||||||
let ref_type = get_ref_type("Array of result objects- see table below");
|
// let ref_type = get_ref_type("Array of result objects- see table below");
|
||||||
assert_eq!("result", ref_type.unwrap());
|
// assert_eq!("result", ref_type.unwrap());
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user