[Rust Server] Handle numeric response description (#5452)

* [Rust Server] Handle response descriptions which start with a number.
* [Rust Server] Add test for numeric response descriptions
* Update samples
This commit is contained in:
Richard Whitehouse
2020-02-29 14:54:47 +00:00
committed by GitHub
parent f5c5b91f83
commit a6e96b4971
11 changed files with 211 additions and 30 deletions

View File

@@ -700,7 +700,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
if (rsp.vendorExtensions.containsKey("x-responseId")) {
// If it's been specified directly, use that.
responseId = (String) rsp.vendorExtensions.get("x-responseId");
} else if (words.length != 0) {
} else if ((words.length != 0) && (words[0].trim().length() != 0)) {
// If there's a description, build it from the description.
responseId = camelize(words[0].replace(" ", "_"));
} else {

View File

@@ -965,6 +965,14 @@ paths:
responses:
200:
description: Success
/fake/response-with-numerical-description:
get:
tags:
- fake
operationId: fake_response_with_numerical_description
responses:
200:
description: 1234
securityDefinitions:
petstore_auth:
type: oauth2

View File

@@ -66,6 +66,7 @@ cargo run --example client FakeOuterBooleanSerialize
cargo run --example client FakeOuterCompositeSerialize
cargo run --example client FakeOuterNumberSerialize
cargo run --example client FakeOuterStringSerialize
cargo run --example client FakeResponseWithNumericalDescription
cargo run --example client HyphenParam
cargo run --example client TestBodyWithQueryParams
cargo run --example client TestClientModel
@@ -132,6 +133,7 @@ Method | HTTP request | Description
[**fakeOuterCompositeSerialize**](docs/fake_api.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite |
[**fakeOuterNumberSerialize**](docs/fake_api.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number |
[**fakeOuterStringSerialize**](docs/fake_api.md#fakeOuterStringSerialize) | **POST** /fake/outer/string |
[**fake_response_with_numerical_description**](docs/fake_api.md#fake_response_with_numerical_description) | **GET** /fake/response-with-numerical-description |
[**hyphenParam**](docs/fake_api.md#hyphenParam) | **GET** /fake/hyphenParam/{hyphen-param} |
[**testBodyWithQueryParams**](docs/fake_api.md#testBodyWithQueryParams) | **PUT** /fake/body-with-query-params |
[**testClientModel**](docs/fake_api.md#testClientModel) | **PATCH** /fake | To test \"client\" model

View File

@@ -1001,6 +1001,15 @@ paths:
description: Success
tags:
- fake
/fake/response-with-numerical-description:
get:
operationId: fake_response_with_numerical_description
responses:
"200":
content: {}
description: "1234"
tags:
- fake
components:
schemas:
Order:

View File

@@ -1,14 +0,0 @@
# NullableTest
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**nullable** | **String** | |
**nullable_with_null_default** | **String** | | [optional] [default to None]
**nullable_with_present_default** | **String** | | [optional] [default to Some("default".to_string())]
**nullable_with_no_default** | **String** | | [optional] [default to None]
**nullable_array** | **Vec<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)

View File

@@ -8,6 +8,7 @@ Method | HTTP request | Description
**fakeOuterCompositeSerialize**](fake_api.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite |
**fakeOuterNumberSerialize**](fake_api.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number |
**fakeOuterStringSerialize**](fake_api.md#fakeOuterStringSerialize) | **POST** /fake/outer/string |
**fake_response_with_numerical_description**](fake_api.md#fake_response_with_numerical_description) | **GET** /fake/response-with-numerical-description |
**hyphenParam**](fake_api.md#hyphenParam) | **GET** /fake/hyphenParam/{hyphen-param} |
**testBodyWithQueryParams**](fake_api.md#testBodyWithQueryParams) | **PUT** /fake/body-with-query-params |
**testClientModel**](fake_api.md#testClientModel) | **PATCH** /fake | To test \"client\" model
@@ -153,6 +154,28 @@ 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)
# **fake_response_with_numerical_description**
> fake_response_with_numerical_description()
### Required Parameters
This endpoint does not need any parameter.
### 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)
# **hyphenParam**
> hyphenParam(hyphen_param)

View File

@@ -19,6 +19,7 @@ use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Client,
FakeOuterCompositeSerializeResponse,
FakeOuterNumberSerializeResponse,
FakeOuterStringSerializeResponse,
FakeResponseWithNumericalDescriptionResponse,
HyphenParamResponse,
TestBodyWithQueryParamsResponse,
TestClientModelResponse,
@@ -64,6 +65,8 @@ fn main() {
"FakeOuterStringSerialize",
"FakeResponseWithNumericalDescription",
"HyphenParam",
"TestEndpointParameters",
@@ -188,6 +191,13 @@ fn main() {
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
Some("FakeResponseWithNumericalDescription") => {
let mut rt = tokio::runtime::Runtime::new().unwrap();
let result = rt.block_on(client.fake_response_with_numerical_description(
));
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
},
Some("HyphenParam") => {
let mut rt = tokio::runtime::Runtime::new().unwrap();
let result = rt.block_on(client.hyphen_param(

View File

@@ -22,6 +22,7 @@ use petstore_with_fake_endpoints_models_for_testing::{Api, ApiError,
FakeOuterCompositeSerializeResponse,
FakeOuterNumberSerializeResponse,
FakeOuterStringSerializeResponse,
FakeResponseWithNumericalDescriptionResponse,
HyphenParamResponse,
TestBodyWithQueryParamsResponse,
TestClientModelResponse,
@@ -102,6 +103,13 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
}
fn fake_response_with_numerical_description(&self, context: &C) -> Box<Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send> {
let context = context.clone();
println!("fake_response_with_numerical_description() - X-Span-ID: {:?}", context.get().0.clone());
Box::new(futures::failed("Generic failure".into()))
}
fn hyphen_param(&self, hyphen_param: String, context: &C) -> Box<Future<Item=HyphenParamResponse, Error=ApiError> + Send> {
let context = context.clone();
println!("hyphen_param(\"{}\") - X-Span-ID: {:?}", hyphen_param, context.get().0.clone());

View File

@@ -37,6 +37,7 @@ use {Api,
FakeOuterCompositeSerializeResponse,
FakeOuterNumberSerializeResponse,
FakeOuterStringSerializeResponse,
FakeResponseWithNumericalDescriptionResponse,
HyphenParamResponse,
TestBodyWithQueryParamsResponse,
TestClientModelResponse,
@@ -704,6 +705,77 @@ impl<C, F> Api<C> for Client<F> where
}
fn fake_response_with_numerical_description(&self, context: &C) -> Box<dyn Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send> {
let mut uri = format!(
"{}/v2/fake/response-with-numerical-description",
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<XSpanIdString>).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(
future::ok(
FakeResponseWithNumericalDescriptionResponse::Status200
)
) as Box<dyn Future<Item=_, Error=_> + 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!("<Body was not UTF8: {:?}>", e)),
},
Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
})))
)
) as Box<dyn Future<Item=_, Error=_> + Send>
}
}
}))
}
fn hyphen_param(&self, param_hyphen_param: String, context: &C) -> Box<dyn Future<Item=HyphenParamResponse, Error=ApiError> + Send> {
let mut uri = format!(
"{}/v2/fake/hyphenParam/{hyphen_param}",

View File

@@ -113,6 +113,12 @@ pub enum FakeOuterStringSerializeResponse {
( String )
}
#[derive(Debug, PartialEq)]
pub enum FakeResponseWithNumericalDescriptionResponse {
/// 1234
Status200
}
#[derive(Debug, PartialEq)]
pub enum HyphenParamResponse {
/// Success
@@ -367,6 +373,9 @@ pub trait Api<C> {
fn fake_outer_string_serialize(&self, body: Option<models::OuterString>, context: &C) -> Box<dyn Future<Item=FakeOuterStringSerializeResponse, Error=ApiError> + Send>;
fn fake_response_with_numerical_description(&self, context: &C) -> Box<dyn Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send>;
fn hyphen_param(&self, hyphen_param: String, context: &C) -> Box<dyn Future<Item=HyphenParamResponse, Error=ApiError> + Send>;
@@ -471,6 +480,9 @@ pub trait ApiNoContext {
fn fake_outer_string_serialize(&self, body: Option<models::OuterString>) -> Box<dyn Future<Item=FakeOuterStringSerializeResponse, Error=ApiError> + Send>;
fn fake_response_with_numerical_description(&self) -> Box<dyn Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send>;
fn hyphen_param(&self, hyphen_param: String) -> Box<dyn Future<Item=HyphenParamResponse, Error=ApiError> + Send>;
@@ -596,6 +608,11 @@ impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
}
fn fake_response_with_numerical_description(&self) -> Box<dyn Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send> {
self.api().fake_response_with_numerical_description(&self.context())
}
fn hyphen_param(&self, hyphen_param: String) -> Box<dyn Future<Item=HyphenParamResponse, Error=ApiError> + Send> {
self.api().hyphen_param(hyphen_param, &self.context())
}

View File

@@ -28,6 +28,7 @@ use {Api,
FakeOuterCompositeSerializeResponse,
FakeOuterNumberSerializeResponse,
FakeOuterStringSerializeResponse,
FakeResponseWithNumericalDescriptionResponse,
HyphenParamResponse,
TestBodyWithQueryParamsResponse,
TestClientModelResponse,
@@ -79,6 +80,7 @@ mod paths {
r"^/v2/fake/outer/composite$",
r"^/v2/fake/outer/number$",
r"^/v2/fake/outer/string$",
r"^/v2/fake/response-with-numerical-description$",
r"^/v2/fake_classname_test$",
r"^/v2/pet$",
r"^/v2/pet/findByStatus$",
@@ -112,36 +114,37 @@ mod paths {
pub static ID_FAKE_OUTER_COMPOSITE: usize = 7;
pub static ID_FAKE_OUTER_NUMBER: usize = 8;
pub static ID_FAKE_OUTER_STRING: usize = 9;
pub static ID_FAKE_CLASSNAME_TEST: usize = 10;
pub static ID_PET: usize = 11;
pub static ID_PET_FINDBYSTATUS: usize = 12;
pub static ID_PET_FINDBYTAGS: usize = 13;
pub static ID_PET_PETID: usize = 14;
pub static ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION: usize = 10;
pub static ID_FAKE_CLASSNAME_TEST: usize = 11;
pub static ID_PET: usize = 12;
pub static ID_PET_FINDBYSTATUS: usize = 13;
pub static ID_PET_FINDBYTAGS: usize = 14;
pub static ID_PET_PETID: usize = 15;
lazy_static! {
pub static ref REGEX_PET_PETID: regex::Regex =
regex::Regex::new(r"^/v2/pet/(?P<pet_id>[^/?#]*)$")
.expect("Unable to create regex for PET_PETID");
}
pub static ID_PET_PETID_UPLOADIMAGE: usize = 15;
pub static ID_PET_PETID_UPLOADIMAGE: usize = 16;
lazy_static! {
pub static ref REGEX_PET_PETID_UPLOADIMAGE: regex::Regex =
regex::Regex::new(r"^/v2/pet/(?P<pet_id>[^/?#]*)/uploadImage$")
.expect("Unable to create regex for PET_PETID_UPLOADIMAGE");
}
pub static ID_STORE_INVENTORY: usize = 16;
pub static ID_STORE_ORDER: usize = 17;
pub static ID_STORE_ORDER_ORDER_ID: usize = 18;
pub static ID_STORE_INVENTORY: usize = 17;
pub static ID_STORE_ORDER: usize = 18;
pub static ID_STORE_ORDER_ORDER_ID: usize = 19;
lazy_static! {
pub static ref REGEX_STORE_ORDER_ORDER_ID: regex::Regex =
regex::Regex::new(r"^/v2/store/order/(?P<order_id>[^/?#]*)$")
.expect("Unable to create regex for STORE_ORDER_ORDER_ID");
}
pub static ID_USER: usize = 19;
pub static ID_USER_CREATEWITHARRAY: usize = 20;
pub static ID_USER_CREATEWITHLIST: usize = 21;
pub static ID_USER_LOGIN: usize = 22;
pub static ID_USER_LOGOUT: usize = 23;
pub static ID_USER_USERNAME: usize = 24;
pub static ID_USER: usize = 20;
pub static ID_USER_CREATEWITHARRAY: usize = 21;
pub static ID_USER_CREATEWITHLIST: usize = 22;
pub static ID_USER_LOGIN: usize = 23;
pub static ID_USER_LOGOUT: usize = 24;
pub static ID_USER_USERNAME: usize = 25;
lazy_static! {
pub static ref REGEX_USER_USERNAME: regex::Regex =
regex::Regex::new(r"^/v2/user/(?P<username>[^/?#]*)$")
@@ -640,6 +643,46 @@ where
) as Self::Future
},
// FakeResponseWithNumericalDescription - GET /fake/response-with-numerical-description
&hyper::Method::GET if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => {
Box::new({
{{
Box::new(
api_impl.fake_response_with_numerical_description(
&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<XSpanIdString>).get().0.clone().to_string().as_str())
.expect("Unable to create X-Span-ID header value"));
match result {
Ok(rsp) => match rsp {
FakeResponseWithNumericalDescriptionResponse::Status200
=> {
*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");
},
}
future::ok(response)
}
))
}}
}) as Self::Future
},
// HyphenParam - GET /fake/hyphenParam/{hyphen-param}
&hyper::Method::GET if path.matched(paths::ID_FAKE_HYPHENPARAM_HYPHEN_PARAM) => {
// Path parameters
@@ -3256,6 +3299,9 @@ impl<T> RequestParser<T> for ApiRequestParser {
// FakeOuterStringSerialize - POST /fake/outer/string
&hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_STRING) => Ok("FakeOuterStringSerialize"),
// FakeResponseWithNumericalDescription - GET /fake/response-with-numerical-description
&hyper::Method::GET if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => Ok("FakeResponseWithNumericalDescription"),
// HyphenParam - GET /fake/hyphenParam/{hyphen-param}
&hyper::Method::GET if path.matched(paths::ID_FAKE_HYPHENPARAM_HYPHEN_PARAM) => Ok("HyphenParam"),