[Core, Rust Server] Support JSON query parameters (#6577)

* [Core] Record content type for parameters

* [Rust Server] Support query parameters in JSON

* [Rust Server] Add test for JSON query parameter

* Update samples
This commit is contained in:
Richard Whitehouse 2020-06-15 23:06:03 +01:00 committed by GitHub
parent 45655c2235
commit c094effd90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 573 additions and 121 deletions

View File

@ -4096,22 +4096,23 @@ public class DefaultCodegen implements CodegenConfig {
codegenParameter.vendorExtensions.putAll(parameter.getExtensions());
}
Schema s;
Schema parameterSchema;
if (parameter.getSchema() != null) {
s = parameter.getSchema();
parameterSchema = parameter.getSchema();
} else if (parameter.getContent() != null) {
Content content = parameter.getContent();
if (content.size() > 1) {
once(LOGGER).warn("Multiple schemas found in content, returning only the first one");
}
MediaType mediaType = content.values().iterator().next();
s = mediaType.getSchema();
Map.Entry<String, MediaType> entry = content.entrySet().iterator().next();
codegenParameter.contentType = entry.getKey();
parameterSchema = entry.getValue().getSchema();
} else {
s = null;
parameterSchema = null;
}
if (s != null) {
Schema parameterSchema = ModelUtils.unaliasSchema(this.openAPI, s, importMapping);
if (parameterSchema != null) {
parameterSchema = ModelUtils.unaliasSchema(this.openAPI, parameterSchema);
if (parameterSchema == null) {
LOGGER.warn("warning! Schema not found for parameter \"" + parameter.getName() + "\", using String");
parameterSchema = new StringSchema().description("//TODO automatically added by openapi-generator due to missing type definition.");

View File

@ -1027,6 +1027,13 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
}
}
for (CodegenParameter param : op.queryParams) {
// If the MIME type is JSON, mark it. We don't currently support any other MIME types.
if (param.contentType != null && isMimetypeJson(param.contentType)) {
param.vendorExtensions.put("x-consumes-json", true);
}
}
for (CodegenParameter param : op.formParams) {
processParam(param, op);
}

View File

@ -36,7 +36,23 @@
{{^required}}
if let Some(param_{{{paramName}}}) = param_{{{paramName}}} {
{{/required}}
query_string.append_pair("{{{baseName}}}", &param_{{{paramName}}}{{#isListContainer}}.iter().map(ToString::to_string).collect::<Vec<String>>().join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
query_string.append_pair("{{{baseName}}}",
{{#vendorExtensions}}
{{#x-consumes-json}}
&match serde_json::to_string(&param_{{{paramName}}}) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {}", e))),
});
{{/x-consumes-json}}
{{^x-consumes-json}}
{{#isListContainer}}
&param_{{{paramName}}}.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
{{/isListContainer}}
{{^isListContainer}}
&param_{{{paramName}}}.to_string());
{{/isListContainer}}
{{/x-consumes-json}}
{{/vendorExtensions}}
{{^required}}
}
{{/required}}
@ -87,7 +103,7 @@
{{#jsonSchema}}
let {{{paramName}}}_str = match serde_json::to_string(&param_{{{paramName}}}) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {}", e))),
};
let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec();

View File

@ -121,43 +121,83 @@
{{/-last}}
{{/headerParams}}
{{#queryParams}}
{{#-first}}
{{#-first}}
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
{{/-first}}
{{/-first}}
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.to_owned())
{{#isListContainer}}
{{#isListContainer}}
{{^vendorExtensions.x-consumes-json}}
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse().ok())
.collect::<Vec<_>>();
{{^required}}
{{^required}}
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
Some(param_{{{paramName}}})
} else {
None
};
{{/required}}
{{/isListContainer}}
{{^isListContainer}}
{{/required}}
{{/vendorExtensions.x-consumes-json}}
{{#vendorExtensions.x-consumes-json}}
.nth(0);
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")),
Some(param_{{{paramName}}}) => {
let param_{{{paramName}}} =
serde_json::from_str::<{{{dataType}}}>
(&param_{{{paramName}}});
match param_{{{paramName}}} {
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")),
}
},
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter {{{baseName}}}"))
.expect("Unable to create Bad Request response for missing qeury parameter {{{baseName}}}")),
None => None,
};
{{/required}}
{{^required}}
let param_{{{paramName}}} = param_{{{paramName}}}.and_then(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok());
{{/required}}
{{/isListContainer}}
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => param_{{{paramName}}},
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter {{{baseName}}}"))
.expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")),
};
{{/required}}
{{/vendorExtensions.x-consumes-json}}
{{/isListContainer}}
{{^isListContainer}}
.nth(0);
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => {
let param_{{{paramName}}} =
{{#vendorExtensions.x-consumes-json}}
serde_json::from_str::<{{{dataType}}}>
{{/vendorExtensions.x-consumes-json}}
{{^vendorExtensions.x-consumes-json}}
<{{{dataType}}} as std::str::FromStr>::from_str
{{/vendorExtensions.x-consumes-json}}
(&param_{{{paramName}}});
match param_{{{paramName}}} {
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")),
}
},
None => None,
};
{{#required}}
let param_{{{paramName}}} = match param_{{{paramName}}} {
Some(param_{{{paramName}}}) => param_{{{paramName}}},
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter {{{baseName}}}"))
.expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")),
};
{{/required}}
{{/isListContainer}}
{{#-last}}
{{/-last}}

View File

@ -391,6 +391,20 @@ paths:
responses:
'200':
description: Success
/json-complex-query-param:
get:
parameters:
- name: list-of-strings
in: query
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StringObject'
responses:
'200':
description: Success
components:
securitySchemes:

View File

@ -574,7 +574,7 @@ impl<S, C> Api<C> for Client<S, C> where
let string_field_str = match serde_json::to_string(&param_string_field) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse string_field to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize string_field to string: {}", e))),
};
let string_field_vec = string_field_str.as_bytes().to_vec();
@ -586,7 +586,7 @@ impl<S, C> Api<C> for Client<S, C> where
let optional_string_field_str = match serde_json::to_string(&param_optional_string_field) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse optional_string_field to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize optional_string_field to string: {}", e))),
};
let optional_string_field_vec = optional_string_field_str.as_bytes().to_vec();
@ -598,7 +598,7 @@ impl<S, C> Api<C> for Client<S, C> where
let object_field_str = match serde_json::to_string(&param_object_field) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse object_field to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize object_field to string: {}", e))),
};
let object_field_vec = object_field_str.as_bytes().to_vec();

View File

@ -63,6 +63,7 @@ To run a client, follow one of the following simple steps:
```
cargo run --example client CallbackWithHeaderPost
cargo run --example client ComplexQueryParamGet
cargo run --example client JsonComplexQueryParamGet
cargo run --example client MandatoryRequestHeaderGet
cargo run --example client MergePatchJsonGet
cargo run --example client MultigetGet
@ -119,6 +120,7 @@ Method | HTTP request | Description
[****](docs/default_api.md#) | **POST** /callback-with-header |
[****](docs/default_api.md#) | **GET** /complex-query-param |
[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} |
[****](docs/default_api.md#) | **GET** /json-complex-query-param |
[****](docs/default_api.md#) | **GET** /mandatory-request-header |
[****](docs/default_api.md#) | **GET** /merge-patch-json |
[****](docs/default_api.md#) | **GET** /multiget | Get some stuff.

View File

@ -407,6 +407,23 @@ paths:
description: Success
tags:
- Repo
/json-complex-query-param:
get:
parameters:
- content:
application/json:
schema:
items:
$ref: '#/components/schemas/StringObject'
type: array
explode: true
in: query
name: list-of-strings
required: false
style: form
responses:
"200":
description: Success
components:
schemas:
EnumWithStarObject:

View File

@ -7,6 +7,7 @@ Method | HTTP request | Description
****](default_api.md#) | **POST** /callback-with-header |
****](default_api.md#) | **GET** /complex-query-param |
****](default_api.md#) | **GET** /enum_in_path/{path_param} |
****](default_api.md#) | **GET** /json-complex-query-param |
****](default_api.md#) | **GET** /mandatory-request-header |
****](default_api.md#) | **GET** /merge-patch-json |
****](default_api.md#) | **GET** /multiget | Get some stuff.
@ -109,6 +110,38 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# ****
> (optional)
### Required Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**optional** | **map[string]interface{}** | optional parameters | nil if no parameters
### Optional Parameters
Optional parameters are passed through a map[string]interface{}.
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**list_of_strings** | [**String**](String.md)| |
### Return type
(empty response body)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: Not defined
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# ****
> (x_header)

View File

@ -9,6 +9,7 @@ use openapi_v3::{Api, ApiNoContext, Client, ContextWrapperExt, models,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
MultigetGetResponse,
@ -52,6 +53,7 @@ fn main() {
.possible_values(&[
"CallbackWithHeaderPost",
"ComplexQueryParamGet",
"JsonComplexQueryParamGet",
"MandatoryRequestHeaderGet",
"MergePatchJsonGet",
"MultigetGet",
@ -138,6 +140,12 @@ fn main() {
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
*/
Some("JsonComplexQueryParamGet") => {
let result = rt.block_on(client.json_complex_query_param_get(
Some(&Vec::new())
));
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
Some("MandatoryRequestHeaderGet") => {
let result = rt.block_on(client.mandatory_request_header_get(
"x_header_example".to_string()

View File

@ -99,6 +99,7 @@ use openapi_v3::{
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
MultigetGetResponse,
@ -157,6 +158,16 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString> + Send + Sync
Err("Generic failuare".into())
}
async fn json_complex_query_param_get(
&self,
list_of_strings: Option<&Vec<models::StringObject>>,
context: &C) -> Result<JsonComplexQueryParamGetResponse, ApiError>
{
let context = context.clone();
info!("json_complex_query_param_get({:?}) - X-Span-ID: {:?}", list_of_strings, context.get().0.clone());
Err("Generic failuare".into())
}
async fn mandatory_request_header_get(
&self,
x_header: String,

View File

@ -39,6 +39,7 @@ use crate::{Api,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
MultigetGetResponse,
@ -418,7 +419,8 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("url", &param_url.to_string());
query_string.append_pair("url",
&param_url.to_string());
query_string.finish()
};
if !query_string.is_empty() {
@ -490,7 +492,8 @@ impl<S, C> Api<C> for Client<S, C> where
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
if let Some(param_list_of_strings) = param_list_of_strings {
query_string.append_pair("list-of-strings", &param_list_of_strings.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.append_pair("list-of-strings",
&param_list_of_strings.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
}
query_string.finish()
};
@ -619,6 +622,83 @@ impl<S, C> Api<C> for Client<S, C> where
}
}
async fn json_complex_query_param_get(
&self,
param_list_of_strings: Option<&Vec<models::StringObject>>,
context: &C) -> Result<JsonComplexQueryParamGetResponse, ApiError>
{
let mut client_service = self.client_service.clone();
let mut uri = format!(
"{}/json-complex-query-param",
self.base_path
);
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
if let Some(param_list_of_strings) = param_list_of_strings {
query_string.append_pair("list-of-strings",
&match serde_json::to_string(&param_list_of_strings) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to serialize list_of_strings to string: {}", e))),
});
}
query_string.finish()
};
if !query_string.is_empty() {
uri += "?";
uri += &query_string;
}
let uri = match Uri::from_str(&uri) {
Ok(uri) => uri,
Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))),
};
let mut request = match Request::builder()
.method("GET")
.uri(uri)
.body(Body::empty()) {
Ok(req) => req,
Err(e) => return Err(ApiError(format!("Unable to create request: {}", e)))
};
let header = HeaderValue::from_str(Has::<XSpanIdString>::get(context).0.clone().to_string().as_str());
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
Ok(h) => h,
Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))
});
let mut response = client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))).await?;
match response.status().as_u16() {
200 => {
let body = response.into_body();
Ok(
JsonComplexQueryParamGetResponse::Success
)
}
code => {
let headers = response.headers().clone();
let body = response.into_body()
.take(100)
.to_raw().await;
Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
code,
headers,
match body {
Ok(body) => match String::from_utf8(body) {
Ok(body) => body,
Err(e) => format!("<Body was not UTF8: {:?}>", e),
},
Err(e) => format!("<Failed to read body: {}>", e),
}
)))
}
}
}
async fn mandatory_request_header_get(
&self,
param_x_header: String,
@ -1095,13 +1175,16 @@ impl<S, C> Api<C> for Client<S, C> where
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
if let Some(param_uuid) = param_uuid {
query_string.append_pair("uuid", &param_uuid.to_string());
query_string.append_pair("uuid",
&param_uuid.to_string());
}
if let Some(param_some_object) = param_some_object {
query_string.append_pair("someObject", &param_some_object.to_string());
query_string.append_pair("someObject",
&param_some_object.to_string());
}
if let Some(param_some_list) = param_some_list {
query_string.append_pair("someList", &param_some_list.to_string());
query_string.append_pair("someList",
&param_some_list.to_string());
}
query_string.finish()
};
@ -1265,7 +1348,8 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("url", &param_url.to_string());
query_string.append_pair("url",
&param_url.to_string());
query_string.finish()
};
if !query_string.is_empty() {

View File

@ -29,6 +29,12 @@ pub enum EnumInPathPathParamGetResponse {
Success
}
#[derive(Debug, PartialEq)]
pub enum JsonComplexQueryParamGetResponse {
/// Success
Success
}
#[derive(Debug, PartialEq)]
pub enum MandatoryRequestHeaderGetResponse {
/// Success
@ -262,6 +268,11 @@ pub trait Api<C: Send + Sync> {
path_param: models::StringEnum,
context: &C) -> Result<EnumInPathPathParamGetResponse, ApiError>;
async fn json_complex_query_param_get(
&self,
list_of_strings: Option<&Vec<models::StringObject>>,
context: &C) -> Result<JsonComplexQueryParamGetResponse, ApiError>;
async fn mandatory_request_header_get(
&self,
x_header: String,
@ -384,6 +395,11 @@ pub trait ApiNoContext<C: Send + Sync> {
path_param: models::StringEnum,
) -> Result<EnumInPathPathParamGetResponse, ApiError>;
async fn json_complex_query_param_get(
&self,
list_of_strings: Option<&Vec<models::StringObject>>,
) -> Result<JsonComplexQueryParamGetResponse, ApiError>;
async fn mandatory_request_header_get(
&self,
x_header: String,
@ -533,6 +549,15 @@ impl<T: Api<C> + Send + Sync, C: Clone + Send + Sync> ApiNoContext<C> for Contex
self.api().enum_in_path_path_param_get(path_param, &context).await
}
async fn json_complex_query_param_get(
&self,
list_of_strings: Option<&Vec<models::StringObject>>,
) -> Result<JsonComplexQueryParamGetResponse, ApiError>
{
let context = self.context().clone();
self.api().json_complex_query_param_get(list_of_strings, &context).await
}
async fn mandatory_request_header_get(
&self,
x_header: String,

View File

@ -25,6 +25,7 @@ use crate::{Api,
CallbackWithHeaderPostResponse,
ComplexQueryParamGetResponse,
EnumInPathPathParamGetResponse,
JsonComplexQueryParamGetResponse,
MandatoryRequestHeaderGetResponse,
MergePatchJsonGetResponse,
MultigetGetResponse,
@ -57,6 +58,7 @@ mod paths {
r"^/callback-with-header$",
r"^/complex-query-param$",
r"^/enum_in_path/(?P<path_param>[^/?#]*)$",
r"^/json-complex-query-param$",
r"^/mandatory-request-header$",
r"^/merge-patch-json$",
r"^/multiget$",
@ -86,29 +88,30 @@ mod paths {
regex::Regex::new(r"^/enum_in_path/(?P<path_param>[^/?#]*)$")
.expect("Unable to create regex for ENUM_IN_PATH_PATH_PARAM");
}
pub(crate) static ID_MANDATORY_REQUEST_HEADER: usize = 3;
pub(crate) static ID_MERGE_PATCH_JSON: usize = 4;
pub(crate) static ID_MULTIGET: usize = 5;
pub(crate) static ID_MULTIPLE_AUTH_SCHEME: usize = 6;
pub(crate) static ID_OVERRIDE_SERVER: usize = 7;
pub(crate) static ID_PARAMGET: usize = 8;
pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 9;
pub(crate) static ID_REGISTER_CALLBACK: usize = 10;
pub(crate) static ID_REPOS: usize = 11;
pub(crate) static ID_REPOS_REPOID: usize = 12;
pub(crate) static ID_JSON_COMPLEX_QUERY_PARAM: usize = 3;
pub(crate) static ID_MANDATORY_REQUEST_HEADER: usize = 4;
pub(crate) static ID_MERGE_PATCH_JSON: usize = 5;
pub(crate) static ID_MULTIGET: usize = 6;
pub(crate) static ID_MULTIPLE_AUTH_SCHEME: usize = 7;
pub(crate) static ID_OVERRIDE_SERVER: usize = 8;
pub(crate) static ID_PARAMGET: usize = 9;
pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 10;
pub(crate) static ID_REGISTER_CALLBACK: usize = 11;
pub(crate) static ID_REPOS: usize = 12;
pub(crate) static ID_REPOS_REPOID: usize = 13;
lazy_static! {
pub static ref REGEX_REPOS_REPOID: regex::Regex =
regex::Regex::new(r"^/repos/(?P<repoId>[^/?#]*)$")
.expect("Unable to create regex for REPOS_REPOID");
}
pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 13;
pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 14;
pub(crate) static ID_RFC7807: usize = 15;
pub(crate) static ID_UNTYPED_PROPERTY: usize = 16;
pub(crate) static ID_UUID: usize = 17;
pub(crate) static ID_XML: usize = 18;
pub(crate) static ID_XML_EXTRA: usize = 19;
pub(crate) static ID_XML_OTHER: usize = 20;
pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 14;
pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 15;
pub(crate) static ID_RFC7807: usize = 16;
pub(crate) static ID_UNTYPED_PROPERTY: usize = 17;
pub(crate) static ID_UUID: usize = 18;
pub(crate) static ID_XML: usize = 19;
pub(crate) static ID_XML_EXTRA: usize = 20;
pub(crate) static ID_XML_OTHER: usize = 21;
}
pub struct MakeService<T, C> where
@ -220,17 +223,26 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.to_owned())
.nth(0);
let param_url = match param_url {
Some(param_url) => match param_url.parse::<String>() {
Ok(param_url) => param_url,
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter url")),
Some(param_url) => {
let param_url =
<String as std::str::FromStr>::from_str
(&param_url);
match param_url {
Ok(param_url) => Some(param_url),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter url")),
}
},
None => None,
};
let param_url = match param_url {
Some(param_url) => param_url,
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter url"))
.expect("Unable to create Bad Request response for missing qeury parameter url")),
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter url"))
.expect("Unable to create Bad Request response for missing query parameter url")),
};
let result = api_impl.callback_with_header_post(
@ -355,6 +367,56 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
Ok(response)
},
// JsonComplexQueryParamGet - GET /json-complex-query-param
&hyper::Method::GET if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => {
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
let param_list_of_strings = query_params.iter().filter(|e| e.0 == "list-of-strings").map(|e| e.1.to_owned())
.nth(0);
let param_list_of_strings = match param_list_of_strings {
Some(param_list_of_strings) => {
let param_list_of_strings =
serde_json::from_str::<Vec<models::StringObject>>
(&param_list_of_strings);
match param_list_of_strings {
Ok(param_list_of_strings) => Some(param_list_of_strings),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter list-of-strings - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter list-of-strings")),
}
},
None => None,
};
let result = api_impl.json_complex_query_param_get(
param_list_of_strings.as_ref(),
&context
).await;
let mut response = Response::new(Body::empty());
response.headers_mut().insert(
HeaderName::from_static("x-span-id"),
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
.expect("Unable to create X-Span-ID header value"));
match result {
Ok(rsp) => match rsp {
JsonComplexQueryParamGetResponse::Success
=> {
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
},
},
Err(_) => {
// Application code returned an error. This should not happen, as the implementation should
// return a valid response.
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
*response.body_mut() = Body::from("An internal error occurred");
},
}
Ok(response)
},
// MandatoryRequestHeaderGet - GET /mandatory-request-header
&hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => {
// Header parameters
@ -640,13 +702,55 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
let param_uuid = query_params.iter().filter(|e| e.0 == "uuid").map(|e| e.1.to_owned())
.nth(0);
let param_uuid = param_uuid.and_then(|param_uuid| param_uuid.parse::<>().ok());
let param_uuid = match param_uuid {
Some(param_uuid) => {
let param_uuid =
<uuid::Uuid as std::str::FromStr>::from_str
(&param_uuid);
match param_uuid {
Ok(param_uuid) => Some(param_uuid),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter uuid - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter uuid")),
}
},
None => None,
};
let param_some_object = query_params.iter().filter(|e| e.0 == "someObject").map(|e| e.1.to_owned())
.nth(0);
let param_some_object = param_some_object.and_then(|param_some_object| param_some_object.parse::<>().ok());
let param_some_object = match param_some_object {
Some(param_some_object) => {
let param_some_object =
<models::ObjectParam as std::str::FromStr>::from_str
(&param_some_object);
match param_some_object {
Ok(param_some_object) => Some(param_some_object),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter someObject - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter someObject")),
}
},
None => None,
};
let param_some_list = query_params.iter().filter(|e| e.0 == "someList").map(|e| e.1.to_owned())
.nth(0);
let param_some_list = param_some_list.and_then(|param_some_list| param_some_list.parse::<>().ok());
let param_some_list = match param_some_list {
Some(param_some_list) => {
let param_some_list =
<models::MyIdList as std::str::FromStr>::from_str
(&param_some_list);
match param_some_list {
Ok(param_some_list) => Some(param_some_list),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter someList - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter someList")),
}
},
None => None,
};
let result = api_impl.paramget_get(
param_uuid,
@ -750,17 +854,26 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.to_owned())
.nth(0);
let param_url = match param_url {
Some(param_url) => match param_url.parse::<String>() {
Ok(param_url) => param_url,
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter url")),
Some(param_url) => {
let param_url =
<String as std::str::FromStr>::from_str
(&param_url);
match param_url {
Ok(param_url) => Some(param_url),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter url")),
}
},
None => None,
};
let param_url = match param_url {
Some(param_url) => param_url,
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter url"))
.expect("Unable to create Bad Request response for missing qeury parameter url")),
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter url"))
.expect("Unable to create Bad Request response for missing query parameter url")),
};
let result = api_impl.register_callback_post(
@ -1612,6 +1725,7 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
_ if path.matched(paths::ID_CALLBACK_WITH_HEADER) => method_not_allowed(),
_ if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => method_not_allowed(),
_ if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => method_not_allowed(),
_ if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => method_not_allowed(),
_ if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => method_not_allowed(),
_ if path.matched(paths::ID_MERGE_PATCH_JSON) => method_not_allowed(),
_ if path.matched(paths::ID_MULTIGET) => method_not_allowed(),
@ -1649,6 +1763,8 @@ impl<T> RequestParser<T> for ApiRequestParser {
&hyper::Method::GET if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => Ok("ComplexQueryParamGet"),
// EnumInPathPathParamGet - GET /enum_in_path/{path_param}
&hyper::Method::GET if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => Ok("EnumInPathPathParamGet"),
// JsonComplexQueryParamGet - GET /json-complex-query-param
&hyper::Method::GET if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => Ok("JsonComplexQueryParamGet"),
// MandatoryRequestHeaderGet - GET /mandatory-request-header
&hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => Ok("MandatoryRequestHeaderGet"),
// MergePatchJsonGet - GET /merge-patch-json

View File

@ -1080,7 +1080,8 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("query", &param_query.to_string());
query_string.append_pair("query",
&param_query.to_string());
query_string.finish()
};
if !query_string.is_empty() {
@ -1380,16 +1381,20 @@ impl<S, C> Api<C> for Client<S, C> where
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
if let Some(param_enum_query_string_array) = param_enum_query_string_array {
query_string.append_pair("enum_query_string_array", &param_enum_query_string_array.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.append_pair("enum_query_string_array",
&param_enum_query_string_array.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
}
if let Some(param_enum_query_string) = param_enum_query_string {
query_string.append_pair("enum_query_string", &param_enum_query_string.to_string());
query_string.append_pair("enum_query_string",
&param_enum_query_string.to_string());
}
if let Some(param_enum_query_integer) = param_enum_query_integer {
query_string.append_pair("enum_query_integer", &param_enum_query_integer.to_string());
query_string.append_pair("enum_query_integer",
&param_enum_query_integer.to_string());
}
if let Some(param_enum_query_double) = param_enum_query_double {
query_string.append_pair("enum_query_double", &param_enum_query_double.to_string());
query_string.append_pair("enum_query_double",
&param_enum_query_double.to_string());
}
query_string.finish()
};
@ -1970,7 +1975,8 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("status", &param_status.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.append_pair("status",
&param_status.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.finish()
};
if !query_string.is_empty() {
@ -2073,7 +2079,8 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("tags", &param_tags.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.append_pair("tags",
&param_tags.iter().map(ToString::to_string).collect::<Vec<String>>().join(","));
query_string.finish()
};
if !query_string.is_empty() {
@ -2514,7 +2521,7 @@ impl<S, C> Api<C> for Client<S, C> where
let additional_metadata_str = match serde_json::to_string(&param_additional_metadata) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse additional_metadata to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize additional_metadata to string: {}", e))),
};
let additional_metadata_vec = additional_metadata_str.as_bytes().to_vec();
@ -2526,7 +2533,7 @@ impl<S, C> Api<C> for Client<S, C> where
let file_str = match serde_json::to_string(&param_file) {
Ok(str) => str,
Err(e) => return Err(ApiError(format!("Unable to parse file to string: {}", e))),
Err(e) => return Err(ApiError(format!("Unable to serialize file to string: {}", e))),
};
let file_vec = file_str.as_bytes().to_vec();
@ -3386,8 +3393,10 @@ impl<S, C> Api<C> for Client<S, C> where
// Query parameters
let query_string = {
let mut query_string = form_urlencoded::Serializer::new("".to_owned());
query_string.append_pair("username", &param_username.to_string());
query_string.append_pair("password", &param_password.to_string());
query_string.append_pair("username",
&param_username.to_string());
query_string.append_pair("password",
&param_password.to_string());
query_string.finish()
};
if !query_string.is_empty() {

View File

@ -730,17 +730,26 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
let param_query = query_params.iter().filter(|e| e.0 == "query").map(|e| e.1.to_owned())
.nth(0);
let param_query = match param_query {
Some(param_query) => match param_query.parse::<String>() {
Ok(param_query) => param_query,
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter query - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter query")),
Some(param_query) => {
let param_query =
<String as std::str::FromStr>::from_str
(&param_query);
match param_query {
Ok(param_query) => Some(param_query),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter query - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter query")),
}
},
None => None,
};
let param_query = match param_query {
Some(param_query) => param_query,
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter query"))
.expect("Unable to create Bad Request response for missing qeury parameter query")),
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter query"))
.expect("Unable to create Bad Request response for missing query parameter query")),
};
// Body parameters (note that non-required body parameters will ignore garbage
@ -1020,13 +1029,55 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
};
let param_enum_query_string = query_params.iter().filter(|e| e.0 == "enum_query_string").map(|e| e.1.to_owned())
.nth(0);
let param_enum_query_string = param_enum_query_string.and_then(|param_enum_query_string| param_enum_query_string.parse::<>().ok());
let param_enum_query_string = match param_enum_query_string {
Some(param_enum_query_string) => {
let param_enum_query_string =
<String as std::str::FromStr>::from_str
(&param_enum_query_string);
match param_enum_query_string {
Ok(param_enum_query_string) => Some(param_enum_query_string),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter enum_query_string - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter enum_query_string")),
}
},
None => None,
};
let param_enum_query_integer = query_params.iter().filter(|e| e.0 == "enum_query_integer").map(|e| e.1.to_owned())
.nth(0);
let param_enum_query_integer = param_enum_query_integer.and_then(|param_enum_query_integer| param_enum_query_integer.parse::<>().ok());
let param_enum_query_integer = match param_enum_query_integer {
Some(param_enum_query_integer) => {
let param_enum_query_integer =
<i32 as std::str::FromStr>::from_str
(&param_enum_query_integer);
match param_enum_query_integer {
Ok(param_enum_query_integer) => Some(param_enum_query_integer),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter enum_query_integer - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter enum_query_integer")),
}
},
None => None,
};
let param_enum_query_double = query_params.iter().filter(|e| e.0 == "enum_query_double").map(|e| e.1.to_owned())
.nth(0);
let param_enum_query_double = param_enum_query_double.and_then(|param_enum_query_double| param_enum_query_double.parse::<>().ok());
let param_enum_query_double = match param_enum_query_double {
Some(param_enum_query_double) => {
let param_enum_query_double =
<f64 as std::str::FromStr>::from_str
(&param_enum_query_double);
match param_enum_query_double {
Ok(param_enum_query_double) => Some(param_enum_query_double),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter enum_query_double - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter enum_query_double")),
}
},
None => None,
};
// Form parameters
let param_enum_form_string = Some("enum_form_string_example".to_string());
@ -2686,32 +2737,50 @@ impl<T, C> hyper::service::Service<(Request<Body>, C)> for Service<T, C> where
let param_username = query_params.iter().filter(|e| e.0 == "username").map(|e| e.1.to_owned())
.nth(0);
let param_username = match param_username {
Some(param_username) => match param_username.parse::<String>() {
Ok(param_username) => param_username,
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter username - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter username")),
Some(param_username) => {
let param_username =
<String as std::str::FromStr>::from_str
(&param_username);
match param_username {
Ok(param_username) => Some(param_username),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter username - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter username")),
}
},
None => None,
};
let param_username = match param_username {
Some(param_username) => param_username,
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter username"))
.expect("Unable to create Bad Request response for missing qeury parameter username")),
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter username"))
.expect("Unable to create Bad Request response for missing query parameter username")),
};
let param_password = query_params.iter().filter(|e| e.0 == "password").map(|e| e.1.to_owned())
.nth(0);
let param_password = match param_password {
Some(param_password) => match param_password.parse::<String>() {
Ok(param_password) => param_password,
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter password - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter password")),
Some(param_password) => {
let param_password =
<String as std::str::FromStr>::from_str
(&param_password);
match param_password {
Ok(param_password) => Some(param_password),
Err(e) => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from(format!("Couldn't parse query parameter password - doesn't match schema: {}", e)))
.expect("Unable to create Bad Request response for invalid query parameter password")),
}
},
None => None,
};
let param_password = match param_password {
Some(param_password) => param_password,
None => return Ok(Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter password"))
.expect("Unable to create Bad Request response for missing qeury parameter password")),
.status(StatusCode::BAD_REQUEST)
.body(Body::from("Missing required query parameter password"))
.expect("Unable to create Bad Request response for missing query parameter password")),
};
let result = api_impl.login_user(