[rust] Make it easier to test rust client generator (#3543)

As we discovered in #3463, there are various bits of the rust client generator that are currently untested. This PR adds tests for various generator-specific types, and also files.

Follows the example of the rust-server generator for making it easy to add new test specs. This should make it easier for future contributors to make sure that their contributions are tested
This commit is contained in:
Benjamin Gill 2019-09-27 16:27:28 +01:00 committed by GitHub
parent 5f6e53fc60
commit eb793ae279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
134 changed files with 2064 additions and 174 deletions

View File

@ -27,6 +27,21 @@ fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/rust -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g rust -o samples/client/petstore/rust --additional-properties packageName=petstore_client --library=hyper $@"
java ${JAVA_OPTS} -jar ${executable} ${ags}
for spec_path in \
modules/openapi-generator/src/test/resources/2_0/petstore.yaml \
modules/openapi-generator/src/test/resources/3_0/rust/rust-test.yaml \
modules/openapi-generator/src/test/resources/2_0/fileResponseTest.json\
; do
spec=$(basename "$spec_path" | sed 's/.yaml//' | sed 's/.json//' )
for library in hyper reqwest; do
args="generate --template-dir modules/openapi-generator/src/main/resources/rust
--input-spec $spec_path
--generator-name rust
--output samples/client/petstore/rust/$library/$spec
--additional-properties packageName=${spec}-${library}
--library=$library $@"
java ${JAVA_OPTS} -jar ${executable} ${args} || exit 1
done
done

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
echo "# START SCRIPT: $SCRIPT"
while [ -h "$SCRIPT" ] ; do
ls=$(ls -ld "$SCRIPT")
link=$(expr "$ls" : '.*-> \(.*\)$')
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=$(dirname "$SCRIPT")/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=$(dirname "$SCRIPT")/..
APP_DIR=$(cd "${APP_DIR}"; pwd)
fi
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
if [ ! -f "$executable" ]
then
mvn -B clean package
fi
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="generate -t modules/openapi-generator/src/main/resources/rust -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g rust -o samples/client/petstore/rust-reqwest --additional-properties packageName=petstore_client --library=reqwest $@"
java ${JAVA_OPTS} -jar ${executable} ${ags}

View File

@ -0,0 +1,31 @@
openapi: 3.0.1
info:
title: Rust client test spec
description: Special testing for the Rust client generator
version: 1.0.7
paths:
/dummy:
get:
summary: A dummy endpoint to make the spec valid.
responses:
'200':
description: Success
components:
schemas:
TypeTesting:
description: Test handling of differing types (see \#3463)
type: object
properties:
integer:
type: integer
long:
type: long
number:
type: number
float:
type: float
double:
type: double
uuid:
type: string
format: uuid

View File

@ -1039,7 +1039,6 @@
<!-- <module>samples/client/petstore/cpp-qt5</module> -->
<module>samples/client/petstore/elm-0.18</module>
<module>samples/client/petstore/rust</module>
<module>samples/client/petstore/rust-reqwest</module>
<!--<module>samples/client/petstore/perl</module>-->
<module>samples/client/petstore/php/OpenAPIClient-php</module>
<module>samples/openapi3/client/petstore/php/OpenAPIClient-php</module>

View File

@ -1,46 +0,0 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openapitools</groupId>
<artifactId>RustReqwestPetstoreClientTests</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Rust (reqwest) Petstore Client</name>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>bundle-test</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>cargo</executable>
<arguments>
<argument>check</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,34 +0,0 @@
use std::rc::Rc;
use super::configuration::Configuration;
pub struct APIClient {
pet_api: Box<crate::apis::PetApi>,
store_api: Box<crate::apis::StoreApi>,
user_api: Box<crate::apis::UserApi>,
}
impl APIClient {
pub fn new(configuration: Configuration) -> APIClient {
let rc = Rc::new(configuration);
APIClient {
pet_api: Box::new(crate::apis::PetApiClient::new(rc.clone())),
store_api: Box::new(crate::apis::StoreApiClient::new(rc.clone())),
user_api: Box::new(crate::apis::UserApiClient::new(rc.clone())),
}
}
pub fn pet_api(&self) -> &crate::apis::PetApi{
self.pet_api.as_ref()
}
pub fn store_api(&self) -> &crate::apis::StoreApi{
self.store_api.as_ref()
}
pub fn user_api(&self) -> &crate::apis::UserApi{
self.user_api.as_ref()
}
}

View File

@ -1,3 +1,2 @@
/target/
**/*.rs.bk
target
Cargo.lock

View File

@ -1 +0,0 @@
4.0.3-SNAPSHOT

View File

@ -1,17 +1,2 @@
[package]
name = "petstore_client"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]
[dependencies]
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
url = "1.5"
hyper = "~0.11"
serde_yaml = "0.7"
base64 = "~0.7.0"
futures = "0.1.23"
[dev-dependencies]
tokio-core = "*"
[workspace]
members = ["hyper/*", "reqwest/*"]

View File

@ -0,0 +1,17 @@
[package]
name = "fileResponseTest-hyper"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]
[dependencies]
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
url = "1.5"
hyper = "~0.11"
serde_yaml = "0.7"
base64 = "~0.7.0"
futures = "0.1.23"
[dev-dependencies]
tokio-core = "*"

View File

@ -0,0 +1,43 @@
# Rust API client for fileResponseTest-hyper
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
## Overview
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
- API version: 1.0.0
- Package version: 1.0.0
- Build package: org.openapitools.codegen.languages.RustClientCodegen
## Installation
Put the package under your project folder and add the following to `Cargo.toml` under `[dependencies]`:
```
openapi = { path = "./generated" }
```
## Documentation for API Endpoints
All URIs are relative to *http://localhost/v2*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*DefaultApi* | [**fileresponsetest**](docs/DefaultApi.md#fileresponsetest) | **Get** /tests/fileResponse |
## Documentation For Models
To get access to the crate's generated documentation, use:
```
cargo doc --open
```
## Author

View File

@ -0,0 +1,34 @@
# \DefaultApi
All URIs are relative to *http://localhost/v2*
Method | HTTP request | Description
------------- | ------------- | -------------
[**fileresponsetest**](DefaultApi.md#fileresponsetest) | **Get** /tests/fileResponse |
## fileresponsetest
> std::path::PathBuf fileresponsetest()
### Parameters
This endpoint does not need any parameter.
### Return type
[**std::path::PathBuf**](std::path::PathBuf.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/octet-stream
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

View File

@ -0,0 +1,23 @@
use std::rc::Rc;
use hyper;
use super::configuration::Configuration;
pub struct APIClient {
default_api: Box<crate::apis::DefaultApi>,
}
impl APIClient {
pub fn new<C: hyper::client::Connect>(configuration: Configuration<C>) -> APIClient {
let rc = Rc::new(configuration);
APIClient {
default_api: Box::new(crate::apis::DefaultApiClient::new(rc.clone())),
}
}
pub fn default_api(&self) -> &crate::apis::DefaultApi{
self.default_api.as_ref()
}
}

View File

@ -0,0 +1,41 @@
/*
* File Response Test
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
use hyper;
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> {
pub fn new(client: hyper::client::Client<C>) -> Configuration<C> {
Configuration {
base_path: "http://localhost/v2".to_owned(),
user_agent: Some("OpenAPI-Generator/1.0.0/rust".to_owned()),
client: client,
basic_auth: None,
oauth_access_token: None,
api_key: None,
}
}
}

View File

@ -0,0 +1,44 @@
/*
* File Response Test
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
use std::rc::Rc;
use std::borrow::Borrow;
use hyper;
use serde_json;
use futures::Future;
use super::{Error, configuration};
use super::request as __internal_request;
pub struct DefaultApiClient<C: hyper::client::Connect> {
configuration: Rc<configuration::Configuration<C>>,
}
impl<C: hyper::client::Connect> DefaultApiClient<C> {
pub fn new(configuration: Rc<configuration::Configuration<C>>) -> DefaultApiClient<C> {
DefaultApiClient {
configuration: configuration,
}
}
}
pub trait DefaultApi {
fn fileresponsetest(&self, ) -> Box<Future<Item = std::path::PathBuf, Error = Error<serde_json::Value>>>;
}
impl<C: hyper::client::Connect>DefaultApi for DefaultApiClient<C> {
fn fileresponsetest(&self, ) -> Box<Future<Item = std::path::PathBuf, Error = Error<serde_json::Value>>> {
__internal_request::Request::new(hyper::Method::Get, "/tests/fileResponse".to_string())
.execute(self.configuration.borrow())
}
}

View File

@ -0,0 +1,58 @@
use hyper;
use serde;
use serde_json;
#[derive(Debug)]
pub enum Error<T> {
UriError(hyper::error::UriError),
Hyper(hyper::Error),
Serde(serde_json::Error),
ApiError(ApiError<T>),
}
#[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<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
return Error::Serde(e)
}
}
mod request;
mod default_api;
pub use self::default_api::{ DefaultApi, DefaultApiClient };
pub mod configuration;
pub mod client;

View File

@ -0,0 +1,3 @@
/target/
**/*.rs.bk
Cargo.lock

View File

@ -0,0 +1 @@
4.1.0-SNAPSHOT

View File

@ -0,0 +1,17 @@
[package]
name = "petstore-hyper"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]
[dependencies]
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
url = "1.5"
hyper = "~0.11"
serde_yaml = "0.7"
base64 = "~0.7.0"
futures = "0.1.23"
[dev-dependencies]
tokio-core = "*"

View File

@ -1,4 +1,4 @@
# Rust API client for petstore_client
# Rust API client for petstore-hyper
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.

View File

@ -0,0 +1,239 @@
use std::borrow::Cow;
use std::collections::HashMap;
use super::{configuration, Error};
use futures;
use futures::{Future, Stream};
use hyper;
use hyper::header::UserAgent;
use serde;
use serde_json;
pub(crate) struct ApiKey {
pub in_header: bool,
pub in_query: bool,
pub param_name: String,
}
impl ApiKey {
fn key(&self, prefix: &Option<String>, key: &str) -> String {
match prefix {
None => key.to_owned(),
Some(ref prefix) => format!("{} {}", prefix, key),
}
}
}
#[allow(dead_code)]
pub(crate) enum Auth {
None,
ApiKey(ApiKey),
Basic,
Oauth,
}
pub(crate) struct Request {
auth: Auth,
method: hyper::Method,
path: String,
query_params: HashMap<String, String>,
no_return_type: bool,
path_params: HashMap<String, String>,
form_params: HashMap<String, String>,
header_params: HashMap<String, String>,
// TODO: multiple body params are possible technically, but not supported here.
serialized_body: Option<String>,
}
impl Request {
pub fn new(method: hyper::Method, path: String) -> Self {
Request {
auth: Auth::None,
method: method,
path: path,
query_params: HashMap::new(),
path_params: HashMap::new(),
form_params: HashMap::new(),
header_params: HashMap::new(),
serialized_body: None,
no_return_type: false,
}
}
pub fn with_body_param<T: serde::Serialize>(mut self, param: T) -> Self {
self.serialized_body = Some(serde_json::to_string(&param).unwrap());
self
}
pub fn with_header_param(mut self, basename: String, param: String) -> Self {
self.header_params.insert(basename, param);
self
}
pub fn with_query_param(mut self, basename: String, param: String) -> Self {
self.query_params.insert(basename, param);
self
}
pub fn with_path_param(mut self, basename: String, param: String) -> Self {
self.path_params.insert(basename, param);
self
}
pub fn with_form_param(mut self, basename: String, param: String) -> Self {
self.form_params.insert(basename, param);
self
}
pub fn returns_nothing(mut self) -> Self {
self.no_return_type = true;
self
}
pub fn with_auth(mut self, auth: Auth) -> Self {
self.auth = auth;
self
}
pub fn execute<'a, C, U>(
self,
conf: &configuration::Configuration<C>,
) -> Box<Future<Item = U, Error = Error<serde_json::Value>> + 'a>
where
C: hyper::client::Connect,
U: Sized + 'a,
for<'de> U: serde::Deserialize<'de>,
{
let mut query_string = ::url::form_urlencoded::Serializer::new("".to_owned());
// raw_headers is for headers we don't know the proper type of (e.g. custom api key
// headers); headers is for ones we do know the type of.
let mut raw_headers = HashMap::new();
let mut headers: hyper::header::Headers = hyper::header::Headers::new();
let mut path = self.path;
for (k, v) in self.path_params {
// replace {id} with the value of the id path param
path = path.replace(&format!("{{{}}}", k), &v);
}
for (k, v) in self.header_params {
raw_headers.insert(k, v);
}
for (key, val) in self.query_params {
query_string.append_pair(&key, &val);
}
match self.auth {
Auth::ApiKey(apikey) => {
if let Some(ref key) = conf.api_key {
let val = apikey.key(&key.prefix, &key.key);
if apikey.in_query {
query_string.append_pair(&apikey.param_name, &val);
}
if apikey.in_header {
raw_headers.insert(apikey.param_name, val);
}
}
}
Auth::Basic => {
if let Some(ref auth_conf) = conf.basic_auth {
let auth = hyper::header::Authorization(hyper::header::Basic {
username: auth_conf.0.to_owned(),
password: auth_conf.1.to_owned(),
});
headers.set(auth);
}
}
Auth::Oauth => {
if let Some(ref token) = conf.oauth_access_token {
let auth = hyper::header::Authorization(hyper::header::Bearer {
token: token.to_owned(),
});
headers.set(auth);
}
}
Auth::None => {}
}
let mut uri_str = format!("{}{}", conf.base_path, path);
let query_string_str = query_string.finish();
if query_string_str != "" {
uri_str += "?";
uri_str += &query_string_str;
}
let uri: hyper::Uri = match uri_str.parse() {
Err(e) => {
return Box::new(futures::future::err(Error::UriError(e)));
}
Ok(u) => u,
};
let mut req = hyper::Request::new(self.method, uri);
{
let req_headers = req.headers_mut();
if let Some(ref user_agent) = conf.user_agent {
req_headers.set(UserAgent::new(Cow::Owned(user_agent.clone())));
}
req_headers.extend(headers.iter());
for (key, val) in raw_headers {
req_headers.set_raw(key, val);
}
}
if self.form_params.len() > 0 {
req.headers_mut().set(hyper::header::ContentType::form_url_encoded());
let mut enc = ::url::form_urlencoded::Serializer::new("".to_owned());
for (k, v) in self.form_params {
enc.append_pair(&k, &v);
}
req.set_body(enc.finish());
}
if let Some(body) = self.serialized_body {
req.headers_mut().set(hyper::header::ContentType::json());
req.headers_mut()
.set(hyper::header::ContentLength(body.len() as u64));
req.set_body(body);
}
let no_ret_type = self.no_return_type;
let res = conf.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)))
}
});
Box::new(
res
.and_then(move |body| {
let parsed: Result<U, _> = if no_ret_type {
// This is a hack; if there's no_ret_type, U is (), but serde_json gives an
// error when deserializing "" into (), so deserialize 'null' into it
// instead.
// An alternate option would be to require U: Default, and then return
// U::default() here instead since () implements that, but then we'd
// need to impl default for all models.
serde_json::from_str("null")
} else {
serde_json::from_slice(&body)
};
parsed.map_err(|e| Error::from(e))
})
)
}
}

