Skip to content

Commit 03754a4

Browse files
committed
Use request-trait template
Also updated the request-trait templates to match the changes we'de done to reqwest: - Replace &str by uuids when appropiate - Removed lifetimes, which were unused Also updated the build script and added missing async-trait and mockall dependencies
1 parent f2bc708 commit 03754a4

File tree

7 files changed

+118
-75
lines changed

7 files changed

+118
-75
lines changed

Cargo.lock

Lines changed: 75 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bitwarden-api-api/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ repository.workspace = true
1212
license-file.workspace = true
1313
keywords.workspace = true
1414

15+
[features]
16+
mockall = ["dep:mockall"]
17+
1518
[dependencies]
19+
async-trait = { workspace = true }
20+
mockall = { version = ">=0.13, <0.14", optional = true}
1621
reqwest = { workspace = true }
1722
serde = { workspace = true }
1823
serde_json = { workspace = true }

crates/bitwarden-api-identity/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ repository.workspace = true
1212
license-file.workspace = true
1313
keywords.workspace = true
1414

15+
[features]
16+
mockall = ["dep:mockall"]
17+
1518
[dependencies]
19+
async-trait = { workspace = true }
20+
mockall = { version = ">=0.13, <0.14", optional = true}
1621
reqwest = { workspace = true }
1722
serde = { workspace = true }
1823
serde_json = { workspace = true }

support/build-api.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ npx openapi-generator-cli generate \
1818
-o crates/bitwarden-api-api \
1919
--package-name bitwarden-api-api \
2020
-t ./support/openapi-template \
21-
--additional-properties=packageVersion=$VERSION,packageDescription=\"Api bindings for the Bitwarden API.\"
21+
--additional-properties=library=reqwest-trait,mockall,topLevelApiClient,packageVersion=$VERSION,packageDescription=\"Api bindings for the Bitwarden API.\"
2222

2323
# Delete old directory to ensure all files are updated
2424
rm -rf crates/bitwarden-api-identity/src
@@ -30,7 +30,7 @@ npx openapi-generator-cli generate \
3030
-o crates/bitwarden-api-identity \
3131
--package-name bitwarden-api-identity \
3232
-t ./support/openapi-template \
33-
--additional-properties=packageVersion=$VERSION,packageDescription=\"Api bindings for the Bitwarden Identity API.\"
33+
--additional-properties=library=reqwest-trait,mockall,topLevelApiClient,packageVersion=$VERSION,packageDescription=\"Api bindings for the Bitwarden Identity API.\"
3434

3535
rustup toolchain install nightly
3636
cargo +nightly fmt

support/openapi-template/lib.mustache

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
clippy::empty_docs,
55
clippy::to_string_in_format_args,
66
clippy::needless_return,
7-
clippy::uninlined_format_args
7+
clippy::uninlined_format_args,
8+
clippy::new_without_default
89
)]
910

1011
extern crate serde_repr;

