[rust-server] Drop file support (#547)

* [rust-server] drop 'file' support

In swagger v2, we had 'binary', 'byte', and 'file'. OpenAPI v3 only has
the former two. This commit drops the old 'file' handling. This has the
side-effect of removing a half-complete implementation of form parameter handling.

This removes the ability to send files as streams, so will make life
harder for those wishing to send large files without running out of
memory.

* Remove all remaining uses of `hasFile`
This commit is contained in:
Benjamin Gill 2018-07-23 11:46:35 +01:00 committed by William Cheng
parent af3ca293e4
commit a9961a062a
17 changed files with 238 additions and 788 deletions

View File

@ -164,8 +164,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("date", "chrono::DateTime<chrono::Utc>"); typeMapping.put("date", "chrono::DateTime<chrono::Utc>");
typeMapping.put("DateTime", "chrono::DateTime<chrono::Utc>"); typeMapping.put("DateTime", "chrono::DateTime<chrono::Utc>");
typeMapping.put("password", "String"); typeMapping.put("password", "String");
typeMapping.put("File", "Box<Stream<Item=Vec<u8>, Error=Error> + Send>"); typeMapping.put("File", "swagger::ByteArray");
typeMapping.put("file", "Box<Stream<Item=Vec<u8>, Error=Error> + Send>"); typeMapping.put("file", "swagger::ByteArray");
typeMapping.put("array", "Vec"); typeMapping.put("array", "Vec");
typeMapping.put("map", "HashMap"); typeMapping.put("map", "HashMap");
@ -710,8 +710,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} }
header.nameInCamelCase = toModelName(header.baseName); header.nameInCamelCase = toModelName(header.baseName);
} }
additionalProperties.put("apiHasFile", true);
} }
return objs; return objs;
@ -1069,22 +1067,11 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
private void processParam(CodegenParameter param, CodegenOperation op) { private void processParam(CodegenParameter param, CodegenOperation op) {
String example = null; String example = null;
if (param.isFile) { if (param.isString) {
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "\\\"{}\\\"");
op.vendorExtensions.put("hasFile", true); example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
additionalProperties.put("apiHasFile", true);
example = "Box::new(stream::once(Ok(b\"hello\".to_vec()))) as Box<Stream<Item=_, Error=_> + Send>";
} else if (param.isString) {
if (param.dataFormat != null && param.dataFormat.equals("byte")) {
param.vendorExtensions.put("formatString", "\\\"{:?}\\\"");
example = "swagger::ByteArray(\"" + ((param.example != null) ? param.example : "") + "\".to_string().into_bytes())";
} else {
param.vendorExtensions.put("formatString", "\\\"{}\\\"");
example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
}
} else if (param.isPrimitiveType) { } else if (param.isPrimitiveType) {
if ((param.isByteArray) || if ((param.isByteArray) || (param.isBinary)) {
(param.isBinary)) {
// Binary primitive types don't implement `Display`. // Binary primitive types don't implement `Display`.
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}");
example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))"; example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))";
@ -1119,12 +1106,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
} else { } else {
// Not required, so override the format string and example // Not required, so override the format string and example
param.vendorExtensions.put("formatString", "{:?}"); param.vendorExtensions.put("formatString", "{:?}");
if (param.isFile) { param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None");
// Optional file types are wrapped in a future
param.vendorExtensions.put("example", (example != null) ? "Box::new(future::ok(Some(" + example + "))) as Box<Future<Item=_, Error=_> + Send>" : "None");
} else {
param.vendorExtensions.put("example", (example != null) ? "Some(" + example + ")" : "None");
}
} }
} }
} }

View File