View File

@ -0,0 +1,11 @@
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate url;
extern crate hyper;
extern crate futures;
pub mod apis;
pub mod models;

View File

@ -0,0 +1,3 @@
/target/
**/*.rs.bk
Cargo.lock

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1 @@
4.1.0-SNAPSHOT

View File

@ -0,0 +1 @@
language: rust

View File

@ -0,0 +1,17 @@
[package]
name = "rust-test-hyper"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]
[dependencies]
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
url = "1.5"
hyper = "~0.11"
serde_yaml = "0.7"
base64 = "~0.7.0"
futures = "0.1.23"
[dev-dependencies]
tokio-core = "*"

View File

@ -0,0 +1,44 @@
# Rust API client for rust-test-hyper
Special testing for the Rust client generator
## Overview
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
- API version: 1.0.7
- Package version: 1.0.0
- Build package: org.openapitools.codegen.languages.RustClientCodegen
## Installation
Put the package under your project folder and add the following to `Cargo.toml` under `[dependencies]`:
```
openapi = { path = "./generated" }
```
## Documentation for API Endpoints
All URIs are relative to *http://localhost*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*DefaultApi* | [**dummy_get**](docs/DefaultApi.md#dummy_get) | **Get** /dummy | A dummy endpoint to make the spec valid.
## Documentation For Models
- [TypeTesting](docs/TypeTesting.md)
To get access to the crate's generated documentation, use:
```
cargo doc --open
```
## Author

View File

@ -0,0 +1,34 @@
# \DefaultApi
All URIs are relative to *http://localhost*
Method | HTTP request | Description
------------- | ------------- | -------------
[**dummy_get**](DefaultApi.md#dummy_get) | **Get** /dummy | A dummy endpoint to make the spec valid.
## dummy_get
> dummy_get()
A dummy endpoint to make the spec valid.
### Parameters
This endpoint does not need any parameter.
### Return type
(empty response body)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: Not defined
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

View File

@ -0,0 +1,16 @@
# TypeTesting
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**integer** | **i32** | | [optional]
**long** | **i64** | | [optional]
**number** | **f32** | | [optional]
**float** | **f32** | | [optional]
**double** | **f64** | | [optional]
**uuid** | **String** | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="GIT_USER_ID"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="GIT_REPO_ID"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="Minor update"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,23 @@
use std::rc::Rc;
use hyper;
use super::configuration::Configuration;
pub struct APIClient {
default_api: Box<crate::apis::DefaultApi>,
}
impl APIClient {
pub fn new<C: hyper::client::Connect>(configuration: Configuration<C>) -> APIClient {
let rc = Rc::new(configuration);
APIClient {
default_api: Box::new(crate::apis::DefaultApiClient::new(rc.clone())),
}
}
pub fn default_api(&self) -> &crate::apis::DefaultApi{
self.default_api.as_ref()
}
}

View File

@ -0,0 +1,41 @@
/*
* Rust client test spec
*
* Special testing for the Rust client generator
*
* The version of the OpenAPI document: 1.0.7
*
* Generated by: https://openapi-generator.tech
*/
use hyper;
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> {
pub fn new(client: hyper::client::Client<C>) -> Configuration<C> {
Configuration {
base_path: "http://localhost".to_owned(),
user_agent: Some("OpenAPI-Generator/1.0.7/rust".to_owned()),
client: client,
basic_auth: None,
oauth_access_token: None,
api_key: None,
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Rust client test spec
*
* Special testing for the Rust client generator
*
* The version of the OpenAPI document: 1.0.7
*
* Generated by: https://openapi-generator.tech
*/
use std::rc::Rc;
use std::borrow::Borrow;
use hyper;
use serde_json;
use futures::Future;
use super::{Error, configuration};
use super::request as __internal_request;
pub struct DefaultApiClient<C: hyper::client::Connect> {
configuration: Rc<configuration::Configuration<C>>,
}
impl<C: hyper::client::Connect> DefaultApiClient<C> {
pub fn new(configuration: Rc<configuration::Configuration<C>>) -> DefaultApiClient<C> {
DefaultApiClient {
configuration: configuration,
}
}
}
pub trait DefaultApi {
fn dummy_get(&self, ) -> Box<Future<Item = (), Error = Error<serde_json::Value>>>;
}
impl<C: hyper::client::Connect>DefaultApi for DefaultApiClient<C> {
fn dummy_get(&self, ) -> Box<Future<Item = (), Error = Error<serde_json::Value>>> {
__internal_request::Request::new(hyper::Method::Get, "/dummy".to_string())
.returns_nothing()
.execute(self.configuration.borrow())
}
}

View File

@ -0,0 +1,58 @@
use hyper;
use serde;
use serde_json;
#[derive(Debug)]
pub enum Error<T> {
UriError(hyper::error::UriError),
Hyper(hyper::Error),
Serde(serde_json::Error),
ApiError(ApiError<T>),
}
#[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<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
return Error::Serde(e)
}
}
mod request;
mod default_api;
pub use self::default_api::{ DefaultApi, DefaultApiClient };
pub mod configuration;
pub mod client;

View File

@ -0,0 +1,239 @@
use std::borrow::Cow;
use std::collections::HashMap;
use super::{configuration, Error};
use futures;
use futures::{Future, Stream};
use hyper;
use hyper::header::UserAgent;
use serde;
use serde_json;
pub(crate) struct ApiKey {
pub in_header: bool,
pub in_query: bool,
pub param_name: String,
}
impl ApiKey {
fn key(&self, prefix: &Option<String>, key: &str) -> String {
match prefix {
None => key.to_owned(),
Some(ref prefix) => format!("{} {}", prefix, key),
}
}
}
#[allow(dead_code)]
pub(crate) enum Auth {
None,
ApiKey(ApiKey),
Basic,
Oauth,
}
pub(crate) struct Request {
auth: Auth,
method: hyper::Method,
path: String,
query_params: HashMap<String, String>,
no_return_type: bool,
path_params: HashMap<String, String>,
form_params: HashMap<String, String>,
header_params: HashMap<String, String>,
// TODO: multiple body params are possible technically, but not supported here.
serialized_body: Option<String>,
}
impl Request {
pub fn new(method: hyper::Method, path: String) -> Self {
Request {
auth: Auth::None,
method: method,
path: path,
query_params: HashMap::new(),
path_params: HashMap::new(),
form_params: HashMap::new(),
header_params: HashMap::new(),
serialized_body: None,
no_return_type: false,
}
}
pub fn with_body_param<T: serde::Serialize>(mut self, param: T) -> Self {
self.serialized_body = Some(serde_json::to_string(&param).unwrap());
self
}
pub fn with_header_param(mut self, basename: String, param: String) -> Self {
self.header_params.insert(basename, param);
self
}
pub fn with_query_param(mut self, basename: String, param: String) -> Self {
self.query_params.insert(basename, param);
self
}
pub fn with_path_param(mut self, basename: String, param: String) -> Self {
self.path_params.insert(basename, param);
self
}
pub fn with_form_param(mut self, basename: String, param: String) -> Self {
self.form_params.insert(basename, param);
self
}
pub fn returns_nothing(mut self) -> Self {
self.no_return_type = true;
self
}
pub fn with_auth(mut self, auth: Auth) -> Self {
self.auth = auth;
self
}
pub fn execute<'a, C, U>(
self,
conf: &configuration::Configuration<C>,
) -> Box<Future<Item = U, Error = Error<serde_json::Value>> + 'a>
where
C: hyper::client::Connect,
U: Sized + 'a,
for<'de> U: serde::Deserialize<'de>,
{
let mut query_string = ::url::form_urlencoded::Serializer::new("".to_owned());
// raw_headers is for headers we don't know the proper type of (e.g. custom api key
// headers); headers is for ones we do know the type of.
let mut raw_headers = HashMap::new();
let mut headers: hyper::header::Headers = hyper::header::Headers::new();
let mut path = self.path;
for (k, v) in self.path_params {
// replace {id} with the value of the id path param
path = path.replace(&format!("{{{}}}", k), &v);
}
for (k, v) in self.header_params {
raw_headers.insert(k, v);
}
for (key, val) in self.query_params {
query_string.append_pair(&key, &val);
}
match self.auth {
Auth::ApiKey(apikey) => {
if let Some(ref key) = conf.api_key {
let val = apikey.key(&key.prefix, &key.key);
if apikey.in_query {
query_string.append_pair(&apikey.param_name, &val);
}
if apikey.in_header {
raw_headers.insert(apikey.param_name, val);
}
}
}
Auth::Basic => {
if let Some(ref auth_conf) = conf.basic_auth {
let auth = hyper::header::Authorization(hyper::header::Basic {
username: auth_conf.0.to_owned(),
password: auth_conf.1.to_owned(),
});
headers.set(auth);
}
}
Auth::Oauth => {
if let Some(ref token) = conf.oauth_access_token {
let auth = hyper::header::Authorization(hyper::header::Bearer {
token: token.to_owned(),
});
headers.set(auth);
}
}
Auth::None => {}
}
let mut uri_str = format!("{}{}", conf.base_path, path);
let query_string_str = query_string.finish();
if query_string_str != "" {
uri_str += "?";
uri_str += &query_string_str;
}
let uri: hyper::Uri = match uri_str.parse() {
Err(e) => {
return Box::new(futures::future::err(Error::UriError(e)));
}
Ok(u) => u,
};
let mut req = hyper::Request::new(self.method, uri);
{
let req_headers = req.headers_mut();
if let Some(ref user_agent) = conf.user_agent {
req_headers.set(UserAgent::new(Cow::Owned(user_agent.clone())));
}
req_headers.extend(headers.iter());
for (key, val) in raw_headers {
req_headers.set_raw(key, val);
}
}
if self.form_params.len() > 0 {
req.headers_mut().set(hyper::header::ContentType::form_url_encoded());
let mut enc = ::url::form_urlencoded::Serializer::new("".to_owned());
for (k, v) in self.form_params {
enc.append_pair(&k, &v);
}
req.set_body(enc.finish());
}
if let Some(body) = self.serialized_body {
req.headers_mut().set(hyper::header::ContentType::json());
req.headers_mut()
.set(hyper::header::ContentLength(body.len() as u64));
req.set_body(body);
}
let no_ret_type = self.no_return_type;
let res = conf.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)))
}
});
Box::new(
res
.and_then(move |body| {
let parsed: Result<U, _> = if no_ret_type {
// This is a hack; if there's no_ret_type, U is (), but serde_json gives an
// error when deserializing "" into (), so deserialize 'null' into it
// instead.
// An alternate option would be to require U: Default, and then return
// U::default() here instead since () implements that, but then we'd
// need to impl default for all models.
serde_json::from_str("null")
} else {
serde_json::from_slice(&body)
};
parsed.map_err(|e| Error::from(e))
})
)
}
}