support/openapi-template/reqwest-trait/api.mustache

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::apis::ContentType;
1515
{{#mockall}}
1616
#[cfg_attr(feature = "mockall", automock)]
1717
{{/mockall}}
18-
#[async_trait]
18+
#[async_trait(?Send)]
1919
pub trait {{{classname}}}: Send + Sync {
2020
{{#operations}}
2121
{{#operation}}
@@ -26,11 +26,11 @@ pub trait {{{classname}}}: Send + Sync {
2626
/// {{{notes}}}
2727
{{/notes.empty}}
2828
{{#vendorExtensions.x-group-parameters}}
29-
async fn {{{operationId}}}(&self, {{#allParams}}{{#-first}} params: {{{operationIdCamelCase}}}Params {{/-first}}{{/allParams}}{{!
29+
async fn {{{operationId}}}(&self, {{#allParams}}{{#-first}} params: {{{operationIdCamelCase}}}Params {{/-first}}{{/allParams}}{{!
3030
### Function return type
3131
}}) -> Result<{{!
3232
### Multi response support
33-
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
33+
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
3434
### Regular return type
3535
}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{{returnType}}}{{/supportMultipleResponses}}{{!
3636
### Error Type
@@ -39,27 +39,27 @@ pub trait {{{classname}}}: Send + Sync {
3939
{{^vendorExtensions.x-group-parameters}}
4040
async fn {{{operationId}}}{{!
4141
### Lifetimes
42-
}}<{{#allParams}}'{{#lambda.lifetimeName}}{{{paramName}}}{{/lambda.lifetimeName}}{{^-last}}, {{/-last}}{{/allParams}}>{{!
42+
}}<'a>{{!
4343
### Function parameter names
44-
}}(&self, {{#allParams}}{{{paramName}}}: {{!
44+
}}(&self, {{#allParams}}{{{paramName}}}: {{!
4545
### Option Start
46-
}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{!
46+
}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{!
4747
### &str and Vec<&str>
48-
}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{^isUuid}}&'{{#lambda.lifetimeName}}{{{paramName}}}{{/lambda.lifetimeName}} str{{/isUuid}}{{#isArray}}>{{/isArray}}{{/isString}}{{!
48+
}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{^isUuid}}&'a str{{/isUuid}}{{#isArray}}>{{/isArray}}{{/isString}}{{!
4949
### UUIDs
50-
}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isUuid}}{{!
50+
}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{!
5151
### Models and primative types
52-
}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{!
52+
}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{!
5353
### Option End
54-
}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{!
54+
}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{!
5555
### Comma for next arguement
5656
}}{{^-last}}, {{/-last}}{{/allParams}}{{!
5757
### Function return type
58-
}}) -> Result<{{!
58+
}}) -> Result<{{!
5959
### Multi response support
60-
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
60+
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
6161
### Regular return type
62-
}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{{returnType}}}{{/supportMultipleResponses}}{{!
62+
}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{{returnType}}}{{/supportMultipleResponses}}{{!
6363
### Error Type
6464
}}, Error<{{{operationIdCamelCase}}}Error>>;
6565
{{/vendorExtensions.x-group-parameters}}
@@ -115,7 +115,7 @@ pub struct {{{operationIdCamelCase}}}Params {
115115
{{/operation}}
116116
{{/operations}}
117117

118-
#[async_trait]
118+
#[async_trait(?Send)]
119119
impl {{classname}} for {{classname}}Client {
120120
{{#operations}}
121121
{{#operation}}
@@ -147,23 +147,23 @@ impl {{classname}} for {{classname}}Client {
147147
{{^vendorExtensions.x-group-parameters}}
148148
async fn {{{operationId}}}{{!
149149
### Lifetimes
150-
}}<{{#allParams}}'{{#lambda.lifetimeName}}{{{paramName}}}{{/lambda.lifetimeName}}{{^-last}}, {{/-last}}{{/allParams}}>{{!
150+
}}<'a>{{!
151151
### Function parameter names
152-
}}(&self, {{#allParams}}{{{paramName}}}: {{!
152+
}}(&self, {{#allParams}}{{{paramName}}}: {{!
153153
### Option Start
154154
}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{!
155155
### &str and Vec<&str>
156-
}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{^isUuid}}&'{{#lambda.lifetimeName}}{{{paramName}}}{{/lambda.lifetimeName}} str{{/isUuid}}{{#isArray}}>{{/isArray}}{{/isString}}{{!
156+
}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{^isUuid}}&'a str{{/isUuid}}{{#isArray}}>{{/isArray}}{{/isString}}{{!
157157
### UUIDs
158-
}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isUuid}}{{!
158+
}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}uuid::Uuid{{#isArray}}>{{/isArray}}{{/isUuid}}{{!
159159
### Models and primative types
160160
}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{!
161161
### Option End
162162
}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{!
163163
### Comma for next arguement
164-
}}{{^-last}}, {{/-last}}{{/allParams}}{{!
164+
}}{{^-last}}, {{/-last}}{{/allParams}}{{!
165165
### Function return type
166-
}}) -> Result<{{!
166+
}}) -> Result<{{!
167167
### Multi response support
168168
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
169169
### Regular return type
@@ -175,7 +175,7 @@ impl {{classname}} for {{classname}}Client {
175175

176176
let local_var_client = &local_var_configuration.client;
177177

178-
let local_var_uri_str = format!("{}{{{path}}}", local_var_configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}crate::apis::urlencode({{/isString}}{{{paramName}}}{{^required}}.unwrap(){{/required}}{{#required}}{{#isNullable}}.unwrap(){{/isNullable}}{{/required}}{{#isArray}}.join(",").as_ref(){{/isArray}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}.to_string(){{/isContainer}}{{/isPrimitiveType}}{{/isUuid}}{{/isString}}{{#isString}}){{/isString}}{{/pathParams}});
178+
let local_var_uri_str = format!("{}{{{path}}}", local_var_configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}{{^isUuid}}crate::apis::urlencode({{/isUuid}}{{/isString}}{{{paramName}}}{{^required}}.unwrap(){{/required}}{{#required}}{{#isNullable}}.unwrap(){{/isNullable}}{{/required}}{{#isArray}}.join(",").as_ref(){{/isArray}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}.to_string(){{/isContainer}}{{/isPrimitiveType}}{{/isUuid}}{{/isString}}{{#isString}}{{^isUuid}}){{/isUuid}}{{/isString}}{{/pathParams}});
179179
let mut local_var_req_builder = local_var_client.request(reqwest::Method::{{{httpMethod}}}, local_var_uri_str.as_str());
180180

181181
{{#queryParams}}

support/openapi-template/reqwest-trait/api_mod.mustache

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -160,77 +160,35 @@ pub mod configuration;
160160
{{#topLevelApiClient}}
161161
use std::sync::Arc;
162162

163+
{{#mockall}}
164+
#[cfg_attr(feature = "mockall", mockall::automock)]
165+
{{/mockall}}
163166
pub trait Api {
164167
{{#apiInfo}}
165168
{{#apis}}
166-
fn {{{classFilename}}}(&self) -> &dyn {{{classFilename}}}::{{classname}};
169+
fn {{{classFilename}}}(&self) -> Box<dyn {{{classFilename}}}::{{classname}}>;
167170
{{/apis}}
168171
{{/apiInfo}}
169172
}
170173

171174
pub struct ApiClient {
172-
{{#apiInfo}}
173-
{{#apis}}
174-
{{{classFilename}}}: Box<dyn {{{classFilename}}}::{{classname}}>,
175-
{{/apis}}
176-
{{/apiInfo}}
175+
configuration: Arc<configuration::Configuration>,
177176
}
178177

179178
impl ApiClient {
180179
pub fn new(configuration: Arc<configuration::Configuration>) -> Self {
181-
Self {
182-
{{#apiInfo}}
183-
{{#apis}}
184-
{{{classFilename}}}: Box::new({{{classFilename}}}::{{classname}}Client::new(configuration.clone())),
185-
{{/apis}}
186-
{{/apiInfo}}
187-
}
180+
Self { configuration }
188181
}
189182
}
190183

191184
impl Api for ApiClient {
192185
{{#apiInfo}}
193186
{{#apis}}
194-
fn {{{classFilename}}}(&self) -> &dyn {{{classFilename}}}::{{classname}} {
195-
self.{{{classFilename}}}.as_ref()
196-
}
197-
{{/apis}}
198-
{{/apiInfo}}
199-
}
200-
201-
{{#mockall}}
202-
#[cfg(feature = "mockall")]
203-
pub struct MockApiClient {
204-
{{#apiInfo}}
205-
{{#apis}}
206-
pub {{{classFilename}}}_mock: {{{classFilename}}}::Mock{{classname}},
207-
{{/apis}}
208-
{{/apiInfo}}
209-
}
210-
211-
#[cfg(feature = "mockall")]
212-
impl MockApiClient {
213-
pub fn new() -> Self {
214-
Self {
215-
{{#apiInfo}}
216-
{{#apis}}
217-
{{{classFilename}}}_mock: {{{classFilename}}}::Mock{{classname}}::new(),
218-
{{/apis}}
219-
{{/apiInfo}}
220-
}
221-
}
222-
}
223-
224-
#[cfg(feature = "mockall")]
225-
impl Api for MockApiClient {
226-
{{#apiInfo}}
227-
{{#apis}}
228-
fn {{{classFilename}}}(&self) -> &dyn {{{classFilename}}}::{{classname}} {
229-
&self.{{{classFilename}}}_mock
187+
fn {{{classFilename}}}(&self) -> Box<dyn {{{classFilename}}}::{{classname}}> {
188+
Box::new({{{classFilename}}}::{{classname}}Client::new(self.configuration.clone()))
230189
}
231190
{{/apis}}
232191
{{/apiInfo}}
233192
}
234-
{{/mockall}}
235193

236194
{{/topLevelApiClient}}

0 commit comments

Comments
 (0)