From c094effd900bb80a54200cedc51f2d9d06a966c7 Mon Sep 17 00:00:00 2001 From: Richard Whitehouse Date: Mon, 15 Jun 2020 23:06:03 +0100 Subject: [PATCH] [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 --- .../openapitools/codegen/DefaultCodegen.java | 15 +- .../codegen/languages/RustServerCodegen.java | 7 + .../rust-server/client-operation.mustache | 20 +- .../rust-server/server-operation.mustache | 86 +++++--- .../resources/3_0/rust-server/openapi-v3.yaml | 14 ++ .../output/multipart-v3/src/client/mod.rs | 6 +- .../rust-server/output/openapi-v3/README.md | 2 + .../output/openapi-v3/api/openapi.yaml | 17 ++ .../output/openapi-v3/docs/default_api.md | 33 +++ .../output/openapi-v3/examples/client/main.rs | 8 + .../openapi-v3/examples/server/server.rs | 11 + .../output/openapi-v3/src/client/mod.rs | 96 ++++++++- .../rust-server/output/openapi-v3/src/lib.rs | 25 +++ .../output/openapi-v3/src/server/mod.rs | 194 ++++++++++++++---- .../src/client/mod.rs | 31 ++- .../src/server/mod.rs | 129 +++++++++--- 16 files changed, 573 insertions(+), 121 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index a5db5abb78a..9e162388161 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -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 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."); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java index 20d00b74901..fabaad68a99 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java @@ -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); } diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache index cc6ed88b390..8db0196e44b 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache @@ -36,7 +36,23 @@ {{^required}} if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { {{/required}} - query_string.append_pair("{{{baseName}}}", ¶m_{{{paramName}}}{{#isListContainer}}.iter().map(ToString::to_string).collect::>().join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); + query_string.append_pair("{{{baseName}}}", + {{#vendorExtensions}} + {{#x-consumes-json}} + &match serde_json::to_string(¶m_{{{paramName}}}) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {}", e))), + }); + {{/x-consumes-json}} + {{^x-consumes-json}} + {{#isListContainer}} + ¶m_{{{paramName}}}.iter().map(ToString::to_string).collect::>().join(",")); + {{/isListContainer}} + {{^isListContainer}} + ¶m_{{{paramName}}}.to_string()); + {{/isListContainer}} + {{/x-consumes-json}} + {{/vendorExtensions}} {{^required}} } {{/required}} @@ -87,7 +103,7 @@ {{#jsonSchema}} let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{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(); diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache index 1d649007d59..106a0f71970 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache @@ -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::>(); -{{/-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::>(); -{{^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}}}> + (¶m_{{{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}} + (¶m_{{{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}} diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml index c7307396819..f059f8dba91 100644 --- a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml @@ -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: diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs index f8a1b3204de..e72d476174f 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs @@ -574,7 +574,7 @@ impl Api for Client where let string_field_str = match serde_json::to_string(¶m_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 Api for Client where let optional_string_field_str = match serde_json::to_string(¶m_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 Api for Client where let object_field_str = match serde_json::to_string(¶m_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(); diff --git a/samples/server/petstore/rust-server/output/openapi-v3/README.md b/samples/server/petstore/rust-server/output/openapi-v3/README.md index e1a9ab8fd9f..b0fc2ee15f1 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/README.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/README.md @@ -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. diff --git a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml index 41ce3522464..907d126e3da 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml +++ b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml @@ -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: diff --git a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md index a6a5027eb0d..3271e66c40c 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md @@ -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) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs index 633d4e31914..700e2ff2235 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs @@ -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).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).get().clone()); + }, Some("MandatoryRequestHeaderGet") => { let result = rt.block_on(client.mandatory_request_header_get( "x_header_example".to_string() diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs index 9377679f314..8df91e373f7 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs @@ -99,6 +99,7 @@ use openapi_v3::{ CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, EnumInPathPathParamGetResponse, + JsonComplexQueryParamGetResponse, MandatoryRequestHeaderGetResponse, MergePatchJsonGetResponse, MultigetGetResponse, @@ -157,6 +158,16 @@ impl Api for Server where C: Has + Send + Sync Err("Generic failuare".into()) } + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result + { + 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, diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs index a743fff459d..c7fe120a0fe 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs @@ -39,6 +39,7 @@ use crate::{Api, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, EnumInPathPathParamGetResponse, + JsonComplexQueryParamGetResponse, MandatoryRequestHeaderGetResponse, MergePatchJsonGetResponse, MultigetGetResponse, @@ -418,7 +419,8 @@ impl Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("url", ¶m_url.to_string()); + query_string.append_pair("url", + ¶m_url.to_string()); query_string.finish() }; if !query_string.is_empty() { @@ -490,7 +492,8 @@ impl Api for Client 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", ¶m_list_of_strings.iter().map(ToString::to_string).collect::>().join(",")); + query_string.append_pair("list-of-strings", + ¶m_list_of_strings.iter().map(ToString::to_string).collect::>().join(",")); } query_string.finish() }; @@ -619,6 +622,83 @@ impl Api for Client where } } + async fn json_complex_query_param_get( + &self, + param_list_of_strings: Option<&Vec>, + context: &C) -> Result + { + 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(¶m_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::::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!("", e), + }, + Err(e) => format!("", e), + } + ))) + } + } + } + async fn mandatory_request_header_get( &self, param_x_header: String, @@ -1095,13 +1175,16 @@ impl Api for Client 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", ¶m_uuid.to_string()); + query_string.append_pair("uuid", + ¶m_uuid.to_string()); } if let Some(param_some_object) = param_some_object { - query_string.append_pair("someObject", ¶m_some_object.to_string()); + query_string.append_pair("someObject", + ¶m_some_object.to_string()); } if let Some(param_some_list) = param_some_list { - query_string.append_pair("someList", ¶m_some_list.to_string()); + query_string.append_pair("someList", + ¶m_some_list.to_string()); } query_string.finish() }; @@ -1265,7 +1348,8 @@ impl Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("url", ¶m_url.to_string()); + query_string.append_pair("url", + ¶m_url.to_string()); query_string.finish() }; if !query_string.is_empty() { diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs index 47f01fcbfec..6a269c49f2a 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs @@ -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 { path_param: models::StringEnum, context: &C) -> Result; + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result; + async fn mandatory_request_header_get( &self, x_header: String, @@ -384,6 +395,11 @@ pub trait ApiNoContext { path_param: models::StringEnum, ) -> Result; + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + ) -> Result; + async fn mandatory_request_header_get( &self, x_header: String, @@ -533,6 +549,15 @@ impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext 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>, + ) -> Result + { + 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, diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs index b8454d3afc0..eb6ca983932 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs @@ -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[^/?#]*)$", + 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[^/?#]*)$") .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[^/?#]*)$") .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 where @@ -220,17 +223,26 @@ impl hyper::service::Service<(Request, C)> for Service 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::() { - 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 = + ::from_str + (¶m_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 hyper::service::Service<(Request, C)> for Service 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::>(); + 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::> + (¶m_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).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 hyper::service::Service<(Request, C)> for Service where let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); 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 = + ::from_str + (¶m_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 = + ::from_str + (¶m_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 = + ::from_str + (¶m_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 hyper::service::Service<(Request, C)> for Service 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::() { - 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 = + ::from_str + (¶m_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 hyper::service::Service<(Request, C)> for Service 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 RequestParser 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 diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs index b61fae9bdd3..cdb16442bc4 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs @@ -1080,7 +1080,8 @@ impl Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("query", ¶m_query.to_string()); + query_string.append_pair("query", + ¶m_query.to_string()); query_string.finish() }; if !query_string.is_empty() { @@ -1380,16 +1381,20 @@ impl Api for Client 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", ¶m_enum_query_string_array.iter().map(ToString::to_string).collect::>().join(",")); + query_string.append_pair("enum_query_string_array", + ¶m_enum_query_string_array.iter().map(ToString::to_string).collect::>().join(",")); } if let Some(param_enum_query_string) = param_enum_query_string { - query_string.append_pair("enum_query_string", ¶m_enum_query_string.to_string()); + query_string.append_pair("enum_query_string", + ¶m_enum_query_string.to_string()); } if let Some(param_enum_query_integer) = param_enum_query_integer { - query_string.append_pair("enum_query_integer", ¶m_enum_query_integer.to_string()); + query_string.append_pair("enum_query_integer", + ¶m_enum_query_integer.to_string()); } if let Some(param_enum_query_double) = param_enum_query_double { - query_string.append_pair("enum_query_double", ¶m_enum_query_double.to_string()); + query_string.append_pair("enum_query_double", + ¶m_enum_query_double.to_string()); } query_string.finish() }; @@ -1970,7 +1975,8 @@ impl Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("status", ¶m_status.iter().map(ToString::to_string).collect::>().join(",")); + query_string.append_pair("status", + ¶m_status.iter().map(ToString::to_string).collect::>().join(",")); query_string.finish() }; if !query_string.is_empty() { @@ -2073,7 +2079,8 @@ impl Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("tags", ¶m_tags.iter().map(ToString::to_string).collect::>().join(",")); + query_string.append_pair("tags", + ¶m_tags.iter().map(ToString::to_string).collect::>().join(",")); query_string.finish() }; if !query_string.is_empty() { @@ -2514,7 +2521,7 @@ impl Api for Client where let additional_metadata_str = match serde_json::to_string(¶m_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 Api for Client where let file_str = match serde_json::to_string(¶m_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 Api for Client where // Query parameters let query_string = { let mut query_string = form_urlencoded::Serializer::new("".to_owned()); - query_string.append_pair("username", ¶m_username.to_string()); - query_string.append_pair("password", ¶m_password.to_string()); + query_string.append_pair("username", + ¶m_username.to_string()); + query_string.append_pair("password", + ¶m_password.to_string()); query_string.finish() }; if !query_string.is_empty() { diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs index 0db14487098..a4ea1843810 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs @@ -730,17 +730,26 @@ impl hyper::service::Service<(Request, C)> for Service 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::() { - 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 = + ::from_str + (¶m_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 hyper::service::Service<(Request, C)> for Service 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 = + ::from_str + (¶m_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 = + ::from_str + (¶m_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 = + ::from_str + (¶m_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 hyper::service::Service<(Request, C)> for Service 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::() { - 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 = + ::from_str + (¶m_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::() { - 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 = + ::from_str + (¶m_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(