From dcacdcda9c23e0b5cb51d931e1d36406761405c3 Mon Sep 17 00:00:00 2001 From: Joel Wachsler Date: Sat, 23 Jul 2022 00:23:17 +0000 Subject: [PATCH] Fix response tests --- qbittorrent-web-api-gen/api-4_1.md | 99 ++- qbittorrent-web-api-gen/groups.txt | 655 +++++++++++++++++- .../src/generate/group/mod.rs | 37 +- .../group/method/method_tests/ref_type.check | 110 +++ .../group/method/method_tests/ref_type.md | 65 ++ .../group/method/method_tests/ref_type.tree | 276 ++++++++ .../method/method_tests/search_result.check | 4 +- .../src/parser/group/method/mod.rs | 5 + qbittorrent-web-api-gen/src/types.rs | 106 ++- qbittorrent-web-api-gen/token_tree.txt | 583 +++++++++++++++- 10 files changed, 1839 insertions(+), 101 deletions(-) create mode 100644 qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check create mode 100644 qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md create mode 100644 qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree diff --git a/qbittorrent-web-api-gen/api-4_1.md b/qbittorrent-web-api-gen/api-4_1.md index cf94502..35e55f5 100644 --- a/qbittorrent-web-api-gen/api-4_1.md +++ b/qbittorrent-web-api-gen/api-4_1.md @@ -1002,17 +1002,17 @@ HTTP Status Code | Scenario The response is a JSON object with the following possible fields -Property | Type | Description -------------------------------|---------|------------ -`rid` | integer | Response ID -`full_update` | bool | Whether the response contains all the data or partial data -`torrents` | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list) -`torrents_removed` | array | List of hashes of torrents removed since last request -`categories` | object | Info for categories added since last request -`categories_removed` | array | List of categories removed since last request -`tags` | array | List of tags added since last request -`tags_removed` | array | List of tags removed since last request -`server_state` | object | Global transfer info +Property | Type | Description +--------------------------------|-----------|------------ +`rid` | integer | Response ID +`full_update`_optional_ | bool | Whether the response contains all the data or partial data +`torrents`_optional_ | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object +`torrents_removed`_optional_ | array | List of hashes of torrents removed since last request +`categories`_optional_ | object | Info for categories added since last request, map from string to categories object +`categories_removed`_optional_ | array | List of categories removed since last request +`tags`_optional_ | array | List of tags added since last request +`tags_removed`_optional_ | array | List of tags removed since last request +`server_state`_optional_ | object | `server_state` object see table below Example: @@ -1029,6 +1029,74 @@ Example: } ``` +**ServerState object:** + +Property | Type | Description +------------------------------|---------|------------ +`average_time_queue` | integer | Average time queue +`dl_info_data` | number | Download info data +`dl_info_speed` | number | Download info speed +`queued_io_jobs` | integer | Queued io jobs +`total_buffers_size` | number | Total buffers size +`total_peer_connections` | integer | Total peer connections + +**Categories object:** + +Property | Type | Description +------------------------------|---------|------------ +`name` | string | Category name +`savePath` | string | Save path + +**Torrents object:** + +Property | Type | Description +--------------------------------|-----------|------------ +`added_on`_optional_ | integer | Time (Unix Epoch) when the torrent was added to the client +`amount_left`_optional_ | integer | Amount of data left to download (bytes) +`auto_tmm`_optional_ | bool | Whether this torrent is managed by Automatic Torrent Management +`availability`_optional_ | float | Percentage of file pieces currently available +`category`_optional_ | string | Category of the torrent +`completed`_optional_ | integer | Amount of transfer data completed (bytes) +`completion_on`_optional_ | integer | Time (Unix Epoch) when the torrent completed +`content_path`_optional_ | string | Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents) +`dl_limit`_optional_ | integer | Torrent download speed limit (bytes/s). `-1` if ulimited. +`dlspeed`_optional_ | integer | Torrent download speed (bytes/s) +`downloaded`_optional_ | integer | Amount of data downloaded +`downloaded_session`_optional_ | integer | Amount of data downloaded this session +`eta`_optional_ | integer | Torrent ETA (seconds) +`f_l_piece_prio`_optional_ | bool | True if first last piece are prioritized +`force_start`_optional_ | bool | True if force start is enabled for this torrent +`hash`_optional_ | string | Torrent hash +`last_activity`_optional_ | integer | Last time (Unix Epoch) when a chunk was downloaded/uploaded +`magnet_uri`_optional_ | string | Magnet URI corresponding to this torrent +`max_ratio`_optional_ | float | Maximum share ratio until torrent is stopped from seeding/uploading +`max_seeding_time`_optional_ | integer | Maximum seeding time (seconds) until torrent is stopped from seeding +`name`_optional_ | string | Torrent name +`num_complete`_optional_ | integer | Number of seeds in the swarm +`num_incomplete`_optional_ | integer | Number of leechers in the swarm +`num_leechs`_optional_ | integer | Number of leechers connected to +`num_seeds`_optional_ | integer | Number of seeds connected to +`priority`_optional_ | integer | Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode +`progress`_optional_ | float | Torrent progress (percentage/100) +`ratio`_optional_ | float | Torrent share ratio. Max ratio value: 9999. +`ratio_limit`_optional_ | float | TODO (what is different from `max_ratio`?) +`save_path`_optional_ | string | Path where this torrent's data is stored +`seeding_time`_optional_ | integer | Torrent elapsed time while complete (seconds) +`seeding_time_limit`_optional_ | integer | TODO (what is different from `max_seeding_time`?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1. +`seen_complete`_optional_ | integer | Time (Unix Epoch) when this torrent was last seen complete +`seq_dl`_optional_ | bool | True if sequential download is enabled +`size`_optional_ | integer | Total size (bytes) of files selected for download +`state`_optional_ | string | Torrent state. See table here below for the possible values +`super_seeding`_optional_ | bool | True if super seeding is enabled +`tags`_optional_ | string | Comma-concatenated tag list of the torrent +`time_active`_optional_ | integer | Total active time (seconds) +`total_size`_optional_ | integer | Total size (bytes) of all file in this torrent (including unselected ones) +`tracker`_optional_ | string | The first tracker with working status. Returns empty string if no tracker is working. +`up_limit`_optional_ | integer | Torrent upload speed limit (bytes/s). `-1` if ulimited. +`uploaded`_optional_ | integer | Amount of data uploaded +`uploaded_session`_optional_ | integer | Amount of data uploaded this session +`upspeed`_optional_ | integer | Torrent upload speed (bytes/s) + ## Get torrent peers data ## Name: `torrentPeers` @@ -1756,7 +1824,7 @@ Name: `delete` Parameter | Type | Description ------------|----------|------------ `hashes` | string | The hashes of the torrents you want to delete. `hashes` can contain multiple hashes separated by `\|`, to delete multiple torrents, or set to `all`, to delete all torrents. -`deleteFiles` | If set to `true`, the downloaded data will also be deleted, otherwise has no effect. +`deleteFiles` | bool | If set to `true`, the downloaded data will also be deleted, otherwise has no effect. Example: @@ -3275,6 +3343,13 @@ Field | Type | Description ] ``` +**Category object:** + +Field | Type | Description +---------------------------|---------|------------ +`id` | string | Id +`name` | string | Name + ## Install search plugin ## Name: `installPlugin` diff --git a/qbittorrent-web-api-gen/groups.txt b/qbittorrent-web-api-gen/groups.txt index 0cf22a1..e470003 100644 --- a/qbittorrent-web-api-gen/groups.txt +++ b/qbittorrent-web-api-gen/groups.txt @@ -628,6 +628,33 @@ url: "maindata", types: CompositeTypes { composite_types: [ + Object( + TypeWithName { + name: "Categories", + types: [ + String( + TypeInfo { + name: "name", + description: Some( + "Category name", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "savePath", + description: Some( + "Save path", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), Parameters( TypeWithoutName { types: [ @@ -645,6 +672,73 @@ is_list: false, }, ), + Object( + TypeWithName { + name: "ServerState", + types: [ + Number( + TypeInfo { + name: "average_time_queue", + description: Some( + "Average time queue", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_info_data", + description: Some( + "Download info data", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_info_speed", + description: Some( + "Download info speed", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "queued_io_jobs", + description: Some( + "Queued io jobs", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_buffers_size", + description: Some( + "Total buffers size", + ), + is_optional: false, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_peer_connections", + description: Some( + "Total peer connections", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), Response( TypeWithoutName { types: [ @@ -664,7 +758,7 @@ description: Some( "Whether the response contains all the data or partial data", ), - is_optional: false, + is_optional: true, is_list: false, }, ), @@ -673,12 +767,15 @@ type_info: TypeInfo { name: "torrents", description: Some( - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", + "Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", ), - is_optional: false, + is_optional: true, is_list: false, }, - ref_type: "Object", + ref_type: Map( + "String", + "Torrents", + ), }, ), Object( @@ -688,10 +785,12 @@ description: Some( "List of hashes of torrents removed since last request", ), - is_optional: false, + is_optional: true, is_list: true, }, - ref_type: "", + ref_type: String( + "String", + ), }, ), Object( @@ -699,12 +798,15 @@ type_info: TypeInfo { name: "categories", description: Some( - "Info for categories added since last request", + "Info for categories added since last request, map from string to categories object", ), - is_optional: false, + is_optional: true, is_list: false, }, - ref_type: "Object", + ref_type: Map( + "String", + "Categories", + ), }, ), Object( @@ -714,10 +816,12 @@ description: Some( "List of categories removed since last request", ), - is_optional: false, + is_optional: true, is_list: true, }, - ref_type: "", + ref_type: String( + "String", + ), }, ), Object( @@ -727,10 +831,12 @@ description: Some( "List of tags added since last request", ), - is_optional: false, + is_optional: true, is_list: true, }, - ref_type: "", + ref_type: String( + "String", + ), }, ), Object( @@ -740,10 +846,12 @@ description: Some( "List of tags removed since last request", ), - is_optional: false, + is_optional: true, is_list: true, }, - ref_type: "", + ref_type: String( + "String", + ), }, ), Object( @@ -751,18 +859,477 @@ type_info: TypeInfo { name: "server_state", description: Some( - "Global transfer info", + "server_state object see table below", ), - is_optional: false, + is_optional: true, is_list: false, }, - ref_type: "Object", + ref_type: String( + "ServerState", + ), }, ), ], is_list: false, }, ), + Object( + TypeWithName { + name: "Torrents", + types: [ + Number( + TypeInfo { + name: "added_on", + description: Some( + "Time (Unix Epoch) when the torrent was added to the client", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "amount_left", + description: Some( + "Amount of data left to download (bytes)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "auto_tmm", + description: Some( + "Whether this torrent is managed by Automatic Torrent Management", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "availability", + description: Some( + "Percentage of file pieces currently available", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "category", + description: Some( + "Category of the torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completed", + description: Some( + "Amount of transfer data completed (bytes)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "completion_on", + description: Some( + "Time (Unix Epoch) when the torrent completed", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "content_path", + description: Some( + "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dl_limit", + description: Some( + "Torrent download speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "dlspeed", + description: Some( + "Torrent download speed (bytes/s)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded", + description: Some( + "Amount of data downloaded", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "downloaded_session", + description: Some( + "Amount of data downloaded this session", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "eta", + description: Some( + "Torrent ETA (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "f_l_piece_prio", + description: Some( + "True if first last piece are prioritized", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "force_start", + description: Some( + "True if force start is enabled for this torrent", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "hash", + description: Some( + "Torrent hash", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "last_activity", + description: Some( + "Last time (Unix Epoch) when a chunk was downloaded/uploaded", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "magnet_uri", + description: Some( + "Magnet URI corresponding to this torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "max_ratio", + description: Some( + "Maximum share ratio until torrent is stopped from seeding/uploading", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "max_seeding_time", + description: Some( + "Maximum seeding time (seconds) until torrent is stopped from seeding", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Torrent name", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_complete", + description: Some( + "Number of seeds in the swarm", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_incomplete", + description: Some( + "Number of leechers in the swarm", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_leechs", + description: Some( + "Number of leechers connected to", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "num_seeds", + description: Some( + "Number of seeds connected to", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "priority", + description: Some( + "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "progress", + description: Some( + "Torrent progress (percentage/100)", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio", + description: Some( + "Torrent share ratio. Max ratio value: 9999.", + ), + is_optional: true, + is_list: false, + }, + ), + Float( + TypeInfo { + name: "ratio_limit", + description: Some( + "TODO (what is different from max_ratio?)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "save_path", + description: Some( + "Path where this torrent's data is stored", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time", + description: Some( + "Torrent elapsed time while complete (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seeding_time_limit", + description: Some( + "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "seen_complete", + description: Some( + "Time (Unix Epoch) when this torrent was last seen complete", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "seq_dl", + description: Some( + "True if sequential download is enabled", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "size", + description: Some( + "Total size (bytes) of files selected for download", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "state", + description: Some( + "Torrent state. See table here below for the possible values", + ), + is_optional: true, + is_list: false, + }, + ), + Bool( + TypeInfo { + name: "super_seeding", + description: Some( + "True if super seeding is enabled", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tags", + description: Some( + "Comma-concatenated tag list of the torrent", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "time_active", + description: Some( + "Total active time (seconds)", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "total_size", + description: Some( + "Total size (bytes) of all file in this torrent (including unselected ones)", + ), + is_optional: true, + is_list: false, + }, + ), + String( + TypeInfo { + name: "tracker", + description: Some( + "The first tracker with working status. Returns empty string if no tracker is working.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "up_limit", + description: Some( + "Torrent upload speed limit (bytes/s). -1 if ulimited.", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded", + description: Some( + "Amount of data uploaded", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "uploaded_session", + description: Some( + "Amount of data uploaded this session", + ), + is_optional: true, + is_list: false, + }, + ), + Number( + TypeInfo { + name: "upspeed", + description: Some( + "Torrent upload speed (bytes/s)", + ), + is_optional: true, + is_list: false, + }, + ), + ], + }, + ), ], }, }, @@ -2161,15 +2728,14 @@ is_list: false, }, ), - Object( - Object { - type_info: TypeInfo { - name: "deleteFiles", - description: None, - is_optional: false, - is_list: false, - }, - ref_type: "If set to true, the downloaded data will also be deleted, otherwise has no effect.", + Bool( + TypeInfo { + name: "deleteFiles", + description: Some( + "If set to true, the downloaded data will also be deleted, otherwise has no effect.", + ), + is_optional: false, + is_list: false, }, ), ], @@ -3614,7 +4180,9 @@ is_optional: false, is_list: true, }, - ref_type: "", + ref_type: String( + "Result", + ), }, ), String( @@ -3678,6 +4246,33 @@ url: "plugins", types: CompositeTypes { composite_types: [ + Object( + TypeWithName { + name: "Category", + types: [ + String( + TypeInfo { + name: "id", + description: Some( + "Id", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Name", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), Response( TypeWithoutName { types: [ @@ -3721,7 +4316,9 @@ is_optional: false, is_list: true, }, - ref_type: "", + ref_type: String( + "Category", + ), }, ), String( diff --git a/qbittorrent-web-api-gen/src/generate/group/mod.rs b/qbittorrent-web-api-gen/src/generate/group/mod.rs index 7003673..111b0fc 100644 --- a/qbittorrent-web-api-gen/src/generate/group/mod.rs +++ b/qbittorrent-web-api-gen/src/generate/group/mod.rs @@ -147,14 +147,36 @@ impl parser::TypeWithName { } impl types::Type { + fn owned_type_ident(&self) -> TokenStream { + let owned_type = match self { + types::Type::Number(_) => quote! { i128 }, + types::Type::Float(_) => quote! { f32 }, + types::Type::Bool(_) => quote! { bool }, + types::Type::String(_) => quote! { String }, + types::Type::StringArray(_) => quote! { String }, + types::Type::Object(obj) => match &obj.ref_type { + types::RefType::String(str) => { + let str_ident = &util::to_ident(str); + quote! { #str_ident } + } + types::RefType::Map(key, value) => { + let key_ident = util::to_ident(key); + let value_ident = util::to_ident(value); + quote! { std::collections::HashMap<#key_ident, #value_ident> } + } + }, + }; + + if self.is_list() { + quote! { std::vec::Vec<#owned_type> } + } else { + owned_type + } + } + fn generate_struct_field(&self) -> TokenStream { let name_snake = self.name_snake(); - let type_name = util::to_ident(&self.to_owned_type()); - let type_ = if self.is_list() { - quote! { std::vec::Vec<#type_name> } - } else { - quote! { #type_name } - }; + let type_ = self.owned_type_ident(); let orig_name = self.name(); util::add_docs( @@ -440,11 +462,10 @@ impl types::Type { } fn borrowed_type(&self) -> TokenStream { + let type_ = self.borrowed_type_ident(); if self.should_borrow() { - let type_ = self.borrowed_type_ident(); quote! { &#type_ } } else { - let type_ = self.borrowed_type_ident(); quote! { #type_ } } } diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check new file mode 100644 index 0000000..7a7dec4 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.check @@ -0,0 +1,110 @@ +ApiMethod { + name: "plugins", + description: Some( + "The response is a JSON array of objects containing the following fields\n\n\n```JSON\n[\n {\n \"enabled\": true,\n \"fullName\": \"Legit Torrents\",\n \"name\": \"legittorrents\",\n \"supportedCategories\": [{\n \"id\": \"all\",\n \"name\": \"All categories\"\n }, {\n \"id\": \"anime\",\n \"name\": \"Anime\"\n }, {\n \"id\": \"books\",\n \"name\": \"Books\"\n }, {\n \"id\": \"games\",\n \"name\": \"Games\"\n }, {\n \"id\": \"movies\",\n \"name\": \"Movies\"\n }, {\n \"id\": \"music\",\n \"name\": \"Music\"\n }, {\n \"id\": \"tv\",\n \"name\": \"TV shows\"\n }],\n \"url\": \"http://www.legittorrents.info\",\n \"version\": \"2.3\"\n }\n]\n```", + ), + url: "plugins", + types: CompositeTypes { + composite_types: [ + Object( + TypeWithName { + name: "Category", + types: [ + String( + TypeInfo { + name: "id", + description: Some( + "Id", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Name", + ), + is_optional: false, + is_list: false, + }, + ), + ], + }, + ), + Response( + TypeWithoutName { + types: [ + Bool( + TypeInfo { + name: "enabled", + description: Some( + "Whether the plugin is enabled", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "fullName", + description: Some( + "Full name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "name", + description: Some( + "Short name of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + Object( + Object { + type_info: TypeInfo { + name: "supportedCategories", + description: Some( + "List of category objects", + ), + is_optional: false, + is_list: true, + }, + ref_type: String( + "Category", + ), + }, + ), + String( + TypeInfo { + name: "url", + description: Some( + "URL of the torrent site", + ), + is_optional: false, + is_list: false, + }, + ), + String( + TypeInfo { + name: "version", + description: Some( + "Installed version of the plugin", + ), + is_optional: false, + is_list: false, + }, + ), + ], + is_list: true, + }, + ), + ], + }, +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md new file mode 100644 index 0000000..07dd1aa --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.md @@ -0,0 +1,65 @@ +## Get search plugins ## + +Name: `plugins` + +**Parameters:** + +None + +**Returns:** + +HTTP Status Code | Scenario +----------------------------------|--------------------- +200 | All scenarios- see JSON below + +The response is a JSON array of objects containing the following fields + +Field | Type | Description +----------------------------------|---------|------------ +`enabled` | bool | Whether the plugin is enabled +`fullName` | string | Full name of the plugin +`name` | string | Short name of the plugin +`supportedCategories` | array | List of category objects +`url` | string | URL of the torrent site +`version` | string | Installed version of the plugin + +```JSON +[ + { + "enabled": true, + "fullName": "Legit Torrents", + "name": "legittorrents", + "supportedCategories": [{ + "id": "all", + "name": "All categories" + }, { + "id": "anime", + "name": "Anime" + }, { + "id": "books", + "name": "Books" + }, { + "id": "games", + "name": "Games" + }, { + "id": "movies", + "name": "Movies" + }, { + "id": "music", + "name": "Music" + }, { + "id": "tv", + "name": "TV shows" + }], + "url": "http://www.legittorrents.info", + "version": "2.3" + } +] +``` + +**Category object:** + +Field | Type | Description +---------------------------|---------|------------ +`id` | string | Id +`name` | string | Name diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree new file mode 100644 index 0000000..2e3f921 --- /dev/null +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/ref_type.tree @@ -0,0 +1,276 @@ +TokenTree { + title: None, + content: [], + children: [ + TokenTree { + title: Some( + "Get search plugins", + ), + content: [ + Text( + "", + ), + Text( + "Name: `plugins`", + ), + Text( + "", + ), + Asterisk( + "Parameters:", + ), + Text( + "", + ), + Text( + "None", + ), + Text( + "", + ), + Asterisk( + "Returns:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "HTTP Status Code | Scenario", + columns: [ + "HTTP Status Code", + "Scenario", + ], + }, + split: "----------------------------------|---------------------", + rows: [ + TableRow { + raw: "200 | All scenarios- see JSON below", + columns: [ + "200", + "All scenarios- see JSON below", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "The response is a JSON array of objects containing the following fields", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "----------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`enabled` | bool | Whether the plugin is enabled", + columns: [ + "enabled", + "bool", + "Whether the plugin is enabled", + ], + }, + TableRow { + raw: "`fullName` | string | Full name of the plugin", + columns: [ + "fullName", + "string", + "Full name of the plugin", + ], + }, + TableRow { + raw: "`name` | string | Short name of the plugin", + columns: [ + "name", + "string", + "Short name of the plugin", + ], + }, + TableRow { + raw: "`supportedCategories` | array | List of category objects", + columns: [ + "supportedCategories", + "array", + "List of category objects", + ], + }, + TableRow { + raw: "`url` | string | URL of the torrent site", + columns: [ + "url", + "string", + "URL of the torrent site", + ], + }, + TableRow { + raw: "`version` | string | Installed version of the plugin", + columns: [ + "version", + "string", + "Installed version of the plugin", + ], + }, + ], + }, + ), + Text( + "", + ), + Text( + "```JSON", + ), + Text( + "[", + ), + Text( + " {", + ), + Text( + " \"enabled\": true,", + ), + Text( + " \"fullName\": \"Legit Torrents\",", + ), + Text( + " \"name\": \"legittorrents\",", + ), + Text( + " \"supportedCategories\": [{", + ), + Text( + " \"id\": \"all\",", + ), + Text( + " \"name\": \"All categories\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"anime\",", + ), + Text( + " \"name\": \"Anime\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"books\",", + ), + Text( + " \"name\": \"Books\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"games\",", + ), + Text( + " \"name\": \"Games\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"movies\",", + ), + Text( + " \"name\": \"Movies\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"music\",", + ), + Text( + " \"name\": \"Music\"", + ), + Text( + " }, {", + ), + Text( + " \"id\": \"tv\",", + ), + Text( + " \"name\": \"TV shows\"", + ), + Text( + " }],", + ), + Text( + " \"url\": \"http://www.legittorrents.info\",", + ), + Text( + " \"version\": \"2.3\"", + ), + Text( + " }", + ), + Text( + "]", + ), + Text( + "```", + ), + Text( + "", + ), + Asterisk( + "Category object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "---------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | string | Id", + columns: [ + "id", + "string", + "Id", + ], + }, + TableRow { + raw: "`name` | string | Name", + columns: [ + "name", + "string", + "Name", + ], + }, + ], + }, + ), + ], + children: [], + }, + ], +} \ No newline at end of file diff --git a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check index 44fc18c..fc24550 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check +++ b/qbittorrent-web-api-gen/src/parser/group/method/method_tests/search_result.check @@ -133,7 +133,9 @@ ApiMethod { is_optional: false, is_list: true, }, - ref_type: "", + ref_type: String( + "Result", + ), }, ), String( diff --git a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs index 6788151..7d53d47 100644 --- a/qbittorrent-web-api-gen/src/parser/group/method/mod.rs +++ b/qbittorrent-web-api-gen/src/parser/group/method/mod.rs @@ -422,4 +422,9 @@ mod tests { fn array_field() { run_test!("array_field"); } + + #[test] + fn ref_type() { + run_test!("ref_type"); + } } diff --git a/qbittorrent-web-api-gen/src/types.rs b/qbittorrent-web-api-gen/src/types.rs index 565dcc1..d2b70ef 100644 --- a/qbittorrent-web-api-gen/src/types.rs +++ b/qbittorrent-web-api-gen/src/types.rs @@ -31,10 +31,16 @@ impl TypeInfo { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum RefType { + String(String), + Map(String, String), +} + #[derive(Debug, Clone)] pub struct Object { pub type_info: TypeInfo, - pub ref_type: String, + pub ref_type: RefType, } #[derive(Debug, Clone)] @@ -63,17 +69,6 @@ pub enum Type { } impl Type { - pub fn to_owned_type(&self) -> String { - match self { - Type::Number(_) => "i128".into(), - Type::Float(_) => "f32".into(), - Type::Bool(_) => "bool".into(), - Type::String(_) => "String".into(), - Type::StringArray(_) => "String".into(), - Type::Object(_) => "String".into(), - } - } - pub fn to_borrowed_type(&self) -> String { match self { Type::Number(_) => "i32".into(), @@ -81,7 +76,7 @@ impl Type { Type::Bool(_) => "bool".into(), Type::String(_) => "str".into(), Type::StringArray(_) => "&[str]".into(), - Type::Object(_) => "str".into(), + Type::Object(_) => todo!(), } } @@ -136,10 +131,10 @@ impl Type { ) }; - let create_object_type = |name: &str| { + let create_object_type = |ref_type: RefType| { Some(Type::Object(Object { type_info: create_type_info(), - ref_type: name.to_camel(), + ref_type, })) }; @@ -150,30 +145,85 @@ impl Type { "string" => Some(Type::String(create_type_info())), "array" => description .extract_type() - .and_then(|t| create_object_type(&t)) + .and_then(create_object_type) .or_else(|| Some(Type::StringArray(create_type_info()))), "float" => Some(Type::Float(create_type_info())), - name => create_object_type(name), + name => description + .extract_type() + .and_then(create_object_type) + .or_else(|| { + let n = if name.is_empty() { + "String".into() + } else { + name.into() + }; + + create_object_type(RefType::String(n)) + }), } } } trait ExtractType { - fn extract_type(&self) -> Option; + fn extract_type(&self) -> Option; } impl ExtractType for Option { - fn extract_type(&self) -> Option { - self.as_ref().and_then(|t| { - let re = RegexBuilder::new(r".*Array of (\w+) objects.*") - .case_insensitive(true) - .build() - .unwrap(); + fn extract_type(&self) -> Option { + let list_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"(?:Array|List) of (\w+) objects") + .case_insensitive(true) + .build() + .unwrap(); - let cap = re.captures(t)?; + let cap = re.captures(t)?; - cap.get(1).map(|m| m.as_str().to_camel()) - }) + cap.get(1) + .map(|m| m.as_str().to_camel()) + .map(RefType::String) + }) + }; + + let map_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"map from (\w+) to (\w+) object") + .case_insensitive(true) + .build() + .unwrap(); + + let cap = re.captures(t)?; + let key_type = match cap.get(1).map(|m| m.as_str().to_camel()) { + Some(k) => k, + None => return None, + }; + let value_type = match cap.get(2).map(|m| m.as_str().to_camel()) { + Some(v) => v, + None => return None, + }; + + Some(RefType::Map(key_type, value_type)) + }) + }; + + let object_type = || { + self.as_ref().and_then(|t| { + let re = RegexBuilder::new(r"(\w+) object see table below") + .case_insensitive(true) + .build() + .unwrap(); + + let cap = re.captures(t)?; + let object_type = match cap.get(1).map(|m| m.as_str().to_camel()) { + Some(k) => k, + None => return None, + }; + + Some(RefType::String(object_type)) + }) + }; + + list_type().or_else(map_type).or_else(object_type) } } @@ -185,6 +235,6 @@ mod tests { fn test_regex() { let input = Some("Array of result objects- see table below".to_string()); let res = input.extract_type(); - assert_eq!(res.unwrap(), "Result"); + assert_eq!(res.unwrap(), RefType::String("Result".into())); } } diff --git a/qbittorrent-web-api-gen/token_tree.txt b/qbittorrent-web-api-gen/token_tree.txt index 46c7841..0e4a9f3 100644 --- a/qbittorrent-web-api-gen/token_tree.txt +++ b/qbittorrent-web-api-gen/token_tree.txt @@ -4497,17 +4497,17 @@ TokenTree { Table( Table { header: TableRow { - raw: "Property | Type | Description", + raw: "Property | Type | Description", columns: [ "Property", "Type", "Description", ], }, - split: "------------------------------|---------|------------", + split: "--------------------------------|-----------|------------", rows: [ TableRow { - raw: "`rid` | integer | Response ID", + raw: "`rid` | integer | Response ID", columns: [ "rid", "integer", @@ -4515,67 +4515,67 @@ TokenTree { ], }, TableRow { - raw: "`full_update` | bool | Whether the response contains all the data or partial data", + raw: "`full_update`_optional_ | bool | Whether the response contains all the data or partial data", columns: [ - "full_update", + "full_update_optional_", "bool", "Whether the response contains all the data or partial data", ], }, TableRow { - raw: "`torrents` | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list)", + raw: "`torrents`_optional_ | object | Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", columns: [ - "torrents", + "torrents_optional_", "object", - "Property: torrent hash, value: same as [torrent list](#get-torrent-list)", + "Property: torrent hash, value: same as [torrent list](#get-torrent-list), map from string to torrents object", ], }, TableRow { - raw: "`torrents_removed` | array | List of hashes of torrents removed since last request", + raw: "`torrents_removed`_optional_ | array | List of hashes of torrents removed since last request", columns: [ - "torrents_removed", + "torrents_removed_optional_", "array", "List of hashes of torrents removed since last request", ], }, TableRow { - raw: "`categories` | object | Info for categories added since last request", + raw: "`categories`_optional_ | object | Info for categories added since last request, map from string to categories object", columns: [ - "categories", + "categories_optional_", "object", - "Info for categories added since last request", + "Info for categories added since last request, map from string to categories object", ], }, TableRow { - raw: "`categories_removed` | array | List of categories removed since last request", + raw: "`categories_removed`_optional_ | array | List of categories removed since last request", columns: [ - "categories_removed", + "categories_removed_optional_", "array", "List of categories removed since last request", ], }, TableRow { - raw: "`tags` | array | List of tags added since last request", + raw: "`tags`_optional_ | array | List of tags added since last request", columns: [ - "tags", + "tags_optional_", "array", "List of tags added since last request", ], }, TableRow { - raw: "`tags_removed` | array | List of tags removed since last request", + raw: "`tags_removed`_optional_ | array | List of tags removed since last request", columns: [ - "tags_removed", + "tags_removed_optional_", "array", "List of tags removed since last request", ], }, TableRow { - raw: "`server_state` | object | Global transfer info", + raw: "`server_state`_optional_ | object | `server_state` object see table below", columns: [ - "server_state", + "server_state_optional_", "object", - "Global transfer info", + "server_state object see table below", ], }, ], @@ -4629,6 +4629,502 @@ TokenTree { Text( "", ), + Asterisk( + "ServerState object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`average_time_queue` | integer | Average time queue", + columns: [ + "average_time_queue", + "integer", + "Average time queue", + ], + }, + TableRow { + raw: "`dl_info_data` | number | Download info data", + columns: [ + "dl_info_data", + "number", + "Download info data", + ], + }, + TableRow { + raw: "`dl_info_speed` | number | Download info speed", + columns: [ + "dl_info_speed", + "number", + "Download info speed", + ], + }, + TableRow { + raw: "`queued_io_jobs` | integer | Queued io jobs", + columns: [ + "queued_io_jobs", + "integer", + "Queued io jobs", + ], + }, + TableRow { + raw: "`total_buffers_size` | number | Total buffers size", + columns: [ + "total_buffers_size", + "number", + "Total buffers size", + ], + }, + TableRow { + raw: "`total_peer_connections` | integer | Total peer connections", + columns: [ + "total_peer_connections", + "integer", + "Total peer connections", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Categories object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "------------------------------|---------|------------", + rows: [ + TableRow { + raw: "`name` | string | Category name", + columns: [ + "name", + "string", + "Category name", + ], + }, + TableRow { + raw: "`savePath` | string | Save path", + columns: [ + "savePath", + "string", + "Save path", + ], + }, + ], + }, + ), + Text( + "", + ), + Asterisk( + "Torrents object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Property | Type | Description", + columns: [ + "Property", + "Type", + "Description", + ], + }, + split: "--------------------------------|-----------|------------", + rows: [ + TableRow { + raw: "`added_on`_optional_ | integer | Time (Unix Epoch) when the torrent was added to the client", + columns: [ + "added_on_optional_", + "integer", + "Time (Unix Epoch) when the torrent was added to the client", + ], + }, + TableRow { + raw: "`amount_left`_optional_ | integer | Amount of data left to download (bytes)", + columns: [ + "amount_left_optional_", + "integer", + "Amount of data left to download (bytes)", + ], + }, + TableRow { + raw: "`auto_tmm`_optional_ | bool | Whether this torrent is managed by Automatic Torrent Management", + columns: [ + "auto_tmm_optional_", + "bool", + "Whether this torrent is managed by Automatic Torrent Management", + ], + }, + TableRow { + raw: "`availability`_optional_ | float | Percentage of file pieces currently available", + columns: [ + "availability_optional_", + "float", + "Percentage of file pieces currently available", + ], + }, + TableRow { + raw: "`category`_optional_ | string | Category of the torrent", + columns: [ + "category_optional_", + "string", + "Category of the torrent", + ], + }, + TableRow { + raw: "`completed`_optional_ | integer | Amount of transfer data completed (bytes)", + columns: [ + "completed_optional_", + "integer", + "Amount of transfer data completed (bytes)", + ], + }, + TableRow { + raw: "`completion_on`_optional_ | integer | Time (Unix Epoch) when the torrent completed", + columns: [ + "completion_on_optional_", + "integer", + "Time (Unix Epoch) when the torrent completed", + ], + }, + TableRow { + raw: "`content_path`_optional_ | string | Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + columns: [ + "content_path_optional_", + "string", + "Absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents)", + ], + }, + TableRow { + raw: "`dl_limit`_optional_ | integer | Torrent download speed limit (bytes/s). `-1` if ulimited.", + columns: [ + "dl_limit_optional_", + "integer", + "Torrent download speed limit (bytes/s). -1 if ulimited.", + ], + }, + TableRow { + raw: "`dlspeed`_optional_ | integer | Torrent download speed (bytes/s)", + columns: [ + "dlspeed_optional_", + "integer", + "Torrent download speed (bytes/s)", + ], + }, + TableRow { + raw: "`downloaded`_optional_ | integer | Amount of data downloaded", + columns: [ + "downloaded_optional_", + "integer", + "Amount of data downloaded", + ], + }, + TableRow { + raw: "`downloaded_session`_optional_ | integer | Amount of data downloaded this session", + columns: [ + "downloaded_session_optional_", + "integer", + "Amount of data downloaded this session", + ], + }, + TableRow { + raw: "`eta`_optional_ | integer | Torrent ETA (seconds)", + columns: [ + "eta_optional_", + "integer", + "Torrent ETA (seconds)", + ], + }, + TableRow { + raw: "`f_l_piece_prio`_optional_ | bool | True if first last piece are prioritized", + columns: [ + "f_l_piece_prio_optional_", + "bool", + "True if first last piece are prioritized", + ], + }, + TableRow { + raw: "`force_start`_optional_ | bool | True if force start is enabled for this torrent", + columns: [ + "force_start_optional_", + "bool", + "True if force start is enabled for this torrent", + ], + }, + TableRow { + raw: "`hash`_optional_ | string | Torrent hash", + columns: [ + "hash_optional_", + "string", + "Torrent hash", + ], + }, + TableRow { + raw: "`last_activity`_optional_ | integer | Last time (Unix Epoch) when a chunk was downloaded/uploaded", + columns: [ + "last_activity_optional_", + "integer", + "Last time (Unix Epoch) when a chunk was downloaded/uploaded", + ], + }, + TableRow { + raw: "`magnet_uri`_optional_ | string | Magnet URI corresponding to this torrent", + columns: [ + "magnet_uri_optional_", + "string", + "Magnet URI corresponding to this torrent", + ], + }, + TableRow { + raw: "`max_ratio`_optional_ | float | Maximum share ratio until torrent is stopped from seeding/uploading", + columns: [ + "max_ratio_optional_", + "float", + "Maximum share ratio until torrent is stopped from seeding/uploading", + ], + }, + TableRow { + raw: "`max_seeding_time`_optional_ | integer | Maximum seeding time (seconds) until torrent is stopped from seeding", + columns: [ + "max_seeding_time_optional_", + "integer", + "Maximum seeding time (seconds) until torrent is stopped from seeding", + ], + }, + TableRow { + raw: "`name`_optional_ | string | Torrent name", + columns: [ + "name_optional_", + "string", + "Torrent name", + ], + }, + TableRow { + raw: "`num_complete`_optional_ | integer | Number of seeds in the swarm", + columns: [ + "num_complete_optional_", + "integer", + "Number of seeds in the swarm", + ], + }, + TableRow { + raw: "`num_incomplete`_optional_ | integer | Number of leechers in the swarm", + columns: [ + "num_incomplete_optional_", + "integer", + "Number of leechers in the swarm", + ], + }, + TableRow { + raw: "`num_leechs`_optional_ | integer | Number of leechers connected to", + columns: [ + "num_leechs_optional_", + "integer", + "Number of leechers connected to", + ], + }, + TableRow { + raw: "`num_seeds`_optional_ | integer | Number of seeds connected to", + columns: [ + "num_seeds_optional_", + "integer", + "Number of seeds connected to", + ], + }, + TableRow { + raw: "`priority`_optional_ | integer | Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + columns: [ + "priority_optional_", + "integer", + "Torrent priority. Returns -1 if queuing is disabled or torrent is in seed mode", + ], + }, + TableRow { + raw: "`progress`_optional_ | float | Torrent progress (percentage/100)", + columns: [ + "progress_optional_", + "float", + "Torrent progress (percentage/100)", + ], + }, + TableRow { + raw: "`ratio`_optional_ | float | Torrent share ratio. Max ratio value: 9999.", + columns: [ + "ratio_optional_", + "float", + "Torrent share ratio. Max ratio value: 9999.", + ], + }, + TableRow { + raw: "`ratio_limit`_optional_ | float | TODO (what is different from `max_ratio`?)", + columns: [ + "ratio_limit_optional_", + "float", + "TODO (what is different from max_ratio?)", + ], + }, + TableRow { + raw: "`save_path`_optional_ | string | Path where this torrent's data is stored", + columns: [ + "save_path_optional_", + "string", + "Path where this torrent's data is stored", + ], + }, + TableRow { + raw: "`seeding_time`_optional_ | integer | Torrent elapsed time while complete (seconds)", + columns: [ + "seeding_time_optional_", + "integer", + "Torrent elapsed time while complete (seconds)", + ], + }, + TableRow { + raw: "`seeding_time_limit`_optional_ | integer | TODO (what is different from `max_seeding_time`?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + columns: [ + "seeding_time_limit_optional_", + "integer", + "TODO (what is different from max_seeding_time?) seeding_time_limit is a per torrent setting, when Automatic Torrent Management is disabled, furthermore then max_seeding_time is set to seeding_time_limit for this torrent. If Automatic Torrent Management is enabled, the value is -2. And if max_seeding_time is unset it have a default value -1.", + ], + }, + TableRow { + raw: "`seen_complete`_optional_ | integer | Time (Unix Epoch) when this torrent was last seen complete", + columns: [ + "seen_complete_optional_", + "integer", + "Time (Unix Epoch) when this torrent was last seen complete", + ], + }, + TableRow { + raw: "`seq_dl`_optional_ | bool | True if sequential download is enabled", + columns: [ + "seq_dl_optional_", + "bool", + "True if sequential download is enabled", + ], + }, + TableRow { + raw: "`size`_optional_ | integer | Total size (bytes) of files selected for download", + columns: [ + "size_optional_", + "integer", + "Total size (bytes) of files selected for download", + ], + }, + TableRow { + raw: "`state`_optional_ | string | Torrent state. See table here below for the possible values", + columns: [ + "state_optional_", + "string", + "Torrent state. See table here below for the possible values", + ], + }, + TableRow { + raw: "`super_seeding`_optional_ | bool | True if super seeding is enabled", + columns: [ + "super_seeding_optional_", + "bool", + "True if super seeding is enabled", + ], + }, + TableRow { + raw: "`tags`_optional_ | string | Comma-concatenated tag list of the torrent", + columns: [ + "tags_optional_", + "string", + "Comma-concatenated tag list of the torrent", + ], + }, + TableRow { + raw: "`time_active`_optional_ | integer | Total active time (seconds)", + columns: [ + "time_active_optional_", + "integer", + "Total active time (seconds)", + ], + }, + TableRow { + raw: "`total_size`_optional_ | integer | Total size (bytes) of all file in this torrent (including unselected ones)", + columns: [ + "total_size_optional_", + "integer", + "Total size (bytes) of all file in this torrent (including unselected ones)", + ], + }, + TableRow { + raw: "`tracker`_optional_ | string | The first tracker with working status. Returns empty string if no tracker is working.", + columns: [ + "tracker_optional_", + "string", + "The first tracker with working status. Returns empty string if no tracker is working.", + ], + }, + TableRow { + raw: "`up_limit`_optional_ | integer | Torrent upload speed limit (bytes/s). `-1` if ulimited.", + columns: [ + "up_limit_optional_", + "integer", + "Torrent upload speed limit (bytes/s). -1 if ulimited.", + ], + }, + TableRow { + raw: "`uploaded`_optional_ | integer | Amount of data uploaded", + columns: [ + "uploaded_optional_", + "integer", + "Amount of data uploaded", + ], + }, + TableRow { + raw: "`uploaded_session`_optional_ | integer | Amount of data uploaded this session", + columns: [ + "uploaded_session_optional_", + "integer", + "Amount of data uploaded this session", + ], + }, + TableRow { + raw: "`upspeed`_optional_ | integer | Torrent upload speed (bytes/s)", + columns: [ + "upspeed_optional_", + "integer", + "Torrent upload speed (bytes/s)", + ], + }, + ], + }, + ), + Text( + "", + ), ], children: [], }, @@ -8171,9 +8667,10 @@ TokenTree { ], }, TableRow { - raw: "`deleteFiles` | If set to `true`, the downloaded data will also be deleted, otherwise has no effect.", + raw: "`deleteFiles` | bool | If set to `true`, the downloaded data will also be deleted, otherwise has no effect.", columns: [ "deleteFiles", + "bool", "If set to true, the downloaded data will also be deleted, otherwise has no effect.", ], }, @@ -14637,6 +15134,46 @@ TokenTree { Text( "", ), + Asterisk( + "Category object:", + ), + Text( + "", + ), + Table( + Table { + header: TableRow { + raw: "Field | Type | Description", + columns: [ + "Field", + "Type", + "Description", + ], + }, + split: "---------------------------|---------|------------", + rows: [ + TableRow { + raw: "`id` | string | Id", + columns: [ + "id", + "string", + "Id", + ], + }, + TableRow { + raw: "`name` | string | Name", + columns: [ + "name", + "string", + "Name", + ], + }, + ], + }, + ), + Text( + "", + ), ], children: [], },