[Rust] Handle error response statuses (#6865)

* [Rust] Consider error statuscodes to be errors

* [Rust] Introduce 'ApiError' type for 4xx/5xx resp

This updates the previous commit which added an 'ErrorStatus' variant to
an 'ApiError' variant.

It does not specialize the error to the specific possible error
responses yet, rather returning a 'serde_json::Value' for any case.

This will lose any error messages which cannot be parsed as json and
instead return a json-parse error.

A future change should update the generated signatures such that the
returned future's error type is specialized to the specific errors that
may be returned by that api (and possibly a catchall json::Value still).

* [Rust] Regenerate petstore samples

* [Rust] Add error example to petstore sample
This commit is contained in:
Euan Kemp 2018-01-14 19:38:11 -08:00 committed by William Cheng
parent 06d0078366
commit 027df610b1
12 changed files with 467 additions and 85 deletions

View File

@ -27,7 +27,7 @@ impl<C: hyper::client::Connect> {{{classname}}}Client<C> {
pub trait {{classname}} {
{{#operations}}
{{#operation}}
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error = Error>>;
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{returnType}}}{{/returnType}}, Error = Error<serde_json::Value>>>;
{{/operation}}
{{/operations}}
}
@ -36,7 +36,7 @@ pub trait {{classname}} {
impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
{{#operations}}
{{#operation}}
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{.}}}{{/returnType}}, Error = Error>> {
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{.}}}{{/returnType}}, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::{{httpMethod}};
@ -84,8 +84,21 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
{{^returnType}}
.and_then(|_| futures::future::ok(()))
{{/returnType}}
@ -93,7 +106,7 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
.and_then(|body| {
let parsed: Result<{{{returnType}}}, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
{{/returnType}}
)
}

View File

@ -1,19 +1,48 @@
use hyper;
use serde;
use serde_json;
#[derive(Debug)]
pub enum Error {
pub enum Error<T> {
Hyper(hyper::Error),
Serde(serde_json::Error),
ApiError(ApiError<T>),
}
impl From<hyper::Error> for Error {
#[derive(Debug)]
pub struct ApiError<T> {
pub code: hyper::StatusCode,
pub content: Option<T>,
}
impl<'de, T> From<(hyper::StatusCode, &'de [u8])> for Error<T>
where T: serde::Deserialize<'de> {
fn from(e: (hyper::StatusCode, &'de [u8])) -> Self {
if e.1.len() == 0 {
return Error::ApiError(ApiError{
code: e.0,
content: None,
});
}
match serde_json::from_slice::<T>(e.1) {
Ok(t) => Error::ApiError(ApiError{
code: e.0,
content: Some(t),
}),
Err(e) => {
Error::from(e)
}
}
}
}
impl<T> From<hyper::Error> for Error<T> {
fn from(e: hyper::Error) -> Self {
return Error::Hyper(e)
}
}
impl From<serde_json::Error> for Error {
impl<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
return Error::Serde(e)
}

View File

@ -2,6 +2,7 @@
extern crate serde_derive;
extern crate hyper;
extern crate serde;
extern crate serde_json;
extern crate futures;
extern crate url;

View File

@ -0,0 +1,49 @@
extern crate futures;
extern crate hyper;
extern crate petstore_client;
extern crate tokio_core;
use hyper::Client;
use hyper::client::HttpConnector;
use tokio_core::reactor::Core;
use futures::Future;
use petstore_client::apis::client::APIClient;
use petstore_client::apis::Error;
fn main() {
let mut core = Core::new().expect("failed to init core");
let handle = core.handle();
let mut configuration = petstore_client::apis::configuration::Configuration::new(
Client::configure()
.connector(HttpConnector::new(4, &handle))
.build(&handle),
);
if let Ok(env_override) = std::env::var("PETSTORE_BASEPATH") {
configuration.base_path = env_override;
}
let apicli = APIClient::new(configuration);
let work = apicli
.user_api()
.delete_user("404")
.then(|resp| match resp {
Ok(resp) => {
panic!(format!(
"update for nonexistent pet should fail, but got: {:?}",
resp
));
}
Err(Error::ApiError(s)) => {
println!("got expected error: {:?}", s);
futures::future::ok::<(), ()>(())
}
Err(Error::Hyper(e)) => {
println!("network error: {}", e);
futures::future::ok::<(), ()>(())
}
Err(e) => panic!("unexpected error: {:?}", e),
});
core.run(work).expect("failed to run core");
}

View File

@ -1,19 +1,48 @@
use hyper;
use serde;
use serde_json;
#[derive(Debug)]
pub enum Error {
pub enum Error<T> {
Hyper(hyper::Error),
Serde(serde_json::Error),
ApiError(ApiError<T>),
}
impl From<hyper::Error> for Error {
#[derive(Debug)]
pub struct ApiError<T> {
pub code: hyper::StatusCode,
pub content: Option<T>,
}
impl<'de, T> From<(hyper::StatusCode, &'de [u8])> for Error<T>
where T: serde::Deserialize<'de> {
fn from(e: (hyper::StatusCode, &'de [u8])) -> Self {
if e.1.len() == 0 {
return Error::ApiError(ApiError{
code: e.0,
content: None,
});
}
match serde_json::from_slice::<T>(e.1) {
Ok(t) => Error::ApiError(ApiError{
code: e.0,
content: Some(t),
}),
Err(e) => {
Error::from(e)
}
}
}
}
impl<T> From<hyper::Error> for Error<T> {
fn from(e: hyper::Error) -> Self {
return Error::Hyper(e)
}
}
impl From<serde_json::Error> for Error {
impl<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
return Error::Serde(e)
}

View File

@ -34,19 +34,19 @@ impl<C: hyper::client::Connect> PetApiClient<C> {
}
pub trait PetApi {
fn add_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error>>;
fn delete_pet(&self, pet_id: i64, api_key: &str) -> Box<Future<Item = (), Error = Error>>;
fn find_pets_by_status(&self, status: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error>>;
fn find_pets_by_tags(&self, tags: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error>>;
fn get_pet_by_id(&self, pet_id: i64) -> Box<Future<Item = ::models::Pet, Error = Error>>;
fn update_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error>>;
fn update_pet_with_form(&self, pet_id: i64, name: &str, status: &str) -> Box<Future<Item = (), Error = Error>>;
fn upload_file(&self, pet_id: i64, additional_metadata: &str, file: ::models::File) -> Box<Future<Item = ::models::ApiResponse, Error = Error>>;
fn add_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn delete_pet(&self, pet_id: i64, api_key: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn find_pets_by_status(&self, status: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error<serde_json::Value>>>;
fn find_pets_by_tags(&self, tags: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error<serde_json::Value>>>;
fn get_pet_by_id(&self, pet_id: i64) -> Box<Future<Item = ::models::Pet, Error = Error<serde_json::Value>>>;
fn update_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn update_pet_with_form(&self, pet_id: i64, name: &str, status: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn upload_file(&self, pet_id: i64, additional_metadata: &str, file: ::models::File) -> Box<Future<Item = ::models::ApiResponse, Error = Error<serde_json::Value>>>;
}
impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
fn add_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error>> {
fn add_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -72,13 +72,26 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn delete_pet(&self, pet_id: i64, api_key: &str) -> Box<Future<Item = (), Error = Error>> {
fn delete_pet(&self, pet_id: i64, api_key: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Delete;
@ -104,13 +117,26 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn find_pets_by_status(&self, status: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error>> {
fn find_pets_by_status(&self, status: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -135,16 +161,29 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<Vec<::models::Pet>, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn find_pets_by_tags(&self, tags: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error>> {
fn find_pets_by_tags(&self, tags: Vec<String>) -> Box<Future<Item = Vec<::models::Pet>, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -169,16 +208,29 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<Vec<::models::Pet>, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn get_pet_by_id(&self, pet_id: i64) -> Box<Future<Item = ::models::Pet, Error = Error>> {
fn get_pet_by_id(&self, pet_id: i64) -> Box<Future<Item = ::models::Pet, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -200,16 +252,29 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::models::Pet, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn update_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error>> {
fn update_pet(&self, body: ::models::Pet) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Put;
@ -235,13 +300,26 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn update_pet_with_form(&self, pet_id: i64, name: &str, status: &str) -> Box<Future<Item = (), Error = Error>> {
fn update_pet_with_form(&self, pet_id: i64, name: &str, status: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -263,13 +341,26 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn upload_file(&self, pet_id: i64, additional_metadata: &str, file: ::models::File) -> Box<Future<Item = ::models::ApiResponse, Error = Error>> {
fn upload_file(&self, pet_id: i64, additional_metadata: &str, file: ::models::File) -> Box<Future<Item = ::models::ApiResponse, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -291,12 +382,25 @@ impl<C: hyper::client::Connect>PetApi for PetApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::models::ApiResponse, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}

View File

@ -34,15 +34,15 @@ impl<C: hyper::client::Connect> StoreApiClient<C> {
}
pub trait StoreApi {
fn delete_order(&self, order_id: &str) -> Box<Future<Item = (), Error = Error>>;
fn get_inventory(&self, ) -> Box<Future<Item = ::std::collections::HashMap<String, i32>, Error = Error>>;
fn get_order_by_id(&self, order_id: i64) -> Box<Future<Item = ::models::Order, Error = Error>>;
fn place_order(&self, body: ::models::Order) -> Box<Future<Item = ::models::Order, Error = Error>>;
fn delete_order(&self, order_id: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn get_inventory(&self, ) -> Box<Future<Item = ::std::collections::HashMap<String, i32>, Error = Error<serde_json::Value>>>;
fn get_order_by_id(&self, order_id: i64) -> Box<Future<Item = ::models::Order, Error = Error<serde_json::Value>>>;
fn place_order(&self, body: ::models::Order) -> Box<Future<Item = ::models::Order, Error = Error<serde_json::Value>>>;
}
impl<C: hyper::client::Connect>StoreApi for StoreApiClient<C> {
fn delete_order(&self, order_id: &str) -> Box<Future<Item = (), Error = Error>> {
fn delete_order(&self, order_id: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Delete;
@ -64,13 +64,26 @@ impl<C: hyper::client::Connect>StoreApi for StoreApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn get_inventory(&self, ) -> Box<Future<Item = ::std::collections::HashMap<String, i32>, Error = Error>> {
fn get_inventory(&self, ) -> Box<Future<Item = ::std::collections::HashMap<String, i32>, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -92,16 +105,29 @@ impl<C: hyper::client::Connect>StoreApi for StoreApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::std::collections::HashMap<String, i32>, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn get_order_by_id(&self, order_id: i64) -> Box<Future<Item = ::models::Order, Error = Error>> {
fn get_order_by_id(&self, order_id: i64) -> Box<Future<Item = ::models::Order, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -123,16 +149,29 @@ impl<C: hyper::client::Connect>StoreApi for StoreApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::models::Order, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn place_order(&self, body: ::models::Order) -> Box<Future<Item = ::models::Order, Error = Error>> {
fn place_order(&self, body: ::models::Order) -> Box<Future<Item = ::models::Order, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -158,12 +197,25 @@ impl<C: hyper::client::Connect>StoreApi for StoreApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::models::Order, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}

View File

@ -34,19 +34,19 @@ impl<C: hyper::client::Connect> UserApiClient<C> {
}
pub trait UserApi {
fn create_user(&self, body: ::models::User) -> Box<Future<Item = (), Error = Error>>;
fn create_users_with_array_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error>>;
fn create_users_with_list_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error>>;
fn delete_user(&self, username: &str) -> Box<Future<Item = (), Error = Error>>;
fn get_user_by_name(&self, username: &str) -> Box<Future<Item = ::models::User, Error = Error>>;
fn login_user(&self, username: &str, password: &str) -> Box<Future<Item = String, Error = Error>>;
fn logout_user(&self, ) -> Box<Future<Item = (), Error = Error>>;
fn update_user(&self, username: &str, body: ::models::User) -> Box<Future<Item = (), Error = Error>>;
fn create_user(&self, body: ::models::User) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn create_users_with_array_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn create_users_with_list_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn delete_user(&self, username: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn get_user_by_name(&self, username: &str) -> Box<Future<Item = ::models::User, Error = Error<serde_json::Value>>>;
fn login_user(&self, username: &str, password: &str) -> Box<Future<Item = String, Error = Error<serde_json::Value>>>;
fn logout_user(&self, ) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
fn update_user(&self, username: &str, body: ::models::User) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
}
impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
fn create_user(&self, body: ::models::User) -> Box<Future<Item = (), Error = Error>> {
fn create_user(&self, body: ::models::User) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -72,13 +72,26 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn create_users_with_array_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error>> {
fn create_users_with_array_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -104,13 +117,26 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn create_users_with_list_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error>> {
fn create_users_with_list_input(&self, body: Vec<::models::User>) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Post;
@ -136,13 +162,26 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn delete_user(&self, username: &str) -> Box<Future<Item = (), Error = Error>> {
fn delete_user(&self, username: &str) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Delete;
@ -164,13 +203,26 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn get_user_by_name(&self, username: &str) -> Box<Future<Item = ::models::User, Error = Error>> {
fn get_user_by_name(&self, username: &str) -> Box<Future<Item = ::models::User, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -192,16 +244,29 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<::models::User, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn login_user(&self, username: &str, password: &str) -> Box<Future<Item = String, Error = Error>> {
fn login_user(&self, username: &str, password: &str) -> Box<Future<Item = String, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -227,16 +292,29 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|body| {
let parsed: Result<String, _> = serde_json::from_slice(&body);
parsed.map_err(|e| Error::from(e))
}).map_err(|e| Error::from(e))
})
)
}
fn logout_user(&self, ) -> Box<Future<Item = (), Error = Error>> {
fn logout_user(&self, ) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Get;
@ -258,13 +336,26 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}
fn update_user(&self, username: &str, body: ::models::User) -> Box<Future<Item = (), Error = Error>> {
fn update_user(&self, username: &str, body: ::models::User) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();
let method = hyper::Method::Put;
@ -290,8 +381,21 @@ impl<C: hyper::client::Connect>UserApi for UserApiClient<C> {
// send request
Box::new(
configuration.client.request(req).and_then(|res| { res.body().concat2() })
configuration.client.request(req)
.map_err(|e| Error::from(e))
.and_then(|resp| {
let status = resp.status();
resp.body().concat2()
.and_then(move |body| Ok((status, body)))
.map_err(|e| Error::from(e))
})
.and_then(|(status, body)| {
if status.is_success() {
Ok(body)
} else {
Err(Error::from((status, &*body)))
}
})
.and_then(|_| futures::future::ok(()))
)
}

View File

@ -2,6 +2,7 @@
extern crate serde_derive;
extern crate hyper;
extern crate serde;
extern crate serde_json;
extern crate futures;
extern crate url;

View File

@ -1 +1 @@
2.3.0-SNAPSHOT
2.3.0

View File

@ -13,7 +13,7 @@ To see how to make this your own, look here:
[README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md)
- API version: 1.0.0
- Build date: 2017-12-20T15:51:59.221+09:00
- Build date: 2018-01-07T09:31:52.377-08:00
This autogenerated project defines an API crate `petstore_api` which contains:
* An `Api` trait defining the API in Rust.

View File

@ -143,11 +143,11 @@ paths:
type: "array"
items:
type: "string"
default: "available"
enum:
- "available"
- "pending"
- "sold"
default: "available"
collectionFormat: "csv"
formatString: "{:?}"
example: "&Vec::new()"
@ -938,10 +938,10 @@ paths:
type: "array"
items:
type: "string"
default: "$"
enum:
- ">"
- "$"
default: "$"
formatString: "{:?}"
example: "Some(&Vec::new())"
- name: "enum_form_string"
@ -963,10 +963,10 @@ paths:
type: "array"
items:
type: "string"
default: "$"
enum:
- ">"
- "$"
default: "$"
formatString: "{:?}"
example: "Some(&Vec::new())"
- name: "enum_header_string"
@ -988,10 +988,10 @@ paths:
type: "array"
items:
type: "string"
default: "$"
enum:
- ">"
- "$"
default: "$"
formatString: "{:?}"
example: "Some(&Vec::new())"
- name: "enum_query_string"