54: Raw response r=jowax a=jowax



Co-authored-by: Joel Wachsler <JoelWachsler@users.noreply.github.com>
This commit is contained in:
bors[bot] 2022-08-06 17:08:49 +00:00 committed by GitHub
commit 9daf1b4bb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 180 additions and 67 deletions

13
Cargo.lock generated
View File

@ -597,6 +597,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr",
"thiserror", "thiserror",
"tokio", "tokio",
] ]
@ -614,6 +615,7 @@ dependencies = [
"reqwest", "reqwest",
"serde", "serde",
"serde_json", "serde_json",
"serde_repr",
"syn", "syn",
"thiserror", "thiserror",
"tokio", "tokio",
@ -778,6 +780,17 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serde_repr"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "serde_urlencoded" name = "serde_urlencoded"
version = "0.7.1" version = "0.7.1"

View File

@ -13,6 +13,7 @@ tokio = { version = "1.19.2", features = ["full"] }
qbittorrent-web-api-gen = { path = "./qbittorrent-web-api-gen", version = "0.6.0" } qbittorrent-web-api-gen = { path = "./qbittorrent-web-api-gen", version = "0.6.0" }
serde = { version = "1.0.138", features = ["derive"] } serde = { version = "1.0.138", features = ["derive"] }
serde_json = "1.0.82" serde_json = "1.0.82"
serde_repr = "0.1.9"
thiserror = "1.0.31" thiserror = "1.0.31"
[workspace] [workspace]

View File

@ -32,6 +32,7 @@ case = "1.0.0"
thiserror = "1.0.31" thiserror = "1.0.31"
serde = { version = "1.0.138", features = ["derive"] } serde = { version = "1.0.138", features = ["derive"] }
serde_json = "1.0.82" serde_json = "1.0.82"
serde_repr = "0.1.9"
regex = "1.6.0" regex = "1.6.0"
[dev-dependencies] [dev-dependencies]

View File

@ -1667,7 +1667,7 @@ Possible values of `priority`:
Value | Description Value | Description
-----------|------------ -----------|------------
`0` | Do not download `0` | Do not download
`1` | Normal priority `4` | Normal priority
`6` | High priority `6` | High priority
`7` | Maximal priority `7` | Maximal priority
@ -2181,7 +2181,7 @@ Possible values of `priority`:
Value | Description Value | Description
-----------|------------ -----------|------------
`0` | Do not download `0` | Do not download
`1` | Normal priority `4` | Normal priority
`6` | High priority `6` | High priority
`7` | Maximal priority `7` | Maximal priority

View File

@ -4426,7 +4426,7 @@
"Normal priority", "Normal priority",
), ),
value: "NormalPriority", value: "NormalPriority",
original_value: "1", original_value: "4",
}, },
EnumValue { EnumValue {
description: Some( description: Some(
@ -5247,7 +5247,7 @@
"Normal priority", "Normal priority",
), ),
value: "NormalPriority", value: "NormalPriority",
original_value: "1", original_value: "4",
}, },
EnumValue { EnumValue {
description: Some( description: Some(

View File

@ -111,11 +111,22 @@ impl<'a> GroupGeneration<'a> {
} }
pub fn struct_derives(&self) -> TokenStream { pub fn struct_derives(&self) -> TokenStream {
self.derives(self.struct_derives, &[]) self.derives(
self.struct_derives,
&["serde::Deserialize", "serde::Serialize"],
)
} }
pub fn enum_derives(&self) -> TokenStream { pub fn enum_derives(&self) -> TokenStream {
self.derives(self.enum_derives, &["PartialEq", "Eq"]) self.derives(
self.enum_derives,
&[
"PartialEq",
"Eq",
"serde_repr::Deserialize_repr",
"serde_repr::Serialize_repr",
],
)
} }
pub fn derives(&self, derives: &'a [&'a str], additional_derives: &[&str]) -> TokenStream { pub fn derives(&self, derives: &'a [&'a str], additional_derives: &[&str]) -> TokenStream {
@ -131,13 +142,8 @@ impl<'a> GroupGeneration<'a> {
} }
fn all_derives(&self, derives: &'a [&'a str]) -> impl Iterator<Item = &'a str> { fn all_derives(&self, derives: &'a [&'a str]) -> impl Iterator<Item = &'a str> {
let base = vec!["serde::Deserialize", "serde::Serialize", "Debug"].into_iter(); let base = vec!["Debug"].into_iter();
let additional = derives let additional = derives.iter().copied().filter(|item| item != &"Debug");
.iter()
.copied()
.filter(|item| item != &"serde::Deserialize")
.filter(|item| item != &"serde::Serialize")
.filter(|item| item != &"Debug");
base.chain(additional) base.chain(additional)
} }

View File

@ -143,6 +143,7 @@ impl<'a> EnumGeneration<'a> {
quote! { quote! {
#[allow(clippy::enum_variant_names)] #[allow(clippy::enum_variant_names)]
#derives #derives
#[repr(i8)]
pub enum #name { pub enum #name {
#(#values,)* #(#values,)*
} }
@ -160,11 +161,15 @@ impl parser::EnumValue {
// special enum value which does not follow conventions // special enum value which does not follow conventions
if orig_name == "\"/path/to/download/to\"" { if orig_name == "\"/path/to/download/to\"" {
quote! { // don't know how to handle this one
PathToDownloadTo(String) // quote! { PathToDownloadTo(String) }
} return quote! { PathToDownloadTo = -1 };
} else { };
let name_camel = self.name_camel(); let name_camel = self.name_camel();
if let Ok(v) = orig_name.parse::<i8>() {
quote! { #name_camel = #v }
} else {
quote! { quote! {
#[serde(rename = #orig_name)] #[serde(rename = #orig_name)]
#name_camel #name_camel

View File

@ -75,16 +75,15 @@ impl<'a> GroupMethod<'a> {
let form_builder = self.mandatory_parameters_as_form_builder(); let form_builder = self.mandatory_parameters_as_form_builder();
let method_impl = if self.method.types.optional_parameters().is_empty() { let method_impl = if self.method.types.optional_parameters().is_empty() {
self.generate_send_method( let builder =
&method_name, SendMethodBuilder::new(&method_name, quote! { self.auth }, quote! { form })
parameters, .set_parameters(parameters)
quote! { self.auth }, .set_form_factory(quote! {
quote! { form },
quote! {
let form = reqwest::multipart::Form::new(); let form = reqwest::multipart::Form::new();
#form_builder #form_builder
}, });
)
self.generate_send_method(builder)
} else { } else {
quote! { quote! {
pub fn #method_name(&self, #(#parameters),*) -> Builder<'_> { pub fn #method_name(&self, #(#parameters),*) -> Builder<'_> {
@ -139,13 +138,11 @@ impl<'a> GroupMethod<'a> {
.map(|param| param.generate_optional_builder_method_with_docs()); .map(|param| param.generate_optional_builder_method_with_docs());
let group_name = self.group.struct_name(); let group_name = self.group.struct_name();
let send_method = self.generate_send_method( let send_method = self.generate_send_method(SendMethodBuilder::new(
&util::to_ident("send"), &util::to_ident("send"),
vec![],
quote! { self.group.auth }, quote! { self.group.auth },
quote! { self.form }, quote! { self.form },
quote! {}, ));
);
quote! { quote! {
pub struct Builder<'a> { pub struct Builder<'a> {
@ -160,29 +157,70 @@ impl<'a> GroupMethod<'a> {
} }
} }
fn generate_send_method( fn generate_send_method(&self, builder: SendMethodBuilder) -> TokenStream {
&self, let builder = builder.set_group(self);
method_name: &Ident, let send_method = builder.generate_send_method();
let send_method_raw = builder
.set_override_return_type(quote! { String })
.append_to_method_name("_raw")
.generate_send_method();
let send_method_raw_with_docs = util::add_docs(
&Some("Returns the raw response of the request.".into()),
send_method_raw,
);
quote! {
#send_method
#send_method_raw_with_docs
}
}
fn mandatory_parameters_as_form_builder(&self) -> TokenStream {
let builder = self
.method
.types
.mandatory_params()
.into_iter()
.map(|param| param.generate_form_builder(quote! { form }));
quote! {
#(let #builder)*
}
}
}
pub struct SendMethodBuilder<'a> {
group: Option<&'a GroupMethod<'a>>,
method_name: Ident,
parameters: Vec<TokenStream>, parameters: Vec<TokenStream>,
auth_access: TokenStream, auth_access: TokenStream,
form_access: TokenStream, form_access: TokenStream,
form_factory: TokenStream, form_factory: Option<TokenStream>,
) -> TokenStream { override_return_type: Option<TokenStream>,
let method_url = format!("/api/v2/{}/{}", self.group.url(), self.method.url); }
let (response_type, response_parse) = match self.method.types.response() { impl<'a> SendMethodBuilder<'a> {
Some(resp) => { pub fn new(method_name: &'a Ident, auth_access: TokenStream, form_access: TokenStream) -> Self {
if resp.is_list { Self {
( group: Option::None,
quote! { std::vec::Vec<Response> }, method_name: method_name.clone(),
quote! { .json::<std::vec::Vec<Response>>() }, parameters: vec![],
) auth_access,
} else { form_access,
(quote! { Response }, quote! { .json::<Response>() }) form_factory: Option::None,
override_return_type: Option::None,
} }
} }
None => (quote! { String }, quote! { .text() }),
}; fn generate_send_method(&self) -> TokenStream {
let method_url = self.method_url();
let (response_type, response_parse) = self.return_type();
let form_factory = self.form_factory();
let parameters = self.parameters.clone();
let form_access = self.form_access.clone();
let method_name = self.method_name.clone();
let auth_access = self.auth_access.clone();
quote! { quote! {
pub async fn #method_name(self, #(#parameters),*) -> super::super::Result<#response_type> { pub async fn #method_name(self, #(#parameters),*) -> super::super::Result<#response_type> {
@ -200,16 +238,65 @@ impl<'a> GroupMethod<'a> {
} }
} }
fn mandatory_parameters_as_form_builder(&self) -> TokenStream { fn return_type(&self) -> (TokenStream, TokenStream) {
let builder = self if let Some(override_return_type) = self.override_return_type.clone() {
.method (override_return_type, quote! { .text() })
.types } else {
.mandatory_params() match self.group().method.types.response() {
.into_iter() Some(resp) => {
.map(|param| param.generate_form_builder(quote! { form })); if resp.is_list {
(
quote! { quote! { std::vec::Vec<Response> },
#(let #builder)* quote! { .json::<std::vec::Vec<Response>>() },
)
} else {
(quote! { Response }, quote! { .json::<Response>() })
} }
} }
None => (quote! { String }, quote! { .text() }),
}
}
}
fn method_url(&self) -> String {
format!(
"/api/v2/{}/{}",
self.group().group.url(),
self.group().method.url
)
}
fn set_override_return_type(mut self, override_return_type: TokenStream) -> Self {
self.override_return_type = Some(override_return_type);
self
}
fn set_form_factory(mut self, form_factory: TokenStream) -> Self {
self.form_factory = Some(form_factory);
self
}
fn form_factory(&self) -> TokenStream {
self.form_factory.clone().unwrap_or_else(|| quote! {})
}
fn set_parameters(mut self, parameters: Vec<TokenStream>) -> Self {
self.parameters = parameters;
self
}
fn append_to_method_name(mut self, append: &str) -> Self {
let new_name = util::to_ident(&format!("{}{}", self.method_name, append));
self.method_name = new_name;
self
}
fn set_group(mut self, group: &'a GroupMethod<'a>) -> Self {
self.group = Option::Some(group);
self
}
fn group(&self) -> &GroupMethod {
self.group.expect("Group is not defined")
}
} }

View File

@ -8007,9 +8007,9 @@ TokenTree {
], ],
}, },
TableRow { TableRow {
raw: "`1` | Normal priority", raw: "`4` | Normal priority",
columns: [ columns: [
"1", "4",
"Normal priority", "Normal priority",
], ],
}, },
@ -10269,9 +10269,9 @@ TokenTree {
], ],
}, },
TableRow { TableRow {
raw: "`1` | Normal priority", raw: "`4` | Normal priority",
columns: [ columns: [
"1", "4",
"Normal priority", "Normal priority",
], ],
}, },