Skip to content

Commit bde0d77

Browse files
authored
[Rust][reqwest] add async support (#6464)
* fix rust sync client * update doc
1 parent f7f4141 commit bde0d77

File tree

51 files changed

+1860
-63
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1860
-63
lines changed

bin/rust-petstore-reqwest-async.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/sh
2+
3+
SCRIPT="$0"
4+
echo "# START SCRIPT: $SCRIPT"
5+
6+
while [ -h "$SCRIPT" ] ; do
7+
ls=`ls -ld "$SCRIPT"`
8+
link=`expr "$ls" : '.*-> \(.*\)$'`
9+
if expr "$link" : '/.*' > /dev/null; then
10+
SCRIPT="$link"
11+
else
12+
SCRIPT=`dirname "$SCRIPT"`/"$link"
13+
fi
14+
done
15+
16+
if [ ! -d "${APP_DIR}" ]; then
17+
APP_DIR=`dirname "$SCRIPT"`/..
18+
APP_DIR=`cd "${APP_DIR}"; pwd`
19+
fi
20+
21+
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
22+
23+
if [ ! -f "$executable" ]
24+
then
25+
mvn -B clean package
26+
fi
27+
28+
# if you've executed sbt assembly previously it will use that instead.
29+
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties $@"
30+
ags="generate -t modules/openapi-generator/src/main/resources/rust -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g rust --library reqwest -o samples/client/petstore/rust/reqwest/petstore-async --additional-properties supportAsync=true,packageName=petstore-reqwest-async $@"
31+
32+
java $JAVA_OPTS -jar $executable $ags

docs/generators/rust.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ sidebar_label: rust
99
|library|library template (sub-template) to use.|<dl><dt>**hyper**</dt><dd>HTTP client: Hyper.</dd><dt>**reqwest**</dt><dd>HTTP client: Reqwest.</dd></dl>|hyper|
1010
|packageName|Rust package name (convention: lowercase).| |openapi|
1111
|packageVersion|Rust package version.| |1.0.0|
12+
|supportAsync|If set, generate async function call instead| |false|
1213
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|
1314

1415
## IMPORT MAPPING

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustClientCodegen.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,13 @@
3939
public class RustClientCodegen extends DefaultCodegen implements CodegenConfig {
4040
private static final Logger LOGGER = LoggerFactory.getLogger(RustClientCodegen.class);
4141
private boolean useSingleRequestParameter = false;
42+
private boolean supportAsync = false;
4243

4344
public static final String PACKAGE_NAME = "packageName";
4445
public static final String PACKAGE_VERSION = "packageVersion";
45-
4646
public static final String HYPER_LIBRARY = "hyper";
4747
public static final String REQWEST_LIBRARY = "reqwest";
48+
public static final String SUPPORT_ASYNC = "supportAsync";
4849

4950
protected String packageName = "openapi";
5051
protected String packageVersion = "1.0.0";
@@ -172,6 +173,8 @@ public RustClientCodegen() {
172173
.defaultValue(Boolean.TRUE.toString()));
173174
cliOptions.add(new CliOption(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, CodegenConstants.USE_SINGLE_REQUEST_PARAMETER_DESC, SchemaTypeUtil.BOOLEAN_TYPE)
174175
.defaultValue(Boolean.FALSE.toString()));
176+
cliOptions.add(new CliOption(SUPPORT_ASYNC, "If set, generate async function call instead", SchemaTypeUtil.BOOLEAN_TYPE)
177+
.defaultValue(Boolean.FALSE.toString()));
175178

176179
supportedLibraries.put(HYPER_LIBRARY, "HTTP client: Hyper.");
177180
supportedLibraries.put(REQWEST_LIBRARY, "HTTP client: Reqwest.");
@@ -257,6 +260,11 @@ public void processOpts() {
257260
}
258261
writePropertyBack(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, getUseSingleRequestParameter());
259262

263+
if (additionalProperties.containsKey(SUPPORT_ASYNC)) {
264+
this.setSupportAsync(convertPropertyToBoolean(SUPPORT_ASYNC));
265+
}
266+
writePropertyBack(SUPPORT_ASYNC, getSupportAsync());
267+
260268
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
261269
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
262270

@@ -284,13 +292,22 @@ public void processOpts() {
284292
supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs"));
285293
supportingFiles.add(new SupportingFile("Cargo.mustache", "", "Cargo.toml"));
286294

295+
supportingFiles.add(new SupportingFile(getLibrary() + "/api_mod.mustache", apiFolder, "mod.rs"));
296+
supportingFiles.add(new SupportingFile(getLibrary() + "/configuration.mustache", apiFolder, "configuration.rs"));
287297
if (HYPER_LIBRARY.equals(getLibrary())) {
288298
supportingFiles.add(new SupportingFile("request.rs", apiFolder, "request.rs"));
289299
}
300+
if (!getSupportAsync()) { // for sync only
301+
supportingFiles.add(new SupportingFile(getLibrary() + "/client.mustache", apiFolder, "client.rs"));
302+
}
303+
}
290304

291-
supportingFiles.add(new SupportingFile(getLibrary() + "/configuration.mustache", apiFolder, "configuration.rs"));
292-
supportingFiles.add(new SupportingFile(getLibrary() + "/client.mustache", apiFolder, "client.rs"));
293-
supportingFiles.add(new SupportingFile(getLibrary() + "/api_mod.mustache", apiFolder, "mod.rs"));
305+
private boolean getSupportAsync() {
306+
return supportAsync;
307+
}
308+
309+
private void setSupportAsync(boolean supportAsync) {
310+
this.supportAsync = supportAsync;
294311
}
295312

296313
private boolean getUseSingleRequestParameter() {

modules/openapi-generator/src/main/resources/rust/Cargo.mustache

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "{{{packageName}}}"
33
version = "{{{packageVersion}}}"
44
authors = ["OpenAPI Generator team and contributors"]
5+
edition = "2018"
56

67
[dependencies]
78
serde = "^1.0"
@@ -15,7 +16,15 @@ base64 = "~0.7.0"
1516
futures = "0.1.23"
1617
{{/hyper}}
1718
{{#reqwest}}
19+
{{^supportAsync}}
1820
reqwest = "~0.9"
21+
{{/supportAsync}}
22+
{{#supportAsync}}
23+
[dependencies.reqwest]
24+
version = "^0.10"
25+
default-features = false
26+
features = ["json"]
27+
{{/supportAsync}}
1928
{{/reqwest}}
2029

2130
[dev-dependencies]

modules/openapi-generator/src/main/resources/rust/reqwest/api.mustache

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{{>partial_header}}
2+
#[allow(unused_imports)]
23
use std::rc::Rc;
34
use std::borrow::Borrow;
4-
#[allow(unused_imports)]
55
use std::option::Option;
66

77
use reqwest;
88

99
use super::{Error, configuration};
1010

11+
{{^supportAsync}}
1112
pub struct {{{classname}}}Client {
1213
configuration: Rc<configuration::Configuration>,
1314
}
@@ -20,6 +21,7 @@ impl {{{classname}}}Client {
2021
}
2122
}
2223

24+
{{/supportAsync}}
2325
{{#operations}}
2426
{{#operation}}
2527
{{#vendorExtensions.x-group-parameters}}
@@ -42,6 +44,7 @@ pub struct {{{classname}}}{{{operationIdCamelCase}}}Params {
4244
{{/operation}}
4345
{{/operations}}
4446

47+
{{^supportAsync}}
4548
pub trait {{{classname}}} {
4649
{{#operations}}
4750
{{#operation}}
@@ -56,20 +59,23 @@ pub trait {{{classname}}} {
5659
}
5760

5861
impl {{{classname}}} for {{{classname}}}Client {
62+
{{/supportAsync}}
5963
{{#operations}}
6064
{{#operation}}
6165
{{#vendorExtensions.x-group-parameters}}
62-
fn {{{operationId}}}(&self{{#allParams}}{{#-first}}, params: {{{classname}}}{{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> {
66+
{{#supportAsync}}pub async {{/supportAsync}}fn {{{operationId}}}({{^supportAsync}}&self{{/supportAsync}}{{#supportAsync}}configuration: &configuration::Configuration{{/supportAsync}}{{#allParams}}{{#-first}}, params: {{{classname}}}{{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> {
6367
// unbox the parameters
6468
{{#allParams}}
6569
let {{paramName}} = params.{{paramName}};
6670
{{/allParams}}
6771

6872
{{/vendorExtensions.x-group-parameters}}
6973
{{^vendorExtensions.x-group-parameters}}
70-
fn {{{operationId}}}(&self, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}&str{{/isString}}{{#isUuid}}&str{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> {
74+
{{#supportAsync}}pub async {{/supportAsync}}fn {{{operationId}}}({{^supportAsync}}&self{{/supportAsync}}{{#supportAsync}}configuration: &configuration::Configuration{{/supportAsync}}, {{#allParams}}{{{paramName}}}: {{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{#isString}}&str{{/isString}}{{#isUuid}}&str{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}crate::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Result<{{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error> {
7175
{{/vendorExtensions.x-group-parameters}}
76+
{{^supportAsync}}
7277
let configuration: &configuration::Configuration = self.configuration.borrow();
78+
{{/supportAsync}}
7379
let client = &configuration.client;
7480

7581
let uri_str = format!("{}{{{path}}}", configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}crate::apis::urlencode({{/isString}}{{{paramName}}}{{^required}}.unwrap(){{/required}}{{#required}}{{#isNullable}}.unwrap(){{/isNullable}}{{/required}}{{#isListContainer}}.join(",").as_ref(){{/isListContainer}}{{#isString}}){{/isString}}{{/pathParams}});
@@ -162,6 +168,7 @@ impl {{{classname}}} for {{{classname}}}Client {
162168
let mut form = reqwest::multipart::Form::new();
163169
{{#formParams}}
164170
{{#isFile}}
171+
{{^supportAsync}}
165172
{{#required}}
166173
{{^isNullable}}
167174
form = form.file("{{{baseName}}}", {{{paramName}}})?;
@@ -178,6 +185,10 @@ impl {{{classname}}} for {{{classname}}}Client {
178185
form = form.file("{{{baseName}}}", param_value)?;
179186
}
180187
{{/required}}
188+
{{/supportAsync}}
189+
{{#supportAsync}}
190+
// TODO: support file upload for '{{{baseName}}}' parameter
191+
{{/supportAsync}}
181192
{{/isFile}}
182193
{{^isFile}}
183194
{{#required}}
@@ -251,18 +262,23 @@ impl {{{classname}}} for {{{classname}}}Client {
251262
{{/bodyParams}}
252263
{{/hasBodyParam}}
253264

254-
// send request
255265
let req = req_builder.build()?;
256-
257266
{{^returnType}}
258-
client.execute(req)?.error_for_status()?;
267+
client.execute(req){{#supportAsync}}.await{{/supportAsync}}?.error_for_status()?;
259268
Ok(())
260269
{{/returnType}}
261270
{{#returnType}}
271+
{{#supportAsync}}
272+
Ok(client.execute(req).await?.error_for_status()?.json::<{{{.}}}>().await?)
273+
{{/supportAsync}}
274+
{{^supportAsync}}
262275
Ok(client.execute(req)?.error_for_status()?.json()?)
276+
{{/supportAsync}}
263277
{{/returnType}}
264278
}
265279

266280
{{/operation}}
267281
{{/operations}}
282+
{{^supportAsync}}
268283
}
284+
{{/supportAsync}}

modules/openapi-generator/src/main/resources/rust/reqwest/api_mod.mustache

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ pub fn urlencode<T: AsRef<str>>(s: T) -> String {
3535
mod {{{classFilename}}};
3636
{{#operations}}
3737
{{#operation}}
38+
{{^supportAsync}}
3839
{{#-first}}
3940
pub use self::{{{classFilename}}}::{ {{{classname}}}, {{{classname}}}Client };
4041
{{/-first}}
42+
{{/supportAsync}}
43+
{{#supportAsync}}
44+
pub use self::{{{classFilename}}}::{ {{{operationId}}} };
45+
{{/supportAsync}}
4146
{{#vendorExtensions.x-group-parameters}}
4247
{{#allParams}}
4348
{{#-first}}
@@ -50,5 +55,7 @@ pub use self::{{{classFilename}}}::{ {{{classname}}}{{{operationIdCamelCase}}}Pa
5055
{{/apis}}
5156
{{/apiInfo}}
5257

53-
pub mod configuration;
58+
{{^supportAsync}}
5459
pub mod client;
60+
{{/supportAsync}}
61+
pub mod configuration;

samples/client/petstore/rust/hyper/fileResponseTest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "fileResponseTest-hyper"
33
version = "1.0.0"
44
authors = ["OpenAPI Generator team and contributors"]
5+
edition = "2018"
56

67
[dependencies]
78
serde = "^1.0"

samples/client/petstore/rust/hyper/petstore/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "petstore-hyper"
33
version = "1.0.0"
44
authors = ["OpenAPI Generator team and contributors"]
5+
edition = "2018"
56

67
[dependencies]
78
serde = "^1.0"

samples/client/petstore/rust/hyper/rust-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "rust-test-hyper"
33
version = "1.0.0"
44
authors = ["OpenAPI Generator team and contributors"]
5+
edition = "2018"
56

67
[dependencies]
78
serde = "^1.0"

samples/client/petstore/rust/reqwest/fileResponseTest/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "fileResponseTest-reqwest"
33
version = "1.0.0"
44
authors = ["OpenAPI Generator team and contributors"]
5+
edition = "2018"
56

67
[dependencies]
78
serde = "^1.0"

0 commit comments

Comments
 (0)