View File

@ -0,0 +1,11 @@
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate url;
extern crate hyper;
extern crate futures;
pub mod apis;
pub mod models;

View File

@ -0,0 +1,2 @@
mod type_testing;
pub use self::type_testing::TypeTesting;

View File

@ -0,0 +1,44 @@
/*
* Rust client test spec
*
* Special testing for the Rust client generator
*
* The version of the OpenAPI document: 1.0.7
*
* Generated by: https://openapi-generator.tech
*/
/// TypeTesting : Test handling of differing types (see \\#3463)
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct TypeTesting {
#[serde(rename = "integer", skip_serializing_if = "Option::is_none")]
pub integer: Option<i32>,
#[serde(rename = "long", skip_serializing_if = "Option::is_none")]
pub long: Option<i64>,
#[serde(rename = "number", skip_serializing_if = "Option::is_none")]
pub number: Option<f32>,
#[serde(rename = "float", skip_serializing_if = "Option::is_none")]
pub float: Option<f32>,
#[serde(rename = "double", skip_serializing_if = "Option::is_none")]
pub double: Option<f64>,
#[serde(rename = "uuid", skip_serializing_if = "Option::is_none")]
pub uuid: Option<String>,
}
impl TypeTesting {
/// Test handling of differing types (see \\#3463)
pub fn new() -> TypeTesting {
TypeTesting {
integer: None,
long: None,
number: None,
float: None,
double: None,
uuid: None,
}
}
}

