diff --git a/modules/openapi-generator/src/test/resources/2_0/rust-server/rust-server-test.yaml b/modules/openapi-generator/src/test/resources/2_0/rust-server/rust-server-test.yaml index d589c30c570..c7937795ced 100644 --- a/modules/openapi-generator/src/test/resources/2_0/rust-server/rust-server-test.yaml +++ b/modules/openapi-generator/src/test/resources/2_0/rust-server/rust-server-test.yaml @@ -9,10 +9,12 @@ paths: /dummy: get: summary: A dummy endpoint to make the spec valid. + operationId: dummyGet responses: '200': description: Success put: + operationId: dummyPut parameters: - $ref: '#/parameters/nested_response' responses: @@ -23,6 +25,7 @@ paths: summary: Test HTML handling consumes: [text/html] produces: [text/html] + operationId: htmlPost parameters: - in: body name: body @@ -37,6 +40,7 @@ paths: /file_response: get: summary: Get a file + operationId: file_responseGet produces: - application/json responses: @@ -47,6 +51,7 @@ paths: /raw_json: get: summary: Get an arbitrary JSON blob. + operationId: raw_jsonGet responses: 200: description: Success @@ -55,6 +60,7 @@ paths: /solo-object: post: summary: Send an arbitrary JSON blob + operationId: solo_objectPost consumes: - application/json parameters: @@ -93,6 +99,15 @@ paths: description: OK schema: $ref: '#/definitions/get_yaml_response' + /allOf: + get: + description: Test getting an object which uses allOf + operationId: AllOf_Get + responses: + '200': + description: OK + schema: + $ref: '#/definitions/allOfObject' parameters: nested_response: @@ -115,6 +130,17 @@ definitions: additionalProperties: type: string example: "foo" + allOfObject: + properties: + sampleProperty: + type: string + allOf: + - $ref: '#/definitions/baseAllOf' + baseAllOf: + type: object + properties: + sampleBasePropery: + type: string aNullableContainer: type: object properties: diff --git a/samples/server/petstore/rust-server/output/rust-server-test/README.md b/samples/server/petstore/rust-server/output/rust-server-test/README.md index 5cf463d2616..13d136522ec 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/README.md +++ b/samples/server/petstore/rust-server/output/rust-server-test/README.md @@ -61,6 +61,7 @@ cargo run --example server To run a client, follow one of the following simple steps: ``` +cargo run --example client AllOfGet cargo run --example client DummyGet cargo run --example client FileResponseGet cargo run --example client GetStructuredYaml @@ -100,20 +101,23 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- -[****](docs/default_api.md#) | **GET** /dummy | A dummy endpoint to make the spec valid. -[****](docs/default_api.md#) | **PUT** /dummy | -[****](docs/default_api.md#) | **GET** /file_response | Get a file +[**AllOf_Get**](docs/default_api.md#AllOf_Get) | **GET** /allOf | +[**dummyGet**](docs/default_api.md#dummyGet) | **GET** /dummy | A dummy endpoint to make the spec valid. +[**dummyPut**](docs/default_api.md#dummyPut) | **PUT** /dummy | +[**file_responseGet**](docs/default_api.md#file_responseGet) | **GET** /file_response | Get a file [**getStructuredYaml**](docs/default_api.md#getStructuredYaml) | **GET** /get-structured-yaml | -[****](docs/default_api.md#) | **POST** /html | Test HTML handling +[**htmlPost**](docs/default_api.md#htmlPost) | **POST** /html | Test HTML handling [**post_yaml**](docs/default_api.md#post_yaml) | **POST** /post-yaml | -[****](docs/default_api.md#) | **GET** /raw_json | Get an arbitrary JSON blob. -[****](docs/default_api.md#) | **POST** /solo-object | Send an arbitrary JSON blob +[**raw_jsonGet**](docs/default_api.md#raw_jsonGet) | **GET** /raw_json | Get an arbitrary JSON blob. +[**solo_objectPost**](docs/default_api.md#solo_objectPost) | **POST** /solo-object | Send an arbitrary JSON blob ## Documentation For Models - [ANullableContainer](docs/ANullableContainer.md) - [AdditionalPropertiesObject](docs/AdditionalPropertiesObject.md) + - [AllOfObject](docs/AllOfObject.md) + - [BaseAllOf](docs/BaseAllOf.md) - [GetYamlResponse](docs/GetYamlResponse.md) - [InlineObject](docs/InlineObject.md) - [ObjectOfObjects](docs/ObjectOfObjects.md) diff --git a/samples/server/petstore/rust-server/output/rust-server-test/api/openapi.yaml b/samples/server/petstore/rust-server/output/rust-server-test/api/openapi.yaml index 03e6237b4a9..276349f7a0e 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/api/openapi.yaml +++ b/samples/server/petstore/rust-server/output/rust-server-test/api/openapi.yaml @@ -8,12 +8,14 @@ servers: paths: /dummy: get: + operationId: dummyGet responses: "200": content: {} description: Success summary: A dummy endpoint to make the spec valid. put: + operationId: dummyPut requestBody: $ref: '#/components/requestBodies/inline_object' content: @@ -35,6 +37,7 @@ paths: x-codegen-request-body-name: nested_response /html: post: + operationId: htmlPost requestBody: content: text/html: @@ -52,6 +55,7 @@ paths: x-codegen-request-body-name: body /file_response: get: + operationId: file_responseGet responses: "200": content: @@ -63,6 +67,7 @@ paths: summary: Get a file /raw_json: get: + operationId: raw_jsonGet responses: "200": content: @@ -73,6 +78,7 @@ paths: summary: Get an arbitrary JSON blob. /solo-object: post: + operationId: solo_objectPost requestBody: content: application/json: @@ -112,6 +118,17 @@ paths: schema: $ref: '#/components/schemas/get_yaml_response' description: OK + /allOf: + get: + description: Test getting an object which uses allOf + operationId: AllOf_Get + responses: + "200": + content: + '*/*': + schema: + $ref: '#/components/schemas/allOfObject' + description: OK components: requestBodies: nested_response: @@ -140,6 +157,19 @@ components: description: An additionalPropertiesObject example: foo type: object + allOfObject: + allOf: + - $ref: '#/components/schemas/baseAllOf' + example: + sampleProperty: sampleProperty + properties: + sampleProperty: + type: string + baseAllOf: + properties: + sampleBasePropery: + type: string + type: object aNullableContainer: properties: NullableThing: diff --git a/samples/server/petstore/rust-server/output/rust-server-test/docs/AllOfObject.md b/samples/server/petstore/rust-server/output/rust-server-test/docs/AllOfObject.md new file mode 100644 index 00000000000..2c1484d1483 --- /dev/null +++ b/samples/server/petstore/rust-server/output/rust-server-test/docs/AllOfObject.md @@ -0,0 +1,11 @@ +# AllOfObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**sample_property** | **String** | | [optional] [default to None] +**sample_base_propery** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/rust-server-test/docs/BaseAllOf.md b/samples/server/petstore/rust-server/output/rust-server-test/docs/BaseAllOf.md new file mode 100644 index 00000000000..aa39ac24756 --- /dev/null +++ b/samples/server/petstore/rust-server/output/rust-server-test/docs/BaseAllOf.md @@ -0,0 +1,10 @@ +# BaseAllOf + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**sample_base_propery** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/rust-server-test/docs/default_api.md b/samples/server/petstore/rust-server/output/rust-server-test/docs/default_api.md index 003f7bedbad..d64874badde 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/docs/default_api.md +++ b/samples/server/petstore/rust-server/output/rust-server-test/docs/default_api.md @@ -4,18 +4,43 @@ All URIs are relative to *http://localhost* Method | HTTP request | Description ------------- | ------------- | ------------- -****](default_api.md#) | **GET** /dummy | A dummy endpoint to make the spec valid. -****](default_api.md#) | **PUT** /dummy | -****](default_api.md#) | **GET** /file_response | Get a file +**AllOf_Get**](default_api.md#AllOf_Get) | **GET** /allOf | +**dummyGet**](default_api.md#dummyGet) | **GET** /dummy | A dummy endpoint to make the spec valid. +**dummyPut**](default_api.md#dummyPut) | **PUT** /dummy | +**file_responseGet**](default_api.md#file_responseGet) | **GET** /file_response | Get a file **getStructuredYaml**](default_api.md#getStructuredYaml) | **GET** /get-structured-yaml | -****](default_api.md#) | **POST** /html | Test HTML handling +**htmlPost**](default_api.md#htmlPost) | **POST** /html | Test HTML handling **post_yaml**](default_api.md#post_yaml) | **POST** /post-yaml | -****](default_api.md#) | **GET** /raw_json | Get an arbitrary JSON blob. -****](default_api.md#) | **POST** /solo-object | Send an arbitrary JSON blob +**raw_jsonGet**](default_api.md#raw_jsonGet) | **GET** /raw_json | Get an arbitrary JSON blob. +**solo_objectPost**](default_api.md#solo_objectPost) | **POST** /solo-object | Send an arbitrary JSON blob -# **** -> () +# **AllOf_Get** +> models::AllOfObject AllOf_Get() + + +Test getting an object which uses allOf + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::AllOfObject**](allOfObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */*, + +[[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) + +# **dummyGet** +> dummyGet() A dummy endpoint to make the spec valid. ### Required Parameters @@ -36,8 +61,8 @@ 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) -# **** -> (nested_response) +# **dummyPut** +> dummyPut(nested_response) ### Required Parameters @@ -61,8 +86,8 @@ 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) -# **** -> swagger::ByteArray () +# **file_responseGet** +> swagger::ByteArray file_responseGet() Get a file ### Required Parameters @@ -107,8 +132,8 @@ 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) -# **** -> String (body) +# **htmlPost** +> String htmlPost(body) Test HTML handling ### Required Parameters @@ -159,8 +184,8 @@ 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) -# **** -> serde_json::Value () +# **raw_jsonGet** +> serde_json::Value raw_jsonGet() Get an arbitrary JSON blob. ### Required Parameters @@ -181,8 +206,8 @@ 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) -# **** -> (value) +# **solo_objectPost** +> solo_objectPost(value) Send an arbitrary JSON blob ### Required Parameters diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs index 403f392450e..733f7f69e6d 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs @@ -14,6 +14,7 @@ use futures::{Future, future, Stream, stream}; #[allow(unused_imports)] use rust_server_test::{Api, ApiNoContext, Client, ContextWrapperExt, ApiError, + AllOfGetResponse, DummyGetResponse, DummyPutResponse, FileResponseGetResponse, @@ -33,6 +34,7 @@ fn main() { .arg(Arg::with_name("operation") .help("Sets the operation to run") .possible_values(&[ + "AllOfGet", "DummyGet", "FileResponseGet", "GetStructuredYaml", @@ -84,6 +86,11 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); match matches.value_of("operation") { + Some("AllOfGet") => { + let result = rt.block_on(client.all_of_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has).get().clone()); + }, Some("DummyGet") => { let result = rt.block_on(client.dummy_get( )); diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs index 60bc3e5e995..1f359b72f9f 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs @@ -87,6 +87,7 @@ impl Server { use rust_server_test::{ Api, ApiError, + AllOfGetResponse, DummyGetResponse, DummyPutResponse, FileResponseGetResponse, @@ -99,6 +100,15 @@ use rust_server_test::{ use rust_server_test::server::MakeService; impl Api for Server where C: Has{ + fn all_of_get( + &self, + context: &C) -> Box + Send> + { + let context = context.clone(); + info!("all_of_get() - X-Span-ID: {:?}", context.get().0.clone()); + Box::new(future::err("Generic failure".into())) + } + /// A dummy endpoint to make the spec valid. fn dummy_get( &self, diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs index 3e9d3003a5f..d10c8c06680 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs @@ -37,6 +37,7 @@ define_encode_set! { } use {Api, + AllOfGetResponse, DummyGetResponse, DummyPutResponse, FileResponseGetResponse, @@ -242,6 +243,89 @@ impl Api for Client where C: Has , F: Future, Error=hyper::Error> + Send + 'static { + fn all_of_get( + &self, + context: &C) -> Box + Send> + { + let mut uri = format!( + "{}/allOf", + self.base_path + ); + + // Query parameters + let mut query_string = url::form_urlencoded::Serializer::new("".to_owned()); + let query_string_str = query_string.finish(); + if !query_string_str.is_empty() { + uri += "?"; + uri += &query_string_str; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))), + }; + + let mut request = match hyper::Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e)))) + }; + + let header = HeaderValue::from_str((context as &dyn Has).get().0.clone().to_string().as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e)))) + }); + + Box::new(self.client_service.request(request) + .map_err(|e| ApiError(format!("No response received: {}", e))) + .and_then(|mut response| { + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + Box::new( + body + .concat2() + .map_err(|e| ApiError(format!("Failed to read response: {}", e))) + .and_then(|body| + str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e))) + .and_then(|body| + serde_json::from_str::(body) + .map_err(|e| e.into()) + ) + ) + .map(move |body| { + AllOfGetResponse::OK + (body) + }) + ) as Box + Send> + }, + code => { + let headers = response.headers().clone(); + Box::new(response.into_body() + .take(100) + .concat2() + .then(move |body| + future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", + code, + headers, + match body { + Ok(ref body) => match str::from_utf8(body) { + Ok(body) => Cow::from(body), + Err(e) => Cow::from(format!("", e)), + }, + Err(e) => Cow::from(format!("", e)), + }))) + ) + ) as Box + Send> + } + } + })) + } + fn dummy_get( &self, context: &C) -> Box + Send> diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs index bb0fbc4f189..0db8e0dd1f0 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs @@ -73,6 +73,13 @@ pub use futures::Future; pub const BASE_PATH: &'static str = ""; pub const API_VERSION: &'static str = "2.3.4"; +#[derive(Debug, PartialEq)] +pub enum AllOfGetResponse { + /// OK + OK + (models::AllOfObject) +} + #[derive(Debug, PartialEq)] pub enum DummyGetResponse { /// Success @@ -127,6 +134,10 @@ pub enum SoloObjectPostResponse { /// API pub trait Api { + fn all_of_get( + &self, + context: &C) -> Box + Send>; + /// A dummy endpoint to make the spec valid. fn dummy_get( &self, @@ -172,6 +183,10 @@ pub trait Api { /// API without a `Context` pub trait ApiNoContext { + fn all_of_get( + &self, + ) -> Box + Send>; + /// A dummy endpoint to make the spec valid. fn dummy_get( &self, @@ -228,6 +243,13 @@ impl<'a, T: Api + Sized, C> ContextWrapperExt<'a, C> for T { } impl<'a, T: Api, C> ApiNoContext for ContextWrapper<'a, T, C> { + fn all_of_get( + &self, + ) -> Box + Send> + { + self.api().all_of_get(&self.context()) + } + /// A dummy endpoint to make the spec valid. fn dummy_get( &self, diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/mimetypes.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/mimetypes.rs index a0cec6d51dd..acdd6186f6e 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/mimetypes.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/mimetypes.rs @@ -1,6 +1,9 @@ /// mime types for requests and responses pub mod responses { + /// Create &str objects for the response content types for AllOfGet + pub static ALL_OF_GET_OK: &str = "*/*"; + /// Create &str objects for the response content types for FileResponseGet @@ -21,6 +24,7 @@ pub mod responses { pub mod requests { + /// Create &str objects for the request content types for DummyPut pub static DUMMY_PUT: &str = "application/json"; diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs index 447a8e3841e..ab8b5d92c3f 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs @@ -171,6 +171,206 @@ impl ::std::str::FromStr for AdditionalPropertiesObject { } +// Methods for converting between IntoHeaderValue and HeaderValue + +impl From> for HeaderValue { + fn from(hdr_value: IntoHeaderValue) -> Self { + HeaderValue::from_str(&hdr_value.to_string()).unwrap() + } +} + +impl From for IntoHeaderValue { + fn from(hdr_value: HeaderValue) -> Self { + IntoHeaderValue(AllOfObject::from_str(hdr_value.to_str().unwrap()).unwrap()) + } +} + + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "conversion", derive(LabelledGeneric))] +pub struct AllOfObject { + #[serde(rename = "sampleProperty")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_property: Option, + + #[serde(rename = "sampleBasePropery")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_base_propery: Option, + +} + +impl AllOfObject { + pub fn new() -> AllOfObject { + AllOfObject { + sample_property: None, + sample_base_propery: None, + } + } +} + +/// Converts the AllOfObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AllOfObject { + fn to_string(&self) -> String { + let mut params: Vec = vec![]; + + if let Some(ref sample_property) = self.sample_property { + params.push("sampleProperty".to_string()); + params.push(sample_property.to_string()); + } + + + if let Some(ref sample_base_propery) = self.sample_base_propery { + params.push("sampleBasePropery".to_string()); + params.push(sample_base_propery.to_string()); + } + + params.join(",").to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AllOfObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AllOfObject { + type Err = (); + + fn from_str(s: &str) -> Result { + #[derive(Default)] + // An intermediate representation of the struct to use for parsing. + struct IntermediateRep { + pub sample_property: Vec, + pub sample_base_propery: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(',').into_iter(); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return Err(()) + }; + + if let Some(key) = key_result { + match key { + "sampleProperty" => intermediate_rep.sample_property.push(String::from_str(val).map_err(|x| ())?), + "sampleBasePropery" => intermediate_rep.sample_base_propery.push(String::from_str(val).map_err(|x| ())?), + _ => return Err(()) // Parse error - unexpected key + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + Ok(AllOfObject { + sample_property: intermediate_rep.sample_property.into_iter().next(), + sample_base_propery: intermediate_rep.sample_base_propery.into_iter().next(), + }) + } +} + + + +// Methods for converting between IntoHeaderValue and HeaderValue + +impl From> for HeaderValue { + fn from(hdr_value: IntoHeaderValue) -> Self { + HeaderValue::from_str(&hdr_value.to_string()).unwrap() + } +} + +impl From for IntoHeaderValue { + fn from(hdr_value: HeaderValue) -> Self { + IntoHeaderValue(BaseAllOf::from_str(hdr_value.to_str().unwrap()).unwrap()) + } +} + + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "conversion", derive(LabelledGeneric))] +pub struct BaseAllOf { + #[serde(rename = "sampleBasePropery")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_base_propery: Option, + +} + +impl BaseAllOf { + pub fn new() -> BaseAllOf { + BaseAllOf { + sample_base_propery: None, + } + } +} + +/// Converts the BaseAllOf value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for BaseAllOf { + fn to_string(&self) -> String { + let mut params: Vec = vec![]; + + if let Some(ref sample_base_propery) = self.sample_base_propery { + params.push("sampleBasePropery".to_string()); + params.push(sample_base_propery.to_string()); + } + + params.join(",").to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a BaseAllOf value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for BaseAllOf { + type Err = (); + + fn from_str(s: &str) -> Result { + #[derive(Default)] + // An intermediate representation of the struct to use for parsing. + struct IntermediateRep { + pub sample_base_propery: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(',').into_iter(); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return Err(()) + }; + + if let Some(key) = key_result { + match key { + "sampleBasePropery" => intermediate_rep.sample_base_propery.push(String::from_str(val).map_err(|x| ())?), + _ => return Err(()) // Parse error - unexpected key + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + Ok(BaseAllOf { + sample_base_propery: intermediate_rep.sample_base_propery.into_iter().next(), + }) + } +} + + + /// structured response // Methods for converting between IntoHeaderValue and HeaderValue diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs index 85e47e67605..56a06660da8 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs @@ -23,6 +23,7 @@ use header; pub use crate::context; use {Api, + AllOfGetResponse, DummyGetResponse, DummyPutResponse, FileResponseGetResponse, @@ -38,6 +39,7 @@ mod paths { lazy_static! { pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/allOf$", r"^/dummy$", r"^/file_response$", r"^/get-structured-yaml$", @@ -48,13 +50,14 @@ mod paths { ]) .expect("Unable to create global regex set"); } - pub static ID_DUMMY: usize = 0; - pub static ID_FILE_RESPONSE: usize = 1; - pub static ID_GET_STRUCTURED_YAML: usize = 2; - pub static ID_HTML: usize = 3; - pub static ID_POST_YAML: usize = 4; - pub static ID_RAW_JSON: usize = 5; - pub static ID_SOLO_OBJECT: usize = 6; + pub static ID_ALLOF: usize = 0; + pub static ID_DUMMY: usize = 1; + pub static ID_FILE_RESPONSE: usize = 2; + pub static ID_GET_STRUCTURED_YAML: usize = 3; + pub static ID_HTML: usize = 4; + pub static ID_POST_YAML: usize = 5; + pub static ID_RAW_JSON: usize = 6; + pub static ID_SOLO_OBJECT: usize = 7; } pub struct MakeService { @@ -131,6 +134,49 @@ where match &method { + // AllOfGet - GET /allOf + &hyper::Method::GET if path.matched(paths::ID_ALLOF) => { + Box::new({ + {{ + Box::new( + api_impl.all_of_get( + &context + ).then(move |result| { + 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 { + AllOfGetResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str(mimetypes::responses::ALL_OF_GET_OK) + .expect("Unable to create Content-Type header for ALL_OF_GET_OK")); + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + }, + }, + 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"); + }, + } + + future::ok(response) + } + )) + }} + }) as Self::Future + }, + // DummyGet - GET /dummy &hyper::Method::GET if path.matched(paths::ID_DUMMY) => { Box::new({ @@ -620,6 +666,8 @@ impl RequestParser for ApiRequestParser { fn parse_operation_id(request: &Request) -> Result<&'static str, ()> { let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); match request.method() { + // AllOfGet - GET /allOf + &hyper::Method::GET if path.matched(paths::ID_ALLOF) => Ok("AllOfGet"), // DummyGet - GET /dummy &hyper::Method::GET if path.matched(paths::ID_DUMMY) => Ok("DummyGet"), // DummyPut - PUT /dummy