Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 66 additions & 14 deletions modules/swagger-codegen/src/main/resources/rust/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use std::rc::Rc;
use std::borrow::Borrow;
use std::borrow::Cow;
use std::collections::HashMap;

use hyper;
use serde_json;
Expand Down Expand Up @@ -39,26 +40,71 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
fn {{{operationId}}}(&self, {{#allParams}}{{paramName}}: {{#isString}}&str{{/isString}}{{#isUuid}}&str{{/isUuid}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}::models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Box<Future<Item = {{^returnType}}(){{/returnType}}{{#returnType}}{{{.}}}{{/returnType}}, Error = Error<serde_json::Value>>> {
let configuration: &configuration::Configuration<C> = self.configuration.borrow();

{{#hasAuthMethods}}
let mut auth_headers = HashMap::<String, String>::new();
let mut auth_query = HashMap::<String, String>::new();
{{#authMethods}}
{{#isApiKey}}
if let Some(ref apikey) = configuration.api_key {
let key = apikey.key.clone();
let val = match apikey.prefix {
Some(ref prefix) => format!("{} {}", prefix, key),
None => key,
};
{{#isKeyInHeader}}
auth_headers.insert("{{keyParamName}}".to_owned(), val);
{{/isKeyInHeader}}
{{#isKeyInQuery}}
auth_query.insert("{{keyParamName}}".to_owned(), val);
{{/isKeyInQuery}}
};
{{/isApiKey}}
{{#isBasic}}
if let Some(ref auth_conf) = configuration.basic_auth {
let auth = hyper::header::Authorization(
hyper::header::Basic {
username: auth_conf.0.to_owned(),
password: auth_conf.1.to_owned(),
}
);
auth_headers.insert("Authorization".to_owned(), auth.to_string());
};
{{/isBasic}}
{{#isOAuth}}
if let Some(ref token) = configuration.oauth_access_token {
let auth = hyper::header::Authorization(
hyper::header::Bearer {
token: token.to_owned(),
}
);
auth_headers.insert("Authorization".to_owned(), auth.to_string());
};
{{/isOAuth}}
{{/authMethods}}
{{/hasAuthMethods}}
let method = hyper::Method::{{httpMethod}};

{{^hasQueryParams}}
let uri_str = format!("{}{{{path}}}", configuration.base_path{{#pathParams}}, {{baseName}}={{paramName}}{{#isListContainer}}.join(",").as_ref(){{/isListContainer}}{{/pathParams}});
{{/hasQueryParams}}
{{#hasQueryParams}}
let query = ::url::form_urlencoded::Serializer::new(String::new())
{{#queryParams}}
.append_pair("{{baseName}}", &{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}.to_string())
{{/queryParams}}
.finish();
let uri_str = format!("{}{{{path}}}{}", configuration.base_path, query{{#pathParams}}, {{baseName}}={{paramName}}{{#isListContainer}}.join(",").as_ref(){{/isListContainer}}{{/pathParams}});
{{/hasQueryParams}}

let uri = uri_str.parse();
let query_string = {
let mut query = ::url::form_urlencoded::Serializer::new(String::new());
{{#queryParams}}
query.append_pair("{{baseName}}", &{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}.to_string());
{{/queryParams}}
{{#hasAuthMethods}}
for (key, val) in &auth_query {
query.append_pair(key, val);
}
{{/hasAuthMethods}}
query.finish()
};
let uri_str = format!("{}{{{path}}}?{}", configuration.base_path, query_string{{#pathParams}}, {{baseName}}={{paramName}}{{#isListContainer}}.join(",").as_ref(){{/isListContainer}}{{/pathParams}});

// TODO(farcaller): handle error
// if let Err(e) = uri {
// return Box::new(futures::future::err(e));
// }
let mut req = hyper::Request::new(method, uri.unwrap());
let mut uri: hyper::Uri = uri_str.parse().unwrap();

let mut req = hyper::Request::new(method, uri);

if let Some(ref user_agent) = configuration.user_agent {
req.headers_mut().set(UserAgent::new(Cow::Owned(user_agent.clone())));
Expand All @@ -73,6 +119,12 @@ impl<C: hyper::client::Connect>{{classname}} for {{classname}}Client<C> {
}
{{/hasHeaderParams}}

{{#hasAuthMethods}}
for (key, val) in auth_headers {
req.headers_mut().set_raw(key, val);
}
{{/hasAuthMethods}}

{{#hasBodyParam}}
{{#bodyParams}}
let serialized = serde_json::to_string(&{{paramName}}).unwrap();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
{{>partial_header}}
use hyper;
use std::collections::HashMap;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not going to yield warnings? It might be nice to allow the warning or only add this use statement if necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would, but at this point we're too far gone on warnings.

I would like to do a pass dedicated to squashing warnings at some point, which I think will be easiest with a certain amount of refactoring. For now, I'm okay with living with another warning in the sea of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be specific, I think refactoring the shared code (the whole fn operationId bit) to be one generic function which takes configurable things as parameters would result in more readable code that would be easier to eliminate warnings from... if only because all the code would be there and just not be called necessarily. Each operation would then just be a short function calling the big generic "do_call" style function with appropriate args.

I recall some of the other clients take this approach, but I don't have references handy because I dug into this some months ago.


pub struct Configuration<C: hyper::client::Connect> {
pub base_path: String,
pub user_agent: Option<String>,
pub client: hyper::client::Client<C>,
pub basic_auth: Option<BasicAuth>,
pub oauth_access_token: Option<String>,
pub api_key: Option<ApiKey>,
// TODO: take an oauth2 token source, similar to the go one
}

pub type BasicAuth = (String, Option<String>);

pub struct ApiKey {
pub prefix: Option<String>,
pub key: String,
}

impl<C: hyper::client::Connect> Configuration<C> {
Expand All @@ -13,6 +25,9 @@ impl<C: hyper::client::Connect> Configuration<C> {
base_path: "{{{basePath}}}".to_owned(),
user_agent: {{#httpUserAgent}}Some("{{{.}}}".to_owned()){{/httpUserAgent}}{{^httpUserAgent}}Some("Swagger-Codegen/{{version}}/rust".to_owned()){{/httpUserAgent}},
client: client,
basic_auth: None,
oauth_access_token: None,
api_key: None,
}
}
}
2 changes: 1 addition & 1 deletion samples/client/petstore/rust/docs/UserApi.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Get user by user name

Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**username** | **String**| The name that needs to be fetched. Use user1 for testing. |
**username** | **String**| The name that needs to be fetched. Use user1 for testing. |

### Return type

Expand Down
15 changes: 15 additions & 0 deletions samples/client/petstore/rust/src/apis/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,23 @@
*/

use hyper;
use std::collections::HashMap;

pub struct Configuration<C: hyper::client::Connect> {
pub base_path: String,
pub user_agent: Option<String>,
pub client: hyper::client::Client<C>,
pub basic_auth: Option<BasicAuth>,
pub oauth_access_token: Option<String>,
pub api_key: Option<ApiKey>,
// TODO: take an oauth2 token source, similar to the go one
}

pub type BasicAuth = (String, Option<String>);

pub struct ApiKey {
pub prefix: Option<String>,
pub key: String,
}

impl<C: hyper::client::Connect> Configuration<C> {
Expand All @@ -22,6 +34,9 @@ impl<C: hyper::client::Connect> Configuration<C> {
base_path: "http://petstore.swagger.io/v2".to_owned(),
user_agent: Some("Swagger-Codegen/1.0.0/rust".to_owned()),
client: client,
basic_auth: None,
oauth_access_token: None,
api_key: None,
}
}
}
Loading