View File

@ -0,0 +1,3 @@
/target/
**/*.rs.bk
Cargo.lock

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1 @@
4.1.0-SNAPSHOT

View File

@ -0,0 +1 @@
language: rust

View File

@ -0,0 +1,13 @@
[package]
name = "fileResponseTest-reqwest"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]
[dependencies]
serde = "^1.0"
serde_derive = "^1.0"
serde_json = "^1.0"
url = "1.5"
reqwest = "~0.9"
[dev-dependencies]

View File

@ -0,0 +1,43 @@
# Rust API client for fileResponseTest-reqwest
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
## Overview
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
- API version: 1.0.0
- Package version: 1.0.0
- Build package: org.openapitools.codegen.languages.RustClientCodegen
## Installation
Put the package under your project folder and add the following to `Cargo.toml` under `[dependencies]`:
```
openapi = { path = "./generated" }
```
## Documentation for API Endpoints
All URIs are relative to *http://localhost/v2*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
*DefaultApi* | [**fileresponsetest**](docs/DefaultApi.md#fileresponsetest) | **get** /tests/fileResponse |
## Documentation For Models
To get access to the crate's generated documentation, use:
```
cargo doc --open
```
## Author

View File

@ -0,0 +1,34 @@
# \DefaultApi
All URIs are relative to *http://localhost/v2*
Method | HTTP request | Description
------------- | ------------- | -------------
[**fileresponsetest**](DefaultApi.md#fileresponsetest) | **get** /tests/fileResponse |
## fileresponsetest
> std::path::PathBuf fileresponsetest()
### Parameters
This endpoint does not need any parameter.
### Return type
[**std::path::PathBuf**](std::path::PathBuf.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: Not defined
- **Accept**: application/octet-stream
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

View File

@ -0,0 +1,52 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="GIT_USER_ID"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="GIT_REPO_ID"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="Minor update"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=`git remote`
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@ -0,0 +1,22 @@
use std::rc::Rc;
use super::configuration::Configuration;
pub struct APIClient {
default_api: Box<crate::apis::DefaultApi>,
}
impl APIClient {
pub fn new(configuration: Configuration) -> APIClient {
let rc = Rc::new(configuration);
APIClient {
default_api: Box::new(crate::apis::DefaultApiClient::new(rc.clone())),
}
}
pub fn default_api(&self) -> &crate::apis::DefaultApi{
self.default_api.as_ref()
}
}

View File

@ -0,0 +1,50 @@
/*
* File Response Test
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
use reqwest;
pub struct Configuration {
pub base_path: String,
pub user_agent: Option<String>,
pub client: reqwest::Client,
pub basic_auth: Option<BasicAuth>,
pub oauth_access_token: Option<String>,
pub bearer_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 Configuration {
pub fn new() -> Configuration {
Configuration::default()
}
}
impl Default for Configuration {
fn default() -> Self {
Configuration {
base_path: "http://localhost/v2".to_owned(),
user_agent: Some("OpenAPI-Generator/1.0.0/rust".to_owned()),
client: reqwest::Client::new(),
basic_auth: None,
oauth_access_token: None,
bearer_access_token: None,
api_key: None,
}
}
}

View File

@ -0,0 +1,52 @@
/*
* File Response Test
*
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
* Generated by: https://openapi-generator.tech
*/
use std::rc::Rc;
use std::borrow::Borrow;
use reqwest;
use super::{Error, configuration};
pub struct DefaultApiClient {
configuration: Rc<configuration::Configuration>,
}
impl DefaultApiClient {
pub fn new(configuration: Rc<configuration::Configuration>) -> DefaultApiClient {
DefaultApiClient {
configuration: configuration,
}
}
}
pub trait DefaultApi {
fn fileresponsetest(&self, ) -> Result<std::path::PathBuf, Error>;
}
impl DefaultApi for DefaultApiClient {
fn fileresponsetest(&self, ) -> Result<std::path::PathBuf, Error> {
let configuration: &configuration::Configuration = self.configuration.borrow();
let client = &configuration.client;
let uri_str = format!("{}/tests/fileResponse", configuration.base_path);
let mut req_builder = client.get(uri_str.as_str());
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
// send request
let req = req_builder.build()?;
Ok(client.execute(req)?.error_for_status()?.json()?)
}
}

View File

@ -0,0 +1,37 @@
use reqwest;
use serde_json;
#[derive(Debug)]
pub enum Error {
Reqwest(reqwest::Error),
Serde(serde_json::Error),
Io(std::io::Error),
}
impl From<reqwest::Error> for Error {
fn from(e: reqwest::Error) -> Self {
Error::Reqwest(e)
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Error::Serde(e)
}
}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}
pub fn urlencode<T: AsRef<str>>(s: T) -> String {
::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
}
mod default_api;
pub use self::default_api::{ DefaultApi, DefaultApiClient };
pub mod configuration;
pub mod client;

View File

@ -0,0 +1,3 @@
/target/
**/*.rs.bk
Cargo.lock

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1 @@
language: rust

View File

@ -1,5 +1,5 @@
[package]
name = "petstore_client"
name = "petstore-reqwest"
version = "1.0.0"
authors = ["OpenAPI Generator team and contributors"]

View File

@ -1,4 +1,4 @@
# Rust API client for petstore_client
# Rust API client for petstore-reqwest
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.

Some files were not shown because too many files have changed in this diff Show More