@ -9,8 +9,8 @@ license = "Unlicense"
[features] [features]
default = ["client", "server"] default = ["client", "server"]
client = ["serde_json", {{#usesUrlEncodedForm}}"serde_urlencoded", {{/usesUrlEncodedForm}} {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] client = ["serde_json", {{#usesUrlEncodedForm}}"serde_urlencoded", {{/usesUrlEncodedForm}} {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
server = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}] server = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"]
[dependencies] [dependencies]
# Required by example server. # Required by example server.

View File

@ -6,11 +6,9 @@ extern crate openssl;
extern crate mime; extern crate mime;
extern crate chrono; extern crate chrono;
extern crate url; extern crate url;
{{#apiHasFile}}extern crate multipart;{{/apiHasFile}}
{{#usesUrlEncodedForm}}extern crate serde_urlencoded;{{/usesUrlEncodedForm}} {{#usesUrlEncodedForm}}extern crate serde_urlencoded;{{/usesUrlEncodedForm}}
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} {{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
{{#apiHasFile}}use self::multipart::client::lazy::Multipart;{{/apiHasFile}}
use hyper; use hyper;
use hyper::header::{Headers, ContentType}; use hyper::header::{Headers, ContentType};
use hyper::Uri; use hyper::Uri;
@ -239,7 +237,7 @@ impl<F, C> Api<C> for Client<F> where
F: Future<Item=hyper::Response, Error=hyper::Error> + 'static, F: Future<Item=hyper::Response, Error=hyper::Error> + 'static,
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}}{ C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}}{
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{paramName}}: {{^required}}{{#isFile}}Box<Future<Item={{/isFile}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> { fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{paramName}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> {
{{#queryParams}}{{#-first}} {{#queryParams}}{{#-first}}
// Query parameters // Query parameters
{{/-first}}{{#required}} let query_{{paramName}} = format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=param_{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}); {{/-first}}{{#required}} let query_{{paramName}} = format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=param_{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
@ -259,47 +257,13 @@ impl<F, C> Api<C> for Client<F> where
let mut request = hyper::Request::new(hyper::Method::{{#vendorExtensions}}{{HttpMethod}}{{/vendorExtensions}}, uri); let mut request = hyper::Request::new(hyper::Method::{{#vendorExtensions}}{{HttpMethod}}{{/vendorExtensions}}, uri);
{{#vendorExtensions}}{{#hasFile}} // Form data body {{#vendorExtensions}}{{#formParams}}{{#-first}} let params = &[{{/-first}}
let mut multipart = Multipart::new();
// Helper function to convert a Stream into a String. The String can then be used to build the HTTP body.
fn convert_stream_to_string(stream: Box<Stream<Item=Vec<u8>, Error=Error> + Send>) -> Result<String, ApiError> {
stream.concat2()
.wait()
.map_err(|e| ApiError(format!("Unable to collect stream: {}", e)))
.and_then(|body| String::from_utf8(body)
.map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e))))
}{{/hasFile}}{{/vendorExtensions}}{{#formParams}}{{#isFile}}
{{^required}} if let Ok(Some(param_{{paramName}})) = param_{{paramName}}.wait() { {{/required}}
{{^required}} {{/required}} match convert_stream_to_string(param_{{paramName}}) {
{{^required}} {{/required}} Ok(param_{{paramName}}) => {
// Add file to multipart form.
multipart.add_text("{{paramName}}", param_{{paramName}});
},
{{^required}} {{/required}} Err(err) => return Box::new(futures::done(Err(err))),
{{^required}} {{/required}} }
{{^required}}}{{/required}}{{/isFile}}{{/formParams}}{{#vendorExtensions}}{{#hasFile}}
let mut fields = match multipart.prepare() {
Ok(fields) => fields,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))),
};
let mut body_string = String::new();
let body = fields.to_body().read_to_string(&mut body_string);
let boundary = fields.boundary();
let multipart_header = match mime::Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) {
Ok(multipart_header) => multipart_header,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))),
};{{/hasFile}}{{^hasFile}}{{#formParams}}{{#-first}} let params = &[{{/-first}}
("{{baseName}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{paramName}}{{/isString}}{{^isString}}format!("{:?}", param_{{paramName}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{paramName}}{{/isString}}{{^isString}}param_{{paramName}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}{{#-last}} ("{{baseName}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{paramName}}{{/isString}}{{^isString}}format!("{:?}", param_{{paramName}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{paramName}}{{/isString}}{{^isString}}param_{{paramName}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}{{#-last}}
]; ];
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone())); request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone()));
request.set_body(body.into_bytes());{{/-last}}{{/formParams}}{{/hasFile}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}} request.set_body(body.into_bytes());{{/-last}}{{/formParams}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}}
// Body parameter // Body parameter
{{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{paramName}};{{/consumesPlainText}}{{#consumesXml}} {{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{paramName}};{{/consumesPlainText}}{{#consumesXml}}
{{^has_namespace}} let body = serde_xml_rs::to_string(&param_{{paramName}}).expect("impossible to fail to serialize");{{/has_namespace}}{{#has_namespace}} {{^has_namespace}} let body = serde_xml_rs::to_string(&param_{{paramName}}).expect("impossible to fail to serialize");{{/has_namespace}}{{#has_namespace}}
@ -340,11 +304,6 @@ impl<F, C> Api<C> for Client<F> where
{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{paramName}}: Option<{{{dataType}}}> = None; {{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{paramName}}: Option<{{{dataType}}}> = None;
{{/isMapContainer}}{{/headerParams}} {{/isMapContainer}}{{/headerParams}}
{{#vendorExtensions}}{{#hasFile}}
request.headers_mut().set(ContentType(multipart_header));
request.set_body(body_string.into_bytes());
{{/hasFile}}{{/vendorExtensions}}
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -357,13 +316,9 @@ impl<F, C> Api<C> for Client<F> where
None => return Box::new(future::err(ApiError(String::from("Required response header {{baseName}} for response {{code}} was not found.")))) as Box<Future<Item=_, Error=_>>, None => return Box::new(future::err(ApiError(String::from("Required response header {{baseName}} for response {{code}} was not found.")))) as Box<Future<Item=_, Error=_>>,
}; };
{{/headers}} {{/headers}}
{{^isFile}}let body = response.body();{{/isFile}}{{#isFile}}let body = Box::new(response.body() let body = response.body();
.map(|chunk| chunk.to_vec())
.map_err(|_|
Error::new(ErrorKind::Other, "Received error reading response.")
));{{/isFile}}
Box::new( Box::new(
{{#dataType}}{{^isFile}} {{#dataType}}
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -383,9 +338,6 @@ impl<F, C> Api<C> for Client<F> where
{{/producesPlainText}}{{/vendorExtensions}} {{/producesPlainText}}{{/vendorExtensions}}
)) ))
.map(move |body| .map(move |body|
{{/isFile}}{{#isFile}}
future::ok(
{{/isFile}}
{{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{name}}: response_{{name}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}} {{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{name}}: response_{{name}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}}
) )
{{/dataType}}{{^dataType}} {{/dataType}}{{^dataType}}

View File

@ -4,9 +4,7 @@
use futures::{self, Future}; use futures::{self, Future};
use chrono; use chrono;
{{#apiHasFile}}use futures::Stream;{{/apiHasFile}}
use std::collections::HashMap; use std::collections::HashMap;
{{#apiHasFile}}use std::io::Error;{{/apiHasFile}}
use std::marker::PhantomData; use std::marker::PhantomData;
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}} {{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
use swagger; use swagger;
@ -31,10 +29,9 @@ impl<C> Server<C> {
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
{{#summary}} /// {{{summary}}}{{/summary}} {{#summary}} /// {{{summary}}}{{/summary}}
fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box<Future<Item={{/isFile}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> { fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> {
let context = context.clone(); let context = context.clone();
println!("{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{^isFile}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/isFile}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}{{^isFile}}, {{paramName}}{{/isFile}}{{/allParams}}, context.get().0.clone());{{#allParams}}{{#isFile}} println!("{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{paramName}}{{/allParams}}, context.get().0.clone());{{#allParams}}{{/allParams}}
let _ = {{paramName}}; //Suppresses unused param warning{{/isFile}}{{/allParams}}
Box::new(futures::failed("Generic failure".into())) Box::new(futures::failed("Generic failure".into()))
} }
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

View File

@ -51,7 +51,7 @@ pub enum {{operationId}}Response {
pub trait Api<C> { pub trait Api<C> {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
{{#summary}} /// {{{summary}}}{{/summary}} {{#summary}} /// {{{summary}}}{{/summary}}
fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box<Future<Item={{/isFile}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>>; fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{operationId}}Response, Error=ApiError>>;
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
} }
@ -59,7 +59,7 @@ pub trait Api<C> {
pub trait ApiNoContext { pub trait ApiNoContext {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
{{#summary}} /// {{{summary}}}{{/summary}} {{#summary}} /// {{{summary}}}{{/summary}}
fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box<Future<Item={{/isFile}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box<Future<Item={{operationId}}Response, Error=ApiError>>; fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<Future<Item={{operationId}}Response, Error=ApiError>>;
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
} }
@ -78,7 +78,7 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> { impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
{{#summary}} /// {{{summary}}}{{/summary}} {{#summary}} /// {{{summary}}}{{/summary}}
fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}{{#isFile}}Box<Future<Item={{/isFile}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{#isFile}}, Error=Error> + Send>{{/isFile}}{{/required}}{{/allParams}}) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> { fn {{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}(&self{{#allParams}}, {{paramName}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<Future<Item={{operationId}}Response, Error=ApiError>> {
self.api().{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{paramName}}, {{/allParams}}&self.context()) self.api().{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{paramName}}, {{/allParams}}&self.context())
} }
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}

View File

@ -17,9 +17,9 @@ pub mod requests {
lazy_static! { lazy_static! {
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap(); pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap();
} }
{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}}{{^hasFile}} /// Create Mime objects for the request content types for {{operationId}} {{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}} /// Create Mime objects for the request content types for {{operationId}}
lazy_static! { lazy_static! {
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap(); pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap();
} }
{{/hasFile}}{{/-first}}{{/formParams}}{{/vendorExtensions}}{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} {{/-first}}{{/formParams}}{{/vendorExtensions}}{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
} }

View File

@ -7,7 +7,6 @@ extern crate openssl;
extern crate mime; extern crate mime;
{{^apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}} {{^apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}}
extern crate chrono; extern crate chrono;
{{#apiHasFile}}extern crate multipart;{{/apiHasFile}}
extern crate percent_encoding; extern crate percent_encoding;
extern crate url; extern crate url;
@ -20,8 +19,6 @@ use hyper::{Request, Response, Error, StatusCode};
use hyper::header::{Headers, ContentType}; use hyper::header::{Headers, ContentType};
use self::url::form_urlencoded; use self::url::form_urlencoded;
use mimetypes; use mimetypes;
{{#apiHasFile}}use self::multipart::server::Multipart;
use self::multipart::server::save::SaveResult;{{/apiHasFile}}
use serde_json; use serde_json;
{{#usesXml}}use serde_xml_rs;{{/usesXml}} {{#usesXml}}use serde_xml_rs;{{/usesXml}}
@ -277,51 +274,7 @@ where
}; };
{{/required}} {{/required}}
{{/-first}}{{/bodyParams}} {{/-first}}{{/bodyParams}}
{{^bodyParams}}{{#vendorExtensions}}{{#hasFile}} {{^bodyParams}}{{#vendorExtensions}}
let boundary = match multipart_boundary(&headers) {
Some(boundary) => boundary.to_string(),
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))),
};
Box::new(body.concat2()
.then(move |result| -> Box<Future<Item=Response, Error=Error>> {
match result {
Ok(body) => {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
SaveResult::Full(entries) => {
entries
},
_ => {
return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts"))))
},
};
{{#formParams}}{{#-first}}
// Form parameters
{{/-first}}
let param_{{paramName}} = entries.fields.remove("{{paramName}}");
let param_{{paramName}} = match param_{{paramName}} {
Some(entry) =>
{{#isFile}}
{{^required}}Some({{/required}}Box::new(stream::once(Ok(entry.as_bytes().to_vec()))) as Box<Stream<Item=Vec<u8>, Error=io::Error> + Send>{{^required}}){{/required}},
{{/isFile}}{{^isFile}}
match entry.parse::<{{{dataType}}}>() {
Ok(entry) => {{^required}}Some({{/required}}entry{{^required}}){{/required}},
{{#required}}
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse form parameter {{baseName}} - doesn't match schema: {}", e)))),
{{/required}}{{^required}}
Err(_) => None,
{{/required}}
},
{{/isFile}}
{{#required}}
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter {{paramName}}")))),
{{/required}}{{^required}}
None => None,
{{/required}}
};
{{^required}}{{#isFile}} let param_{{paramName}} = Box::new(future::ok(param_{{paramName}}));{{/isFile}}{{/required}}
{{/formParams}}
{{/hasFile}}{{^hasFile}}
Box::new({ Box::new({
{{ {{
{{#formParams}}{{#-first}} {{#formParams}}{{#-first}}
@ -329,7 +282,7 @@ where
{{/-first}} {{/-first}}
let param_{{paramName}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}} let param_{{paramName}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}
{{/formParams}} {{/formParams}}
{{/hasFile}}{{/vendorExtensions}}{{/bodyParams}} {{/vendorExtensions}}{{/bodyParams}}
Box::new(api_impl.{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}param_{{paramName}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context) Box::new(api_impl.{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}param_{{paramName}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context)
.then(move |result| { .then(move |result| {
let mut response = Response::new(); let mut response = Response::new();
@ -364,7 +317,7 @@ where
{{/-last}} {{/-last}}
{{/headers}}{{/dataType}} {{/headers}}{{/dataType}}
=> { => {
{{^isFile}} response.set_status(StatusCode::try_from({{code}}).unwrap()); response.set_status(StatusCode::try_from({{code}}).unwrap());
{{#headers}} {{#headers}}
header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{dataType}}}] } header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{dataType}}}] }
response.headers_mut().set(Response{{nameInCamelCase}}({{name}})); response.headers_mut().set(Response{{nameInCamelCase}}({{name}}));
@ -384,34 +337,7 @@ where
let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
{{/producesJson}}{{/vendorExtensions}} {{/producesJson}}{{/vendorExtensions}}
response.set_body(body); response.set_body(body);
{{/dataType}}{{/isFile}}{{#isFile}} {{/dataType}}
let body = body.fold(Vec::new(), | mut body, chunk| {
body.extend(chunk.iter());
future::ok::<Vec<u8>, io::Error>(body)
})
// Block whilst waiting for the stream to complete
.wait();
match body {
// If no error occurred then create successful hyper response
Ok(vec) => {
response.set_status(StatusCode::try_from({{code}}).unwrap());
{{#headers}}
header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{dataType}}}] }
response.headers_mut().set(Response{{nameInCamelCase}}({{name}}));
{{/headers}}{{#produces}}{{#-first}}{{#dataType}}
response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone()));
{{/dataType}}{{/-first}}{{/produces}}
response.set_body(vec);
},
// It's possible that errors were received in the stream, if this is the case then we can't return a success response to the client and instead must return an internal error.
Err(e) => {
response.set_status(StatusCode::InternalServerError);
response.set_body("An internal error occurred");
}
}
{{/isFile}}
}, },
{{/responses}} {{/responses}}
}, },
@ -426,17 +352,10 @@ where
future::ok(response) future::ok(response)
} }
)) ))
{{^bodyParams}}{{#vendorExtensions}}{{^hasFile}} {{^bodyParams}}{{#vendorExtensions}}
}} }}
}) as Box<Future<Item=Response, Error=Error>> }) as Box<Future<Item=Response, Error=Error>>
{{/hasFile}}{{#hasFile}} {{/vendorExtensions}}{{/bodyParams}}
as Box<Future<Item=Response, Error=Error>>
},
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))),
}
})
)
{{/hasFile}}{{/vendorExtensions}}{{/bodyParams}}
{{#bodyParams}}{{#-first}} {{#bodyParams}}{{#-first}}
}, },
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{baseName}}: {}", e)))), Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{baseName}}: {}", e)))),
@ -451,32 +370,3 @@ where
} }
} }
} }
{{#apiHasFile}}
/// Utility function to get the multipart boundary marker (if any) from the Headers.
fn multipart_boundary<'a>(headers: &'a Headers) -> Option<&'a str> {
headers.get::<ContentType>().and_then(|content_type| {
let ContentType(ref mime) = *content_type;
if mime.type_() == mime::MULTIPART && mime.subtype() == mime::FORM_DATA {
mime.get_param(mime::BOUNDARY).map(|x| x.as_str())
} else {
None
}
})
}
{{/apiHasFile}}
/// Request parser for `Api`.
pub struct ApiRequestParser;
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() {
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
// {{operationId}} - {{httpMethod}} {{path}}
&hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => Ok("{{operationId}}"),
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} _ => Err(()),
}
}
}

View File

@ -608,6 +608,7 @@ paths:
consumes: consumes:
- "application/x-www-form-urlencoded" - "application/x-www-form-urlencoded"
parameters: parameters:
# See https://github.com/OpenAPITools/openapi-generator/issues/545
# - name: enum_form_string_array # - name: enum_form_string_array
# type: array # type: array
# items: # items:
@ -618,15 +619,15 @@ paths:
# - '$' # - '$'
# in: formData # in: formData
# description: Form parameter enum test (string array) # description: Form parameter enum test (string array)
# - name: enum_form_string - name: enum_form_string
# type: string type: string
# default: '-efg' default: '-efg'
# enum: enum:
# - _abc - _abc
# - '-efg' - '-efg'
# - (xyz) - (xyz)
# in: formData in: formData
# description: Form parameter enum test (string) description: Form parameter enum test (string)
- name: enum_header_string_array - name: enum_header_string_array
type: array type: array
items: items:
@ -753,12 +754,12 @@ paths:
in: formData in: formData
description: None description: None
required: true required: true
# - name: byte - name: byte
# type: string type: string
# format: byte format: byte
# in: formData in: formData
# description: None description: None
# required: true required: true
- name: binary - name: binary
type: string type: string
format: binary format: binary
@ -1204,9 +1205,9 @@ definitions:
byte: byte:
type: string type: string
format: byte format: byte
# binary: binary:
# type: string type: string
# format: binary format: binary
date: date:
type: string type: string
format: date format: date
@ -1338,16 +1339,15 @@ definitions:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
# comment out the following (map of map of enum) as many language not yet support this map_map_of_enum:
#map_map_of_enum: type: object
# type: object additionalProperties:
# additionalProperties: type: object
# type: object additionalProperties:
# additionalProperties: type: string
# type: string enum:
# enum: - UPPER
# - UPPER - lower
# - lower
map_of_enum_string: map_of_enum_string:
type: object type: object
additionalProperties: additionalProperties:
@ -1375,15 +1375,13 @@ definitions:
type: array type: array
items: items:
$ref: '#/definitions/ReadOnlyFirst' $ref: '#/definitions/ReadOnlyFirst'
# commented out the below test case for array of enum for the time being array_of_enum:
# as not all language can handle it type: array
#array_of_enum: items:
# type: array type: string
# items: enum:
# type: string - UPPER
# enum: - lower
# - UPPER
# - lower
NumberOnly: NumberOnly:
type: object type: object
properties: properties:
@ -1420,16 +1418,15 @@ definitions:
enum: enum:
- fish - fish
- crab - crab
# comment out the following as 2d array of enum is not supported at the moment array_array_enum:
#array_array_enum: type: array
# type: array items:
# items: type: array
# type: array items:
# items: type: string
# type: string enum:
# enum: - Cat
# - Cat - Dog
# - Dog
OuterEnum: OuterEnum:
type: "string" type: "string"
enum: enum:

View File

@ -7,8 +7,8 @@ license = "Unlicense"
[features] [features]
default = ["client", "server"] default = ["client", "server"]
client = ["serde_json", "serde_urlencoded", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid", "multipart"] client = ["serde_json", "serde_urlencoded", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
server = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid", "multipart"] server = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"]
[dependencies] [dependencies]
# Required by example server. # Required by example server.

View File

@ -657,6 +657,19 @@ paths:
- -1.2 - -1.2
format: double format: double
type: number type: number
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
enum_form_string:
default: -efg
description: Form parameter enum test (string)
enum:
- _abc
- -efg
- (xyz)
type: string
responses: responses:
400: 400:
content: {} content: {}
@ -738,6 +751,10 @@ paths:
description: None description: None
pattern: ^[A-Z].* pattern: ^[A-Z].*
type: string type: string
byte:
description: None
format: byte
type: string
binary: binary:
description: None description: None
format: binary format: binary
@ -760,6 +777,7 @@ paths:
description: None description: None
type: string type: string
required: required:
- byte
- double - double
- number - number
- pattern_without_delimiter - pattern_without_delimiter
@ -1247,6 +1265,13 @@ components:
$ref: '#/components/schemas/ReadOnlyFirst' $ref: '#/components/schemas/ReadOnlyFirst'
type: array type: array
type: array type: array
array_of_enum:
items:
enum:
- UPPER
- lower
type: string
type: array
type: object type: object
OuterComposite: OuterComposite:
example: example:
@ -1297,6 +1322,9 @@ components:
format: byte format: byte
pattern: ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$ pattern: ^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$
type: string type: string
binary:
format: binary
type: string
date: date:
format: date format: date
type: string type: string
@ -1331,6 +1359,15 @@ components:
- crab - crab
type: string type: string
type: array type: array
array_array_enum:
items:
items:
enum:
- Cat
- Dog
type: string
type: array
type: array
type: object type: object
OuterString: OuterString:
type: string type: string
@ -1370,6 +1407,15 @@ components:
type: string type: string
type: object type: object
type: object type: object
map_map_of_enum:
additionalProperties:
additionalProperties:
enum:
- UPPER
- lower
type: string
type: object
type: object
map_of_enum_string: map_of_enum_string:
additionalProperties: additionalProperties:
enum: enum:

View File

@ -160,12 +160,12 @@ fn main() {
// }, // },
Some("TestEndpointParameters") => { Some("TestEndpointParameters") => {
let result = core.run(client.test_endpoint_parameters(8.14, 1.2, "pattern_without_delimiter_example".to_string(), Some(56), Some(56), Some(789), Some(3.4), Some("string_example".to_string()), Box::new(future::ok(Some(Box::new(stream::once(Ok(b"hello".to_vec()))) as Box<Stream<Item=_, Error=_> + Send>))) as Box<Future<Item=_, Error=_> + Send>, None, None, Some("password_example".to_string()), Some("callback_example".to_string()))); let result = core.run(client.test_endpoint_parameters(8.14, 1.2, "pattern_without_delimiter_example".to_string(), swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")), Some(56), Some(56), Some(789), Some(3.4), Some("string_example".to_string()), Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))), None, None, Some("password_example".to_string()), Some("callback_example".to_string())));
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone()); println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
}, },
Some("TestEnumParameters") => { Some("TestEnumParameters") => {
let result = core.run(client.test_enum_parameters(Some(&Vec::new()), Some("enum_header_string_example".to_string()), Some(&Vec::new()), Some("enum_query_string_example".to_string()), Some(56), Some(1.2))); let result = core.run(client.test_enum_parameters(Some(&Vec::new()), Some("enum_header_string_example".to_string()), Some(&Vec::new()), Some("enum_query_string_example".to_string()), Some(56), Some(1.2), Some("enum_form_string_example".to_string())));
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone()); println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
}, },
@ -224,7 +224,7 @@ fn main() {
}, },
Some("UploadFile") => { Some("UploadFile") => {
let result = core.run(client.upload_file(789, Some("additional_metadata_example".to_string()), Box::new(future::ok(Some(Box::new(stream::once(Ok(b"hello".to_vec()))) as Box<Stream<Item=_, Error=_> + Send>))) as Box<Future<Item=_, Error=_> + Send>)); let result = core.run(client.upload_file(789, Some("additional_metadata_example".to_string()), Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE")))));
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone()); println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
}, },

View File

@ -4,9 +4,7 @@
use futures::{self, Future}; use futures::{self, Future};
use chrono; use chrono;
use futures::Stream;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::Error;
use std::marker::PhantomData; use std::marker::PhantomData;
use swagger; use swagger;
@ -111,17 +109,16 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
} }
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> { fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Option<swagger::ByteArray>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> {
let context = context.clone(); let context = context.clone();
println!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, integer, int32, int64, float, string, date, date_time, password, callback, context.get().0.clone()); println!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.get().0.clone());
let _ = binary; //Suppresses unused param warning
Box::new(futures::failed("Generic failure".into())) Box::new(futures::failed("Generic failure".into()))
} }
/// To test enum parameters /// To test enum parameters
fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> { fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, enum_form_string: Option<String>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> {
let context = context.clone(); let context = context.clone();
println!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, context.get().0.clone()); println!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, context.get().0.clone());
Box::new(futures::failed("Generic failure".into())) Box::new(futures::failed("Generic failure".into()))
} }
@ -196,10 +193,9 @@ impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
} }
/// uploads an image /// uploads an image
fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> { fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Option<swagger::ByteArray>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> {
let context = context.clone(); let context = context.clone();
println!("upload_file({}, {:?}, ) - X-Span-ID: {:?}", pet_id, additional_metadata, context.get().0.clone()); println!("upload_file({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, additional_metadata, file, context.get().0.clone());
let _ = file; //Suppresses unused param warning
Box::new(futures::failed("Generic failure".into())) Box::new(futures::failed("Generic failure".into()))
} }

View File

@ -6,11 +6,9 @@ extern crate openssl;
extern crate mime; extern crate mime;
extern crate chrono; extern crate chrono;
extern crate url; extern crate url;
extern crate multipart;
extern crate serde_urlencoded; extern crate serde_urlencoded;
use self::multipart::client::lazy::Multipart;
use hyper; use hyper;
use hyper::header::{Headers, ContentType}; use hyper::header::{Headers, ContentType};
use hyper::Uri; use hyper::Uri;
@ -298,8 +296,6 @@ impl<F, C> Api<C> for Client<F> where
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -307,7 +303,6 @@ impl<F, C> Api<C> for Client<F> where
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -378,8 +373,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -387,7 +380,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -456,8 +448,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -465,7 +455,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -534,8 +523,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -543,7 +530,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -612,8 +598,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -621,7 +605,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -692,8 +675,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -757,8 +738,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -766,7 +745,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -807,7 +785,7 @@ if let Some(body) = body {
} }
fn test_endpoint_parameters(&self, param_number: f64, param_double: f64, param_pattern_without_delimiter: String, param_integer: Option<i32>, param_int32: Option<i32>, param_int64: Option<i64>, param_float: Option<f32>, param_string: Option<String>, param_binary: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, param_date: Option<chrono::DateTime<chrono::Utc>>, param_date_time: Option<chrono::DateTime<chrono::Utc>>, param_password: Option<String>, param_callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> { fn test_endpoint_parameters(&self, param_number: f64, param_double: f64, param_pattern_without_delimiter: String, param_byte: swagger::ByteArray, param_integer: Option<i32>, param_int32: Option<i32>, param_int64: Option<i64>, param_float: Option<f32>, param_string: Option<String>, param_binary: Option<swagger::ByteArray>, param_date: Option<chrono::DateTime<chrono::Utc>>, param_date_time: Option<chrono::DateTime<chrono::Utc>>, param_password: Option<String>, param_callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> {
let uri = format!( let uri = format!(
@ -822,41 +800,26 @@ if let Some(body) = body {
let mut request = hyper::Request::new(hyper::Method::Post, uri); let mut request = hyper::Request::new(hyper::Method::Post, uri);
// Form data body let params = &[
let mut multipart = Multipart::new(); ("integer", param_integer.map(|param| format!("{:?}", param))),
("int32", param_int32.map(|param| format!("{:?}", param))),
("int64", param_int64.map(|param| format!("{:?}", param))),
("number", Some(format!("{:?}", param_number))),
("float", param_float.map(|param| format!("{:?}", param))),
("double", Some(format!("{:?}", param_double))),
("string", param_string),
("pattern_without_delimiter", Some(param_pattern_without_delimiter)),
("byte", Some(format!("{:?}", param_byte))),
("binary", param_binary.map(|param| format!("{:?}", param))),
("date", param_date.map(|param| format!("{:?}", param))),
("dateTime", param_date_time.map(|param| format!("{:?}", param))),
("password", param_password),
("callback", param_callback),
];
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
// Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. request.headers_mut().set(ContentType(mimetypes::requests::TEST_ENDPOINT_PARAMETERS.clone()));
fn convert_stream_to_string(stream: Box<Stream<Item=Vec<u8>, Error=Error> + Send>) -> Result<String, ApiError> { request.set_body(body.into_bytes());
stream.concat2()
.wait()
.map_err(|e| ApiError(format!("Unable to collect stream: {}", e)))
.and_then(|body| String::from_utf8(body)
.map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e))))
}
if let Ok(Some(param_binary)) = param_binary.wait() {
match convert_stream_to_string(param_binary) {
Ok(param_binary) => {
// Add file to multipart form.
multipart.add_text("binary", param_binary);
},
Err(err) => return Box::new(futures::done(Err(err))),
}
}
let mut fields = match multipart.prepare() {
Ok(fields) => fields,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))),
};
let mut body_string = String::new();
let body = fields.to_body().read_to_string(&mut body_string);
let boundary = fields.boundary();
let multipart_header = match mime::Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) {
Ok(multipart_header) => multipart_header,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))),
};
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
(context as &Has<Option<AuthData>>).get().as_ref().map(|auth_data| { (context as &Has<Option<AuthData>>).get().as_ref().map(|auth_data| {
@ -867,11 +830,6 @@ if let Some(body) = body {
} }
}); });
request.headers_mut().set(ContentType(multipart_header));
request.set_body(body_string.into_bytes());
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -918,7 +876,7 @@ if let Some(body) = body {
} }
fn test_enum_parameters(&self, param_enum_header_string_array: Option<&Vec<String>>, param_enum_header_string: Option<String>, param_enum_query_string_array: Option<&Vec<String>>, param_enum_query_string: Option<String>, param_enum_query_integer: Option<i32>, param_enum_query_double: Option<f64>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> { fn test_enum_parameters(&self, param_enum_header_string_array: Option<&Vec<String>>, param_enum_header_string: Option<String>, param_enum_query_string_array: Option<&Vec<String>>, param_enum_query_string: Option<String>, param_enum_query_integer: Option<i32>, param_enum_query_double: Option<f64>, param_enum_form_string: Option<String>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> {
// Query parameters // Query parameters
let query_enum_query_string_array = param_enum_query_string_array.map_or_else(String::new, |query| format!("enum_query_string_array={enum_query_string_array}&", enum_query_string_array=query.join(","))); let query_enum_query_string_array = param_enum_query_string_array.map_or_else(String::new, |query| format!("enum_query_string_array={enum_query_string_array}&", enum_query_string_array=query.join(",")));
@ -943,7 +901,13 @@ if let Some(body) = body {
let mut request = hyper::Request::new(hyper::Method::Get, uri); let mut request = hyper::Request::new(hyper::Method::Get, uri);
let params = &[
("enum_form_string", param_enum_form_string),
];
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
request.headers_mut().set(ContentType(mimetypes::requests::TEST_ENUM_PARAMETERS.clone()));
request.set_body(body.into_bytes());
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
@ -954,8 +918,6 @@ if let Some(body) = body {
param_enum_header_string.map(|header| request.headers_mut().set(RequestEnumHeaderString(header))); param_enum_header_string.map(|header| request.headers_mut().set(RequestEnumHeaderString(header)));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1028,8 +990,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1094,8 +1054,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1161,8 +1119,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1170,7 +1126,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -1239,8 +1194,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1302,8 +1255,6 @@ if let Some(body) = body {
param_api_key.map(|header| request.headers_mut().set(RequestApiKey(header))); param_api_key.map(|header| request.headers_mut().set(RequestApiKey(header)));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1365,8 +1316,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1374,7 +1323,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -1450,8 +1398,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1459,7 +1405,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -1531,8 +1476,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1540,7 +1483,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -1627,8 +1569,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1711,8 +1651,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1750,7 +1688,7 @@ if let Some(body) = body {
} }
fn upload_file(&self, param_pet_id: i64, param_additional_metadata: Option<String>, param_file: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> { fn upload_file(&self, param_pet_id: i64, param_additional_metadata: Option<String>, param_file: Option<swagger::ByteArray>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> {
let uri = format!( let uri = format!(
@ -1765,50 +1703,18 @@ if let Some(body) = body {
let mut request = hyper::Request::new(hyper::Method::Post, uri); let mut request = hyper::Request::new(hyper::Method::Post, uri);
// Form data body let params = &[
let mut multipart = Multipart::new(); ("additionalMetadata", param_additional_metadata),
("file", param_file.map(|param| format!("{:?}", param))),
];
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
// Helper function to convert a Stream into a String. The String can then be used to build the HTTP body. request.headers_mut().set(ContentType(mimetypes::requests::UPLOAD_FILE.clone()));
fn convert_stream_to_string(stream: Box<Stream<Item=Vec<u8>, Error=Error> + Send>) -> Result<String, ApiError> { request.set_body(body.into_bytes());
stream.concat2()
.wait()
.map_err(|e| ApiError(format!("Unable to collect stream: {}", e)))
.and_then(|body| String::from_utf8(body)
.map_err(|e| ApiError(format!("Failed to convert utf8 stream to String: {}", e))))
}
if let Ok(Some(param_file)) = param_file.wait() {
match convert_stream_to_string(param_file) {
Ok(param_file) => {
// Add file to multipart form.
multipart.add_text("file", param_file);
},
Err(err) => return Box::new(futures::done(Err(err))),
}
}
let mut fields = match multipart.prepare() {
Ok(fields) => fields,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build request: {}", err))))),
};
let mut body_string = String::new();
let body = fields.to_body().read_to_string(&mut body_string);
let boundary = fields.boundary();
let multipart_header = match mime::Mime::from_str(&format!("multipart/form-data;boundary={}", boundary)) {
Ok(multipart_header) => multipart_header,
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build multipart header: {:?}", err))))),
};
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
request.headers_mut().set(ContentType(multipart_header));
request.set_body(body_string.into_bytes());
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1816,7 +1722,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -1877,8 +1782,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1945,8 +1848,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -1954,7 +1855,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -2015,8 +1915,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2024,7 +1922,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -2111,8 +2008,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2120,7 +2015,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -2200,8 +2094,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2265,8 +2157,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2330,8 +2220,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2389,8 +2277,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2457,8 +2343,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2466,7 +2350,6 @@ if let Some(body) = body {
200 => { 200 => {
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -2553,8 +2436,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2572,7 +2453,6 @@ if let Some(body) = body {
}; };
let body = response.body(); let body = response.body();
Box::new( Box::new(
body body
.concat2() .concat2()
.map_err(|e| ApiError(format!("Failed to read response: {}", e))) .map_err(|e| ApiError(format!("Failed to read response: {}", e)))
@ -2644,8 +2524,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {
@ -2709,8 +2587,6 @@ if let Some(body) = body {
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone())); request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
Box::new(self.client_service.call(request) Box::new(self.client_service.call(request)
.map_err(|e| ApiError(format!("No response received: {}", e))) .map_err(|e| ApiError(format!("No response received: {}", e)))
.and_then(|mut response| { .and_then(|mut response| {

View File

@ -288,10 +288,10 @@ pub trait Api<C> {
fn test_client_model(&self, client: models::Client, context: &C) -> Box<Future<Item=TestClientModelResponse, Error=ApiError>>; fn test_client_model(&self, client: models::Client, context: &C) -> Box<Future<Item=TestClientModelResponse, Error=ApiError>>;
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>>; fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Option<swagger::ByteArray>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>>;
/// To test enum parameters /// To test enum parameters
fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>>; fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, enum_form_string: Option<String>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>>;
/// test inline additionalProperties /// test inline additionalProperties
fn test_inline_additional_properties(&self, request_body: HashMap<String, String>, context: &C) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError>>; fn test_inline_additional_properties(&self, request_body: HashMap<String, String>, context: &C) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError>>;
@ -324,7 +324,7 @@ pub trait Api<C> {
fn update_pet_with_form(&self, pet_id: i64, name: Option<String>, status: Option<String>, context: &C) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError>>; fn update_pet_with_form(&self, pet_id: i64, name: Option<String>, status: Option<String>, context: &C) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError>>;
/// uploads an image /// uploads an image
fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>>; fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Option<swagger::ByteArray>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError>>;
/// Delete purchase order by ID /// Delete purchase order by ID
fn delete_order(&self, order_id: String, context: &C) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError>>; fn delete_order(&self, order_id: String, context: &C) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError>>;
@ -389,10 +389,10 @@ pub trait ApiNoContext {
fn test_client_model(&self, client: models::Client) -> Box<Future<Item=TestClientModelResponse, Error=ApiError>>; fn test_client_model(&self, client: models::Client) -> Box<Future<Item=TestClientModelResponse, Error=ApiError>>;
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>>; fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Option<swagger::ByteArray>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>>;
/// To test enum parameters /// To test enum parameters
fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>>; fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, enum_form_string: Option<String>) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>>;
/// test inline additionalProperties /// test inline additionalProperties
fn test_inline_additional_properties(&self, request_body: HashMap<String, String>) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError>>; fn test_inline_additional_properties(&self, request_body: HashMap<String, String>) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError>>;
@ -425,7 +425,7 @@ pub trait ApiNoContext {
fn update_pet_with_form(&self, pet_id: i64, name: Option<String>, status: Option<String>) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError>>; fn update_pet_with_form(&self, pet_id: i64, name: Option<String>, status: Option<String>) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError>>;
/// uploads an image /// uploads an image
fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>) -> Box<Future<Item=UploadFileResponse, Error=ApiError>>; fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Option<swagger::ByteArray>) -> Box<Future<Item=UploadFileResponse, Error=ApiError>>;
/// Delete purchase order by ID /// Delete purchase order by ID
fn delete_order(&self, order_id: String) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError>>; fn delete_order(&self, order_id: String) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError>>;
@ -515,13 +515,13 @@ impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
} }
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> { fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Option<swagger::ByteArray>, date: Option<chrono::DateTime<chrono::Utc>>, date_time: Option<chrono::DateTime<chrono::Utc>>, password: Option<String>, callback: Option<String>) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError>> {
self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, integer, int32, int64, float, string, binary, date, date_time, password, callback, &self.context()) self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, &self.context())
} }
/// To test enum parameters /// To test enum parameters
fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> { fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, enum_form_string: Option<String>) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError>> {
self.api().test_enum_parameters(enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, &self.context()) self.api().test_enum_parameters(enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, &self.context())
} }
/// test inline additionalProperties /// test inline additionalProperties
@ -575,7 +575,7 @@ impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
} }
/// uploads an image /// uploads an image
fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Box<Future<Item=Option<Box<Stream<Item=Vec<u8>, Error=Error> + Send>>, Error=Error> + Send>) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> { fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Option<swagger::ByteArray>) -> Box<Future<Item=UploadFileResponse, Error=ApiError>> {
self.api().upload_file(pet_id, additional_metadata, file, &self.context()) self.api().upload_file(pet_id, additional_metadata, file, &self.context())
} }

View File

@ -101,6 +101,14 @@ pub mod requests {
lazy_static! { lazy_static! {
pub static ref TEST_CLIENT_MODEL: Mime = "application/json".parse().unwrap(); pub static ref TEST_CLIENT_MODEL: Mime = "application/json".parse().unwrap();
} }
/// Create Mime objects for the request content types for TestEndpointParameters
lazy_static! {
pub static ref TEST_ENDPOINT_PARAMETERS: Mime = "application/x-www-form-urlencoded".parse().unwrap();
}
/// Create Mime objects for the request content types for TestEnumParameters
lazy_static! {
pub static ref TEST_ENUM_PARAMETERS: Mime = "application/x-www-form-urlencoded".parse().unwrap();
}
/// Create Mime objects for the request content types for TestInlineAdditionalProperties /// Create Mime objects for the request content types for TestInlineAdditionalProperties
lazy_static! { lazy_static! {
pub static ref TEST_INLINE_ADDITIONAL_PROPERTIES: Mime = "application/json".parse().unwrap(); pub static ref TEST_INLINE_ADDITIONAL_PROPERTIES: Mime = "application/json".parse().unwrap();
@ -125,6 +133,10 @@ pub mod requests {
lazy_static! { lazy_static! {
pub static ref UPDATE_PET_WITH_FORM: Mime = "application/x-www-form-urlencoded".parse().unwrap(); pub static ref UPDATE_PET_WITH_FORM: Mime = "application/x-www-form-urlencoded".parse().unwrap();
} }
/// Create Mime objects for the request content types for UploadFile
lazy_static! {
pub static ref UPLOAD_FILE: Mime = "multipart/form-data".parse().unwrap();
}
/// Create Mime objects for the request content types for PlaceOrder /// Create Mime objects for the request content types for PlaceOrder
lazy_static! { lazy_static! {
pub static ref PLACE_ORDER: Mime = "application/json".parse().unwrap(); pub static ref PLACE_ORDER: Mime = "application/json".parse().unwrap();

View File

@ -185,6 +185,11 @@ pub struct ArrayTest {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
pub array_array_of_model: Option<Vec<Vec<models::ReadOnlyFirst>>>, pub array_array_of_model: Option<Vec<Vec<models::ReadOnlyFirst>>>,
// Note: inline enums are not fully supported by openapi-generator
#[serde(rename = "array_of_enum")]
#[serde(skip_serializing_if="Option::is_none")]
pub array_of_enum: Option<Vec<String>>,
} }
impl ArrayTest { impl ArrayTest {
@ -193,6 +198,7 @@ impl ArrayTest {
array_of_string: None, array_of_string: None,
array_array_of_integer: None, array_array_of_integer: None,
array_array_of_model: None, array_array_of_model: None,
array_of_enum: None,
} }
} }
} }
@ -356,6 +362,11 @@ pub struct EnumArrays {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
pub array_enum: Option<Vec<String>>, pub array_enum: Option<Vec<String>>,
// Note: inline enums are not fully supported by openapi-generator
#[serde(rename = "array_array_enum")]
#[serde(skip_serializing_if="Option::is_none")]
pub array_array_enum: Option<Vec<Vec<String>>>,
} }
impl EnumArrays { impl EnumArrays {
@ -363,6 +374,7 @@ impl EnumArrays {
EnumArrays { EnumArrays {
just_symbol: None, just_symbol: None,
array_enum: None, array_enum: None,
array_array_enum: None,
} }
} }
} }
@ -475,6 +487,10 @@ pub struct FormatTest {
#[serde(rename = "byte")] #[serde(rename = "byte")]
pub byte: swagger::ByteArray, pub byte: swagger::ByteArray,
#[serde(rename = "binary")]
#[serde(skip_serializing_if="Option::is_none")]
pub binary: Option<swagger::ByteArray>,
#[serde(rename = "date")] #[serde(rename = "date")]
pub date: chrono::DateTime<chrono::Utc>, pub date: chrono::DateTime<chrono::Utc>,
@ -502,6 +518,7 @@ impl FormatTest {
double: None, double: None,
string: None, string: None,
byte: byte, byte: byte,
binary: None,
date: date, date: date,
date_time: None, date_time: None,
uuid: None, uuid: None,
@ -553,6 +570,11 @@ pub struct MapTest {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
pub map_map_of_string: Option<HashMap<String, HashMap<String, String>>>, pub map_map_of_string: Option<HashMap<String, HashMap<String, String>>>,
// Note: inline enums are not fully supported by openapi-generator
#[serde(rename = "map_map_of_enum")]
#[serde(skip_serializing_if="Option::is_none")]
pub map_map_of_enum: Option<HashMap<String, HashMap<String, String>>>,
// Note: inline enums are not fully supported by openapi-generator // Note: inline enums are not fully supported by openapi-generator
#[serde(rename = "map_of_enum_string")] #[serde(rename = "map_of_enum_string")]
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
@ -564,6 +586,7 @@ impl MapTest {
pub fn new() -> MapTest { pub fn new() -> MapTest {
MapTest { MapTest {
map_map_of_string: None, map_map_of_string: None,
map_map_of_enum: None,
map_of_enum_string: None, map_of_enum_string: None,
} }
} }

View File

@ -7,7 +7,6 @@ extern crate openssl;
extern crate mime; extern crate mime;
extern crate uuid; extern crate uuid;
extern crate chrono; extern crate chrono;
extern crate multipart;
extern crate percent_encoding; extern crate percent_encoding;
extern crate url; extern crate url;
@ -20,8 +19,6 @@ use hyper::{Request, Response, Error, StatusCode};
use hyper::header::{Headers, ContentType}; use hyper::header::{Headers, ContentType};
use self::url::form_urlencoded; use self::url::form_urlencoded;
use mimetypes; use mimetypes;
use self::multipart::server::Multipart;
use self::multipart::server::save::SaveResult;
use serde_json; use serde_json;
use serde_xml_rs; use serde_xml_rs;
@ -832,185 +829,26 @@ where
let boundary = match multipart_boundary(&headers) { Box::new({
Some(boundary) => boundary.to_string(), {{
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))),
};
Box::new(body.concat2()
.then(move |result| -> Box<Future<Item=Response, Error=Error>> {
match result {
Ok(body) => {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
SaveResult::Full(entries) => {
entries
},
_ => {
return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts"))))
},
};
// Form parameters // Form parameters
let param_integer = entries.fields.remove("integer"); let param_integer = Some(56);
let param_integer = match param_integer { let param_int32 = Some(56);
Some(entry) => let param_int64 = Some(789);
let param_number = 8.14;
let param_float = Some(3.4);
let param_double = 1.2;
let param_string = Some("string_example".to_string());
let param_pattern_without_delimiter = "pattern_without_delimiter_example".to_string();
let param_byte = swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE"));
let param_binary = Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE")));
let param_date = None;
let param_date_time = None;
let param_password = Some("password_example".to_string());
let param_callback = Some("callback_example".to_string());
match entry.parse::<i32>() { Box::new(api_impl.test_endpoint_parameters(param_number, param_double, param_pattern_without_delimiter, param_byte, param_integer, param_int32, param_int64, param_float, param_string, param_binary, param_date, param_date_time, param_password, param_callback, &context)
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_int32 = entries.fields.remove("int32");
let param_int32 = match param_int32 {
Some(entry) =>
match entry.parse::<i32>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_int64 = entries.fields.remove("int64");
let param_int64 = match param_int64 {
Some(entry) =>
match entry.parse::<i64>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_number = entries.fields.remove("number");
let param_number = match param_number {
Some(entry) =>
match entry.parse::<f64>() {
Ok(entry) => entry,
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse form parameter number - doesn't match schema: {}", e)))),
},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter number")))),
};
let param_float = entries.fields.remove("float");
let param_float = match param_float {
Some(entry) =>
match entry.parse::<f32>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_double = entries.fields.remove("double");
let param_double = match param_double {
Some(entry) =>
match entry.parse::<f64>() {
Ok(entry) => entry,
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse form parameter double - doesn't match schema: {}", e)))),
},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter double")))),
};
let param_string = entries.fields.remove("string");
let param_string = match param_string {
Some(entry) =>
match entry.parse::<String>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_pattern_without_delimiter = entries.fields.remove("pattern_without_delimiter");
let param_pattern_without_delimiter = match param_pattern_without_delimiter {
Some(entry) =>
match entry.parse::<String>() {
Ok(entry) => entry,
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse form parameter pattern_without_delimiter - doesn't match schema: {}", e)))),
},
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Missing required form parameter pattern_without_delimiter")))),
};
let param_binary = entries.fields.remove("binary");
let param_binary = match param_binary {
Some(entry) =>
Some(Box::new(stream::once(Ok(entry.as_bytes().to_vec()))) as Box<Stream<Item=Vec<u8>, Error=io::Error> + Send>),
None => None,
};
let param_binary = Box::new(future::ok(param_binary));
let param_date = entries.fields.remove("date");
let param_date = match param_date {
Some(entry) =>
match entry.parse::<chrono::DateTime<chrono::Utc>>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_date_time = entries.fields.remove("date_time");
let param_date_time = match param_date_time {
Some(entry) =>
match entry.parse::<chrono::DateTime<chrono::Utc>>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_password = entries.fields.remove("password");
let param_password = match param_password {
Some(entry) =>
match entry.parse::<String>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_callback = entries.fields.remove("callback");
let param_callback = match param_callback {
Some(entry) =>
match entry.parse::<String>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
Box::new(api_impl.test_endpoint_parameters(param_number, param_double, param_pattern_without_delimiter, param_integer, param_int32, param_int64, param_float, param_string, param_binary, param_date, param_date_time, param_password, param_callback, &context)
.then(move |result| { .then(move |result| {
let mut response = Response::new(); let mut response = Response::new();
response.headers_mut().set(XSpanId((&context as &Has<XSpanIdString>).get().0.to_string())); response.headers_mut().set(XSpanId((&context as &Has<XSpanIdString>).get().0.to_string()));
@ -1044,12 +882,8 @@ where
} }
)) ))
as Box<Future<Item=Response, Error=Error>> }}
}, }) as Box<Future<Item=Response, Error=Error>>
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))),
}
})
)
}, },
@ -1099,7 +933,10 @@ where
Box::new({ Box::new({
{{ {{
Box::new(api_impl.test_enum_parameters(param_enum_header_string_array.as_ref(), param_enum_header_string, param_enum_query_string_array.as_ref(), param_enum_query_string, param_enum_query_integer, param_enum_query_double, &context) // Form parameters
let param_enum_form_string = Some("enum_form_string_example".to_string());
Box::new(api_impl.test_enum_parameters(param_enum_header_string_array.as_ref(), param_enum_header_string, param_enum_query_string_array.as_ref(), param_enum_query_string, param_enum_query_integer, param_enum_query_double, param_enum_form_string, &context)
.then(move |result| { .then(move |result| {
let mut response = Response::new(); let mut response = Response::new();
response.headers_mut().set(XSpanId((&context as &Has<XSpanIdString>).get().0.to_string())); response.headers_mut().set(XSpanId((&context as &Has<XSpanIdString>).get().0.to_string()));
@ -2108,46 +1945,12 @@ where
let boundary = match multipart_boundary(&headers) { Box::new({
Some(boundary) => boundary.to_string(), {{
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Couldn't find valid multipart body"))),
};
Box::new(body.concat2()
.then(move |result| -> Box<Future<Item=Response, Error=Error>> {
match result {
Ok(body) => {
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
SaveResult::Full(entries) => {
entries
},
_ => {
return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Unable to process all message parts"))))
},
};
// Form parameters // Form parameters
let param_additional_metadata = entries.fields.remove("additional_metadata"); let param_additional_metadata = Some("additional_metadata_example".to_string());
let param_additional_metadata = match param_additional_metadata { let param_file = Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE")));
Some(entry) =>
match entry.parse::<String>() {
Ok(entry) => Some(entry),
Err(_) => None,
},
None => None,
};
let param_file = entries.fields.remove("file");
let param_file = match param_file {
Some(entry) =>
Some(Box::new(stream::once(Ok(entry.as_bytes().to_vec()))) as Box<Stream<Item=Vec<u8>, Error=io::Error> + Send>),
None => None,
};
let param_file = Box::new(future::ok(param_file));
Box::new(api_impl.upload_file(param_pet_id, param_additional_metadata, param_file, &context) Box::new(api_impl.upload_file(param_pet_id, param_additional_metadata, param_file, &context)
.then(move |result| { .then(move |result| {
@ -2184,12 +1987,8 @@ where
} }
)) ))
as Box<Future<Item=Response, Error=Error>> }}
}, }) as Box<Future<Item=Response, Error=Error>>
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read multipart body")))),
}
})
)
}, },
@ -3140,123 +2939,3 @@ where
} }
} }
} }
/// Utility function to get the multipart boundary marker (if any) from the Headers.
fn multipart_boundary<'a>(headers: &'a Headers) -> Option<&'a str> {
headers.get::<ContentType>().and_then(|content_type| {
let ContentType(ref mime) = *content_type;
if mime.type_() == mime::MULTIPART && mime.subtype() == mime::FORM_DATA {
mime.get_param(mime::BOUNDARY).map(|x| x.as_str())
} else {
None
}
})
}
/// Request parser for `Api`.
pub struct ApiRequestParser;
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() {
// TestSpecialTags - PATCH /another-fake/dummy
&hyper::Method::Patch if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => Ok("TestSpecialTags"),
// FakeOuterBooleanSerialize - POST /fake/outer/boolean
&hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_BOOLEAN) => Ok("FakeOuterBooleanSerialize"),
// FakeOuterCompositeSerialize - POST /fake/outer/composite
&hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_COMPOSITE) => Ok("FakeOuterCompositeSerialize"),
// FakeOuterNumberSerialize - POST /fake/outer/number
&hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_NUMBER) => Ok("FakeOuterNumberSerialize"),
// FakeOuterStringSerialize - POST /fake/outer/string
&hyper::Method::Post if path.matched(paths::ID_FAKE_OUTER_STRING) => Ok("FakeOuterStringSerialize"),
// TestBodyWithQueryParams - PUT /fake/body-with-query-params
&hyper::Method::Put if path.matched(paths::ID_FAKE_BODY_WITH_QUERY_PARAMS) => Ok("TestBodyWithQueryParams"),
// TestClientModel - PATCH /fake
&hyper::Method::Patch if path.matched(paths::ID_FAKE) => Ok("TestClientModel"),
// TestEndpointParameters - POST /fake
&hyper::Method::Post if path.matched(paths::ID_FAKE) => Ok("TestEndpointParameters"),
// TestEnumParameters - GET /fake
&hyper::Method::Get if path.matched(paths::ID_FAKE) => Ok("TestEnumParameters"),
// TestInlineAdditionalProperties - POST /fake/inline-additionalProperties
&hyper::Method::Post if path.matched(paths::ID_FAKE_INLINE_ADDITIONALPROPERTIES) => Ok("TestInlineAdditionalProperties"),
// TestJsonFormData - GET /fake/jsonFormData
&hyper::Method::Get if path.matched(paths::ID_FAKE_JSONFORMDATA) => Ok("TestJsonFormData"),
// TestClassname - PATCH /fake_classname_test
&hyper::Method::Patch if path.matched(paths::ID_FAKE_CLASSNAME_TEST) => Ok("TestClassname"),
// AddPet - POST /pet
&hyper::Method::Post if path.matched(paths::ID_PET) => Ok("AddPet"),
// DeletePet - DELETE /pet/{petId}
&hyper::Method::Delete if path.matched(paths::ID_PET_PETID) => Ok("DeletePet"),
// FindPetsByStatus - GET /pet/findByStatus
&hyper::Method::Get if path.matched(paths::ID_PET_FINDBYSTATUS) => Ok("FindPetsByStatus"),
// FindPetsByTags - GET /pet/findByTags
&hyper::Method::Get if path.matched(paths::ID_PET_FINDBYTAGS) => Ok("FindPetsByTags"),
// GetPetById - GET /pet/{petId}
&hyper::Method::Get if path.matched(paths::ID_PET_PETID) => Ok("GetPetById"),
// UpdatePet - PUT /pet
&hyper::Method::Put if path.matched(paths::ID_PET) => Ok("UpdatePet"),
// UpdatePetWithForm - POST /pet/{petId}
&hyper::Method::Post if path.matched(paths::ID_PET_PETID) => Ok("UpdatePetWithForm"),
// UploadFile - POST /pet/{petId}/uploadImage
&hyper::Method::Post if path.matched(paths::ID_PET_PETID_UPLOADIMAGE) => Ok("UploadFile"),
// DeleteOrder - DELETE /store/order/{order_id}
&hyper::Method::Delete if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => Ok("DeleteOrder"),
// GetInventory - GET /store/inventory
&hyper::Method::Get if path.matched(paths::ID_STORE_INVENTORY) => Ok("GetInventory"),
// GetOrderById - GET /store/order/{order_id}
&hyper::Method::Get if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => Ok("GetOrderById"),
// PlaceOrder - POST /store/order
&hyper::Method::Post if path.matched(paths::ID_STORE_ORDER) => Ok("PlaceOrder"),
// CreateUser - POST /user
&hyper::Method::Post if path.matched(paths::ID_USER) => Ok("CreateUser"),
// CreateUsersWithArrayInput - POST /user/createWithArray
&hyper::Method::Post if path.matched(paths::ID_USER_CREATEWITHARRAY) => Ok("CreateUsersWithArrayInput"),
// CreateUsersWithListInput - POST /user/createWithList
&hyper::Method::Post if path.matched(paths::ID_USER_CREATEWITHLIST) => Ok("CreateUsersWithListInput"),
// DeleteUser - DELETE /user/{username}
&hyper::Method::Delete if path.matched(paths::ID_USER_USERNAME) => Ok("DeleteUser"),
// GetUserByName - GET /user/{username}
&hyper::Method::Get if path.matched(paths::ID_USER_USERNAME) => Ok("GetUserByName"),
// LoginUser - GET /user/login
&hyper::Method::Get if path.matched(paths::ID_USER_LOGIN) => Ok("LoginUser"),
// LogoutUser - GET /user/logout
&hyper::Method::Get if path.matched(paths::ID_USER_LOGOUT) => Ok("LogoutUser"),
// UpdateUser - PUT /user/{username}
&hyper::Method::Put if path.matched(paths::ID_USER_USERNAME) => Ok("UpdateUser"),
_ => Err(()),
}
}
}