mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-07-04 06:30:52 +00:00
[Rust Server] Frunk - LabelledGeneric - support (#3552)
Derive the LabelledGeneric trait on Swagger models. This allows conversion between structurally similar types by using https://docs.rs/frunk/0.2.2/frunk/#transmogrifying. Exit if example fails to run
This commit is contained in:
parent
aa4ead2a6d
commit
44fda895d2
@ -38,4 +38,8 @@ for spec_path in modules/openapi-generator/src/test/resources/*/rust-server/* ;
|
|||||||
$@"
|
$@"
|
||||||
|
|
||||||
java $JAVA_OPTS -jar $executable $args
|
java $JAVA_OPTS -jar $executable $args
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
@ -615,10 +615,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (CodegenParameter param : op.headerParams) {
|
for (CodegenParameter param : op.headerParams) {
|
||||||
// If a header uses UUIDs, we need to import the UUID package.
|
|
||||||
if (param.dataType.equals(uuidType)) {
|
|
||||||
additionalProperties.put("apiUsesUuid", true);
|
|
||||||
}
|
|
||||||
processParam(param, op);
|
processParam(param, op);
|
||||||
|
|
||||||
// Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property.
|
// Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property.
|
||||||
@ -925,7 +921,15 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
|||||||
String modelName = entry.getKey();
|
String modelName = entry.getKey();
|
||||||
CodegenModel model = entry.getValue();
|
CodegenModel model = entry.getValue();
|
||||||
|
|
||||||
|
if (uuidType.equals(model.dataType)) {
|
||||||
|
additionalProperties.put("apiUsesUuid", true);
|
||||||
|
}
|
||||||
|
|
||||||
for (CodegenProperty prop : model.vars) {
|
for (CodegenProperty prop : model.vars) {
|
||||||
|
if (prop.dataType.equals(uuidType)) {
|
||||||
|
additionalProperties.put("apiUsesUuid", true);
|
||||||
|
}
|
||||||
|
|
||||||
String xmlName = modelXmlNames.get(prop.dataType);
|
String xmlName = modelXmlNames.get(prop.dataType);
|
||||||
if (xmlName != null) {
|
if (xmlName != null) {
|
||||||
prop.vendorExtensions.put("itemXmlName", xmlName);
|
prop.vendorExtensions.put("itemXmlName", xmlName);
|
||||||
@ -1132,6 +1136,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 a parameter uses UUIDs, we need to import the UUID package.
|
||||||
|
if (param.dataType.equals(uuidType)) {
|
||||||
|
additionalProperties.put("apiUsesUuid", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (param.isString) {
|
if (param.isString) {
|
||||||
param.vendorExtensions.put("formatString", "\\\"{}\\\"");
|
param.vendorExtensions.put("formatString", "\\\"{}\\\"");
|
||||||
example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
|
example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()";
|
||||||
|
@ -9,42 +9,69 @@ 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"]
|
client = [{{#usesUrlEncodedForm}}"serde_urlencoded", {{/usesUrlEncodedForm}}"serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
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"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
{{#apiUsesUuid}}
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
{{#usesXml}}
|
||||||
|
# TODO: this should be updated to point at the official crate once
|
||||||
|
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
||||||
|
serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master"}
|
||||||
|
{{/usesXml}}
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
{{#usesUrlEncodedForm}}serde_urlencoded = {version = "0.5.1", optional = true}{{/usesUrlEncodedForm}}
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
# Other optional crates
|
||||||
# ToDo: this should be updated to point at the official crate once
|
frunk = { version = "0.3.0", optional = true }
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
{{#usesXml}}serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master", optional = true}{{/usesXml}}
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
{{^apiUsesUuid}}
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -5,22 +5,20 @@
|
|||||||
{{/appDescription}}
|
{{/appDescription}}
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
[README]((https://openapi-generator.tech))
|
[README]((https://openapi-generator.tech))
|
||||||
|
|
||||||
- API version: {{{appVersion}}}
|
- API version: {{{appVersion}}}
|
||||||
{{^hideGenerationTimestamp}}
|
{{^hideGenerationTimestamp}}- Build date: {{{generatedDate}}}{{/hideGenerationTimestamp}}
|
||||||
- Build date: {{{generatedDate}}}
|
|
||||||
{{/hideGenerationTimestamp}}
|
{{#infoUrl}}For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}){{/infoUrl}}
|
||||||
{{#infoUrl}}
|
|
||||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
|
||||||
{{/infoUrl}}
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `{{{packageName}}}` which contains:
|
This autogenerated project defines an API crate `{{{packageName}}}` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
@ -29,15 +27,17 @@ This autogenerated project defines an API crate `{{{packageName}}}` which contai
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `{{{packageName}}}`:
|
It also contains an example server and client which make use of `{{{packageName}}}`:
|
||||||
* The example server starts up a web server using the `{{{packageName}}}` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `{{{packageName}}}`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`{{{packageName}}}` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `{{{packageName}}}` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -52,14 +52,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
```{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||||
@ -73,43 +73,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `{{{packageName}}}` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "{{{packageName}}}" ]`.
|
|
||||||
* Add `{{{packageName}}} = {version = "{{{appVersion}}}", path = "{{{packageName}}}"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `{{{packageName}}}/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp {{{packageName}}}/examples/server.rs src/main.rs
|
|
||||||
cp {{{packageName}}}/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp {{{packageName}}}/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -12,10 +12,10 @@ extern crate serde_urlencoded;
|
|||||||
{{#apiUsesMultipart}}
|
{{#apiUsesMultipart}}
|
||||||
extern crate multipart;
|
extern crate multipart;
|
||||||
{{/apiUsesMultipart}}
|
{{/apiUsesMultipart}}
|
||||||
|
|
||||||
{{#apiUsesUuid}}
|
{{#apiUsesUuid}}
|
||||||
use uuid;
|
extern crate uuid;
|
||||||
{{/apiUsesUuid}}
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::header::{Headers, ContentType};
|
use hyper::header::{Headers, ContentType};
|
||||||
use hyper::Uri;
|
use hyper::Uri;
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@ extern crate futures;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
{{#apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}}
|
{{#apiUsesUuid}}
|
||||||
|
extern crate uuid;
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
|
@ -6,9 +6,11 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
{{#apiUsesUuid}}
|
||||||
|
use uuid;
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
use {{{externCrateName}}}::{Api, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
use {{{externCrateName}}}::{Api, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||||
|
@ -1,40 +1,53 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
{{#apiUsesUuid}}extern crate uuid;{{/apiUsesUuid}}
|
|
||||||
{{#usesXml}}extern crate serde_xml_rs;{{/usesXml}}
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
{{#usesXml}}extern crate serde_xml_rs;{{/usesXml}}
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
{{#apiUsesUuid}}
|
||||||
|
extern crate uuid;
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "{{{basePathWithoutHost}}}";
|
pub const BASE_PATH: &'static str = "{{{basePathWithoutHost}}}";
|
||||||
pub const API_VERSION: &'static str = "{{{appVersion}}}";
|
pub const API_VERSION: &'static str = "{{{appVersion}}}";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
{{#usesXml}}
|
{{#usesXml}}
|
||||||
use serde_xml_rs;
|
use serde_xml_rs;
|
||||||
@ -16,7 +15,9 @@ use std::collections::HashMap;
|
|||||||
use models;
|
use models;
|
||||||
use swagger;
|
use swagger;
|
||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
{{#apiUsesUuid}}
|
||||||
|
use uuid;
|
||||||
|
{{/apiUsesUuid}}
|
||||||
|
|
||||||
{{#models}}{{#model}}
|
{{#models}}{{#model}}
|
||||||
{{#description}}/// {{{description}}}
|
{{#description}}/// {{{description}}}
|
||||||
@ -25,7 +26,8 @@ use std::string::ParseError;
|
|||||||
/// which helps with FFI.
|
/// which helps with FFI.
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Eq, Ord)]{{#xmlName}}
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGenericEnum))]{{#xmlName}}
|
||||||
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||||
pub enum {{{classname}}} { {{#allowableValues}}{{#enumVars}}
|
pub enum {{{classname}}} { {{#allowableValues}}{{#enumVars}}
|
||||||
#[serde(rename = {{{value}}})]
|
#[serde(rename = {{{value}}})]
|
||||||
@ -50,6 +52,7 @@ impl ::std::str::FromStr for {{{classname}}} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{/isEnum}}{{^isEnum}}{{#dataType}}{{! newtype}}#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
{{/isEnum}}{{^isEnum}}{{#dataType}}{{! newtype}}#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
{{#xmlName}}#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
{{#xmlName}}#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||||
pub struct {{{classname}}}({{{dataType}}});
|
pub struct {{{classname}}}({{{dataType}}});
|
||||||
|
|
||||||
@ -97,6 +100,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{/itemXmlName}}{{/vendorExtensions}}{{! vec}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
{{/itemXmlName}}{{/vendorExtensions}}{{! vec}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct {{{classname}}}({{#vendorExtensions}}{{#itemXmlName}}#[serde(serialize_with = "wrap_in_{{{itemXmlName}}}")]{{/itemXmlName}}{{/vendorExtensions}}Vec<{{{arrayModelType}}}>);
|
pub struct {{{classname}}}({{#vendorExtensions}}{{#itemXmlName}}#[serde(serialize_with = "wrap_in_{{{itemXmlName}}}")]{{/itemXmlName}}{{/vendorExtensions}}Vec<{{{arrayModelType}}}>);
|
||||||
|
|
||||||
impl ::std::convert::From<Vec<{{{arrayModelType}}}>> for {{{classname}}} {
|
impl ::std::convert::From<Vec<{{{arrayModelType}}}>> for {{{classname}}} {
|
||||||
@ -157,7 +161,8 @@ impl ::std::ops::DerefMut for {{{classname}}} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{/arrayModelType}}{{^arrayModelType}}{{! general struct}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]{{#xmlName}}
|
{{/arrayModelType}}{{^arrayModelType}}{{! general struct}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]{{#xmlName}}
|
||||||
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||||
pub struct {{{classname}}} {
|
pub struct {{{classname}}} {
|
||||||
{{#vars}}{{#description}} /// {{{description}}}
|
{{#vars}}{{#description}} /// {{{description}}}
|
||||||
|
@ -8,7 +8,7 @@ extern crate mime;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate percent_encoding;
|
extern crate percent_encoding;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
{{^apiUsesUuid}}
|
{{#apiUsesUuid}}
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
{{/apiUsesUuid}}
|
{{/apiUsesUuid}}
|
||||||
{{#apiUsesMultipart}}
|
{{#apiUsesMultipart}}
|
||||||
@ -32,9 +32,6 @@ use serde_json;
|
|||||||
{{#usesXml}}
|
{{#usesXml}}
|
||||||
use serde_xml_rs;
|
use serde_xml_rs;
|
||||||
{{/usesXml}}
|
{{/usesXml}}
|
||||||
{{#apiUsesUuid}}
|
|
||||||
use uuid;
|
|
||||||
{{/apiUsesUuid}}
|
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::{HashMap, BTreeMap};
|
use std::collections::{HashMap, BTreeMap};
|
||||||
|
@ -7,42 +7,59 @@ license = "Unlicense"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["client", "server"]
|
default = ["client", "server"]
|
||||||
client = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
|
client = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
server = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
|
||||||
# ToDo: this should be updated to point at the official crate once
|
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
|
||||||
|
|
||||||
|
# Other optional crates
|
||||||
|
frunk = { version = "0.3.0", optional = true }
|
||||||
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
API under test
|
API under test
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ To see how to make this your own, look here:
|
|||||||
|
|
||||||
- API version: 1.0.7
|
- API version: 1.0.7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `multipart-v3` which contains:
|
This autogenerated project defines an API crate `multipart-v3` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
* Data types representing the underlying data model.
|
* Data types representing the underlying data model.
|
||||||
@ -21,15 +25,17 @@ This autogenerated project defines an API crate `multipart-v3` which contains:
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `multipart-v3`:
|
It also contains an example server and client which make use of `multipart-v3`:
|
||||||
* The example server starts up a web server using the `multipart-v3` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `multipart-v3`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`multipart-v3` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `multipart-v3` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -44,14 +50,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -65,43 +71,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `multipart-v3` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "multipart-v3" ]`.
|
|
||||||
* Add `multipart-v3 = {version = "1.0.7", path = "multipart-v3"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `multipart-v3/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp multipart-v3/examples/server.rs src/main.rs
|
|
||||||
cp multipart-v3/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp multipart-v3/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ extern crate chrono;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
use openssl::error::ErrorStack;
|
use openssl::error::ErrorStack;
|
||||||
|
@ -6,7 +6,6 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
|
||||||
|
@ -1,40 +1,50 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "";
|
pub const BASE_PATH: &'static str = "";
|
||||||
pub const API_VERSION: &'static str = "1.0.7";
|
pub const API_VERSION: &'static str = "1.0.7";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
|
|
||||||
@ -10,8 +9,8 @@ use swagger;
|
|||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct MultipartRequest {
|
pub struct MultipartRequest {
|
||||||
#[serde(rename = "string_field")]
|
#[serde(rename = "string_field")]
|
||||||
pub string_field: String,
|
pub string_field: String,
|
||||||
@ -42,6 +41,7 @@ impl MultipartRequest {
|
|||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct MultipartRequestObjectField {
|
pub struct MultipartRequestObjectField {
|
||||||
#[serde(rename = "field_a")]
|
#[serde(rename = "field_a")]
|
||||||
pub field_a: String,
|
pub field_a: String,
|
||||||
|
@ -8,7 +8,6 @@ extern crate mime;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate percent_encoding;
|
extern crate percent_encoding;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
|
||||||
extern crate multipart;
|
extern crate multipart;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -7,42 +7,62 @@ license = "Unlicense"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["client", "server"]
|
default = ["client", "server"]
|
||||||
client = ["serde_json", "serde-xml-rs", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
|
client = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
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"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
# TODO: this should be updated to point at the official crate once
|
||||||
|
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
||||||
|
serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master"}
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
# Other optional crates
|
||||||
# ToDo: this should be updated to point at the official crate once
|
frunk = { version = "0.3.0", optional = true }
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master", optional = true}
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
API under test
|
API under test
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ To see how to make this your own, look here:
|
|||||||
|
|
||||||
- API version: 1.0.7
|
- API version: 1.0.7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `openapi-v3` which contains:
|
This autogenerated project defines an API crate `openapi-v3` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
* Data types representing the underlying data model.
|
* Data types representing the underlying data model.
|
||||||
@ -21,15 +25,17 @@ This autogenerated project defines an API crate `openapi-v3` which contains:
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `openapi-v3`:
|
It also contains an example server and client which make use of `openapi-v3`:
|
||||||
* The example server starts up a web server using the `openapi-v3` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `openapi-v3`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`openapi-v3` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `openapi-v3` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -44,14 +50,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -71,43 +77,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `openapi-v3` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "openapi-v3" ]`.
|
|
||||||
* Add `openapi-v3 = {version = "1.0.7", path = "openapi-v3"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `openapi-v3/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp openapi-v3/examples/server.rs src/main.rs
|
|
||||||
cp openapi-v3/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp openapi-v3/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ extern crate futures;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
|
@ -6,9 +6,9 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
use uuid;
|
||||||
|
|
||||||
use openapi_v3::{Api, ApiError,
|
use openapi_v3::{Api, ApiError,
|
||||||
RequiredOctetStreamPutResponse,
|
RequiredOctetStreamPutResponse,
|
||||||
|
@ -6,6 +6,7 @@ extern crate openssl;
|
|||||||
extern crate mime;
|
extern crate mime;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::header::{Headers, ContentType};
|
use hyper::header::{Headers, ContentType};
|
||||||
|
@ -1,40 +1,51 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
extern crate serde_xml_rs;
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
extern crate serde_xml_rs;
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "";
|
pub const BASE_PATH: &'static str = "";
|
||||||
pub const API_VERSION: &'static str = "1.0.7";
|
pub const API_VERSION: &'static str = "1.0.7";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use serde_xml_rs;
|
use serde_xml_rs;
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
@ -9,7 +8,7 @@ use std::collections::{HashMap, BTreeMap};
|
|||||||
use models;
|
use models;
|
||||||
use swagger;
|
use swagger;
|
||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
use uuid;
|
||||||
|
|
||||||
|
|
||||||
// Utility function for wrapping list elements when serializing xml
|
// Utility function for wrapping list elements when serializing xml
|
||||||
@ -22,6 +21,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct AnotherXmlArray(#[serde(serialize_with = "wrap_in_snake_another_xml_inner")]Vec<String>);
|
pub struct AnotherXmlArray(#[serde(serialize_with = "wrap_in_snake_another_xml_inner")]Vec<String>);
|
||||||
|
|
||||||
impl ::std::convert::From<Vec<String>> for AnotherXmlArray {
|
impl ::std::convert::From<Vec<String>> for AnotherXmlArray {
|
||||||
@ -93,6 +93,7 @@ impl AnotherXmlArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "snake_another_xml_inner")]
|
#[serde(rename = "snake_another_xml_inner")]
|
||||||
pub struct AnotherXmlInner(String);
|
pub struct AnotherXmlInner(String);
|
||||||
|
|
||||||
@ -140,6 +141,7 @@ impl AnotherXmlInner {
|
|||||||
|
|
||||||
/// An XML object
|
/// An XML object
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "snake_another_xml_object")]
|
#[serde(rename = "snake_another_xml_object")]
|
||||||
pub struct AnotherXmlObject {
|
pub struct AnotherXmlObject {
|
||||||
#[serde(rename = "inner_string")]
|
#[serde(rename = "inner_string")]
|
||||||
@ -176,6 +178,7 @@ impl AnotherXmlObject {
|
|||||||
|
|
||||||
/// An XML object
|
/// An XML object
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "camelDuplicateXmlObject")]
|
#[serde(rename = "camelDuplicateXmlObject")]
|
||||||
pub struct DuplicateXmlObject {
|
pub struct DuplicateXmlObject {
|
||||||
#[serde(rename = "inner_string")]
|
#[serde(rename = "inner_string")]
|
||||||
@ -217,6 +220,7 @@ impl DuplicateXmlObject {
|
|||||||
|
|
||||||
/// Test a model containing a UUID
|
/// Test a model containing a UUID
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
|
|
||||||
pub struct UuidObject(uuid::Uuid);
|
pub struct UuidObject(uuid::Uuid);
|
||||||
|
|
||||||
@ -266,6 +270,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct XmlArray(#[serde(serialize_with = "wrap_in_camelXmlInner")]Vec<String>);
|
pub struct XmlArray(#[serde(serialize_with = "wrap_in_camelXmlInner")]Vec<String>);
|
||||||
|
|
||||||
impl ::std::convert::From<Vec<String>> for XmlArray {
|
impl ::std::convert::From<Vec<String>> for XmlArray {
|
||||||
@ -337,6 +342,7 @@ impl XmlArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "camelXmlInner")]
|
#[serde(rename = "camelXmlInner")]
|
||||||
pub struct XmlInner(String);
|
pub struct XmlInner(String);
|
||||||
|
|
||||||
@ -384,6 +390,7 @@ impl XmlInner {
|
|||||||
|
|
||||||
/// An XML object
|
/// An XML object
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "camelXmlObject")]
|
#[serde(rename = "camelXmlObject")]
|
||||||
pub struct XmlObject {
|
pub struct XmlObject {
|
||||||
#[serde(rename = "innerString")]
|
#[serde(rename = "innerString")]
|
||||||
|
@ -7,42 +7,59 @@ license = "Unlicense"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["client", "server"]
|
default = ["client", "server"]
|
||||||
client = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
|
client = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
server = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
|
||||||
# ToDo: this should be updated to point at the official crate once
|
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
|
||||||
|
|
||||||
|
# Other optional crates
|
||||||
|
frunk = { version = "0.3.0", optional = true }
|
||||||
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ To see how to make this your own, look here:
|
|||||||
|
|
||||||
- API version: 0.0.1
|
- API version: 0.0.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `ops-v3` which contains:
|
This autogenerated project defines an API crate `ops-v3` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
* Data types representing the underlying data model.
|
* Data types representing the underlying data model.
|
||||||
@ -21,15 +25,17 @@ This autogenerated project defines an API crate `ops-v3` which contains:
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `ops-v3`:
|
It also contains an example server and client which make use of `ops-v3`:
|
||||||
* The example server starts up a web server using the `ops-v3` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `ops-v3`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`ops-v3` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `ops-v3` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -44,14 +50,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -101,43 +107,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `ops-v3` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "ops-v3" ]`.
|
|
||||||
* Add `ops-v3 = {version = "0.0.1", path = "ops-v3"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `ops-v3/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp ops-v3/examples/server.rs src/main.rs
|
|
||||||
cp ops-v3/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp ops-v3/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ extern crate chrono;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
use openssl::error::ErrorStack;
|
use openssl::error::ErrorStack;
|
||||||
|
@ -6,7 +6,6 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
|
||||||
|
@ -1,40 +1,50 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "";
|
pub const BASE_PATH: &'static str = "";
|
||||||
pub const API_VERSION: &'static str = "0.0.1";
|
pub const API_VERSION: &'static str = "0.0.1";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
|
|
||||||
@ -9,4 +8,3 @@ use models;
|
|||||||
use swagger;
|
use swagger;
|
||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ extern crate mime;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate percent_encoding;
|
extern crate percent_encoding;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -7,42 +7,62 @@ 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"]
|
client = ["serde_urlencoded", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
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"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
# TODO: this should be updated to point at the official crate once
|
||||||
|
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
||||||
|
serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master"}
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
serde_urlencoded = {version = "0.5.1", optional = true}
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
# Other optional crates
|
||||||
# ToDo: this should be updated to point at the official crate once
|
frunk = { version = "0.3.0", optional = true }
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
serde-xml-rs = {git = "git://github.com/Metaswitch/serde-xml-rs.git" , branch = "master", optional = true}
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
|
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ To see how to make this your own, look here:
|
|||||||
|
|
||||||
- API version: 1.0.0
|
- API version: 1.0.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `petstore-with-fake-endpoints-models-for-testing` which contains:
|
This autogenerated project defines an API crate `petstore-with-fake-endpoints-models-for-testing` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
* Data types representing the underlying data model.
|
* Data types representing the underlying data model.
|
||||||
@ -21,15 +25,17 @@ This autogenerated project defines an API crate `petstore-with-fake-endpoints-mo
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `petstore-with-fake-endpoints-models-for-testing`:
|
It also contains an example server and client which make use of `petstore-with-fake-endpoints-models-for-testing`:
|
||||||
* The example server starts up a web server using the `petstore-with-fake-endpoints-models-for-testing` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `petstore-with-fake-endpoints-models-for-testing`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`petstore-with-fake-endpoints-models-for-testing` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `petstore-with-fake-endpoints-models-for-testing` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -44,14 +50,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -96,43 +102,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `petstore-with-fake-endpoints-models-for-testing` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "petstore-with-fake-endpoints-models-for-testing" ]`.
|
|
||||||
* Add `petstore-with-fake-endpoints-models-for-testing = {version = "1.0.0", path = "petstore-with-fake-endpoints-models-for-testing"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `petstore-with-fake-endpoints-models-for-testing/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp petstore-with-fake-endpoints-models-for-testing/examples/server.rs src/main.rs
|
|
||||||
cp petstore-with-fake-endpoints-models-for-testing/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp petstore-with-fake-endpoints-models-for-testing/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ extern crate futures;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
|
@ -6,9 +6,9 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
use uuid;
|
||||||
|
|
||||||
use petstore_with_fake_endpoints_models_for_testing::{Api, ApiError,
|
use petstore_with_fake_endpoints_models_for_testing::{Api, ApiError,
|
||||||
TestSpecialTagsResponse,
|
TestSpecialTagsResponse,
|
||||||
|
@ -8,6 +8,7 @@ extern crate chrono;
|
|||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate serde_urlencoded;
|
extern crate serde_urlencoded;
|
||||||
extern crate multipart;
|
extern crate multipart;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use hyper;
|
use hyper;
|
||||||
use hyper::header::{Headers, ContentType};
|
use hyper::header::{Headers, ContentType};
|
||||||
|
@ -1,40 +1,51 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
extern crate serde_xml_rs;
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
extern crate serde_xml_rs;
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "/v2";
|
pub const BASE_PATH: &'static str = "/v2";
|
||||||
pub const API_VERSION: &'static str = "1.0.0";
|
pub const API_VERSION: &'static str = "1.0.0";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use serde_xml_rs;
|
use serde_xml_rs;
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
@ -9,10 +8,11 @@ use std::collections::{HashMap, BTreeMap};
|
|||||||
use models;
|
use models;
|
||||||
use swagger;
|
use swagger;
|
||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
use uuid;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct AdditionalPropertiesClass {
|
pub struct AdditionalPropertiesClass {
|
||||||
#[serde(rename = "map_property")]
|
#[serde(rename = "map_property")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -43,6 +43,7 @@ impl AdditionalPropertiesClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct Animal {
|
pub struct Animal {
|
||||||
#[serde(rename = "className")]
|
#[serde(rename = "className")]
|
||||||
pub class_name: String,
|
pub class_name: String,
|
||||||
@ -72,6 +73,7 @@ impl Animal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct AnimalFarm(Vec<Animal>);
|
pub struct AnimalFarm(Vec<Animal>);
|
||||||
|
|
||||||
impl ::std::convert::From<Vec<Animal>> for AnimalFarm {
|
impl ::std::convert::From<Vec<Animal>> for AnimalFarm {
|
||||||
@ -143,6 +145,7 @@ impl AnimalFarm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ApiResponse {
|
pub struct ApiResponse {
|
||||||
#[serde(rename = "code")]
|
#[serde(rename = "code")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -178,6 +181,7 @@ impl ApiResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ArrayOfArrayOfNumberOnly {
|
pub struct ArrayOfArrayOfNumberOnly {
|
||||||
#[serde(rename = "ArrayArrayNumber")]
|
#[serde(rename = "ArrayArrayNumber")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -203,6 +207,7 @@ impl ArrayOfArrayOfNumberOnly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ArrayOfNumberOnly {
|
pub struct ArrayOfNumberOnly {
|
||||||
#[serde(rename = "ArrayNumber")]
|
#[serde(rename = "ArrayNumber")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -228,6 +233,7 @@ impl ArrayOfNumberOnly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ArrayTest {
|
pub struct ArrayTest {
|
||||||
#[serde(rename = "array_of_string")]
|
#[serde(rename = "array_of_string")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -269,6 +275,7 @@ impl ArrayTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct Capitalization {
|
pub struct Capitalization {
|
||||||
#[serde(rename = "smallCamel")]
|
#[serde(rename = "smallCamel")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -320,6 +327,7 @@ impl Capitalization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct Cat {
|
pub struct Cat {
|
||||||
#[serde(rename = "className")]
|
#[serde(rename = "className")]
|
||||||
pub class_name: String,
|
pub class_name: String,
|
||||||
@ -354,6 +362,7 @@ impl Cat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct CatAllOf {
|
pub struct CatAllOf {
|
||||||
#[serde(rename = "declawed")]
|
#[serde(rename = "declawed")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -379,6 +388,7 @@ impl CatAllOf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Category")]
|
#[serde(rename = "Category")]
|
||||||
pub struct Category {
|
pub struct Category {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
@ -411,6 +421,7 @@ impl Category {
|
|||||||
|
|
||||||
/// Model for testing model with \"_class\" property
|
/// Model for testing model with \"_class\" property
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ClassModel {
|
pub struct ClassModel {
|
||||||
#[serde(rename = "_class")]
|
#[serde(rename = "_class")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -436,6 +447,7 @@ impl ClassModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
#[serde(rename = "client")]
|
#[serde(rename = "client")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -461,6 +473,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct Dog {
|
pub struct Dog {
|
||||||
#[serde(rename = "className")]
|
#[serde(rename = "className")]
|
||||||
pub class_name: String,
|
pub class_name: String,
|
||||||
@ -495,6 +508,7 @@ impl Dog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct DogAllOf {
|
pub struct DogAllOf {
|
||||||
#[serde(rename = "breed")]
|
#[serde(rename = "breed")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -520,6 +534,7 @@ impl DogAllOf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct EnumArrays {
|
pub struct EnumArrays {
|
||||||
// Note: inline enums are not fully supported by openapi-generator
|
// Note: inline enums are not fully supported by openapi-generator
|
||||||
#[serde(rename = "just_symbol")]
|
#[serde(rename = "just_symbol")]
|
||||||
@ -562,7 +577,8 @@ impl EnumArrays {
|
|||||||
/// which helps with FFI.
|
/// which helps with FFI.
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Eq, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGenericEnum))]
|
||||||
pub enum EnumClass {
|
pub enum EnumClass {
|
||||||
#[serde(rename = "_abc")]
|
#[serde(rename = "_abc")]
|
||||||
_ABC,
|
_ABC,
|
||||||
@ -604,6 +620,7 @@ impl EnumClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct EnumTest {
|
pub struct EnumTest {
|
||||||
// Note: inline enums are not fully supported by openapi-generator
|
// Note: inline enums are not fully supported by openapi-generator
|
||||||
#[serde(rename = "enum_string")]
|
#[serde(rename = "enum_string")]
|
||||||
@ -652,6 +669,7 @@ impl EnumTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct FormatTest {
|
pub struct FormatTest {
|
||||||
#[serde(rename = "integer")]
|
#[serde(rename = "integer")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -733,6 +751,7 @@ impl FormatTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct HasOnlyReadOnly {
|
pub struct HasOnlyReadOnly {
|
||||||
#[serde(rename = "bar")]
|
#[serde(rename = "bar")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -763,6 +782,7 @@ impl HasOnlyReadOnly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct List {
|
pub struct List {
|
||||||
#[serde(rename = "123-list")]
|
#[serde(rename = "123-list")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -788,6 +808,7 @@ impl List {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct MapTest {
|
pub struct MapTest {
|
||||||
#[serde(rename = "map_map_of_string")]
|
#[serde(rename = "map_map_of_string")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -825,6 +846,7 @@ impl MapTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct MixedPropertiesAndAdditionalPropertiesClass {
|
pub struct MixedPropertiesAndAdditionalPropertiesClass {
|
||||||
#[serde(rename = "uuid")]
|
#[serde(rename = "uuid")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -861,6 +883,7 @@ impl MixedPropertiesAndAdditionalPropertiesClass {
|
|||||||
|
|
||||||
/// Model for testing model name starting with number
|
/// Model for testing model name starting with number
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Name")]
|
#[serde(rename = "Name")]
|
||||||
pub struct Model200Response {
|
pub struct Model200Response {
|
||||||
#[serde(rename = "name")]
|
#[serde(rename = "name")]
|
||||||
@ -893,6 +916,7 @@ impl Model200Response {
|
|||||||
|
|
||||||
/// Model for testing reserved words
|
/// Model for testing reserved words
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Return")]
|
#[serde(rename = "Return")]
|
||||||
pub struct ModelReturn {
|
pub struct ModelReturn {
|
||||||
#[serde(rename = "return")]
|
#[serde(rename = "return")]
|
||||||
@ -920,6 +944,7 @@ impl ModelReturn {
|
|||||||
|
|
||||||
/// Model for testing model name same as property name
|
/// Model for testing model name same as property name
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Name")]
|
#[serde(rename = "Name")]
|
||||||
pub struct Name {
|
pub struct Name {
|
||||||
#[serde(rename = "name")]
|
#[serde(rename = "name")]
|
||||||
@ -960,6 +985,7 @@ impl Name {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct NumberOnly {
|
pub struct NumberOnly {
|
||||||
#[serde(rename = "JustNumber")]
|
#[serde(rename = "JustNumber")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -985,6 +1011,7 @@ impl NumberOnly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Order")]
|
#[serde(rename = "Order")]
|
||||||
pub struct Order {
|
pub struct Order {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
@ -1038,6 +1065,7 @@ impl Order {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
|
|
||||||
pub struct OuterBoolean(bool);
|
pub struct OuterBoolean(bool);
|
||||||
|
|
||||||
@ -1078,6 +1106,7 @@ impl OuterBoolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct OuterComposite {
|
pub struct OuterComposite {
|
||||||
#[serde(rename = "my_number")]
|
#[serde(rename = "my_number")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -1117,7 +1146,8 @@ impl OuterComposite {
|
|||||||
/// which helps with FFI.
|
/// which helps with FFI.
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Eq, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGenericEnum))]
|
||||||
pub enum OuterEnum {
|
pub enum OuterEnum {
|
||||||
#[serde(rename = "placed")]
|
#[serde(rename = "placed")]
|
||||||
PLACED,
|
PLACED,
|
||||||
@ -1159,6 +1189,7 @@ impl OuterEnum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
|
|
||||||
pub struct OuterNumber(f64);
|
pub struct OuterNumber(f64);
|
||||||
|
|
||||||
@ -1199,6 +1230,7 @@ impl OuterNumber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
|
|
||||||
pub struct OuterString(String);
|
pub struct OuterString(String);
|
||||||
|
|
||||||
@ -1245,6 +1277,7 @@ impl OuterString {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Pet")]
|
#[serde(rename = "Pet")]
|
||||||
pub struct Pet {
|
pub struct Pet {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
@ -1296,6 +1329,7 @@ impl Pet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ReadOnlyFirst {
|
pub struct ReadOnlyFirst {
|
||||||
#[serde(rename = "bar")]
|
#[serde(rename = "bar")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -1326,6 +1360,7 @@ impl ReadOnlyFirst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "$special[model.name]")]
|
#[serde(rename = "$special[model.name]")]
|
||||||
pub struct SpecialModelName {
|
pub struct SpecialModelName {
|
||||||
#[serde(rename = "$special[property.name]")]
|
#[serde(rename = "$special[property.name]")]
|
||||||
@ -1352,6 +1387,7 @@ impl SpecialModelName {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "Tag")]
|
#[serde(rename = "Tag")]
|
||||||
pub struct Tag {
|
pub struct Tag {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
@ -1383,6 +1419,7 @@ impl Tag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
#[serde(rename = "User")]
|
#[serde(rename = "User")]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
|
@ -7,42 +7,59 @@ license = "Unlicense"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["client", "server"]
|
default = ["client", "server"]
|
||||||
client = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url", "uuid"]
|
client = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "url"]
|
||||||
server = ["serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url", "uuid"]
|
server = ["serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio-core", "tokio-proto", "tokio-tls", "regex", "percent-encoding", "url"]
|
||||||
|
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Required by example server.
|
# Common
|
||||||
#
|
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
hyper = {version = "0.11", optional = true}
|
|
||||||
hyper-tls = {version = "0.1.2", optional = true}
|
|
||||||
swagger = "2"
|
swagger = "2"
|
||||||
|
|
||||||
# Not required by example server.
|
|
||||||
#
|
|
||||||
lazy_static = "0.2"
|
lazy_static = "0.2"
|
||||||
log = "0.3.0"
|
log = "0.3.0"
|
||||||
mime = "0.2.6"
|
mime = "0.2.6"
|
||||||
multipart = {version = "0.13.3"}
|
multipart = "0.13.3"
|
||||||
native-tls = {version = "0.1.4", optional = true}
|
|
||||||
openssl = {version = "0.9.14", optional = true}
|
|
||||||
percent-encoding = {version = "1.0.0", optional = true}
|
|
||||||
regex = {version = "0.2", optional = true}
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
|
# Crates included if required by the API definition
|
||||||
|
|
||||||
|
# Common between server and client features
|
||||||
|
hyper = {version = "0.11", optional = true}
|
||||||
|
hyper-tls = {version = "0.1.2", optional = true}
|
||||||
|
native-tls = {version = "0.1.4", optional = true}
|
||||||
|
openssl = {version = "0.9.14", optional = true}
|
||||||
serde_ignored = {version = "0.0.4", optional = true}
|
serde_ignored = {version = "0.0.4", optional = true}
|
||||||
serde_json = {version = "1.0", optional = true}
|
|
||||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
|
||||||
tokio-core = {version = "0.1.6", optional = true}
|
tokio-core = {version = "0.1.6", optional = true}
|
||||||
|
url = {version = "1.5", optional = true}
|
||||||
|
|
||||||
|
# Client-specific
|
||||||
|
|
||||||
|
|
||||||
|
# Server-specific
|
||||||
|
percent-encoding = {version = "1.0.0", optional = true}
|
||||||
|
regex = {version = "0.2", optional = true}
|
||||||
tokio-proto = {version = "0.1.1", optional = true}
|
tokio-proto = {version = "0.1.1", optional = true}
|
||||||
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
tokio-tls = {version = "0.1.3", optional = true, features = ["tokio-proto"]}
|
||||||
url = {version = "1.5", optional = true}
|
|
||||||
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
|
|
||||||
# ToDo: this should be updated to point at the official crate once
|
|
||||||
# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
|
||||||
|
|
||||||
|
# Other optional crates
|
||||||
|
frunk = { version = "0.3.0", optional = true }
|
||||||
|
frunk_derives = { version = "0.3.0", optional = true }
|
||||||
|
frunk_core = { version = "0.3.0", optional = true }
|
||||||
|
frunk-enum-derive = { version = "0.2.0", optional = true }
|
||||||
|
frunk-enum-core = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
clap = "2.25"
|
clap = "2.25"
|
||||||
error-chain = "0.12"
|
error-chain = "0.12"
|
||||||
|
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "client"
|
||||||
|
required-features = ["client"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "server"
|
||||||
|
required-features = ["server"]
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
This spec is for testing rust-server-specific things
|
This spec is for testing rust-server-specific things
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This client/server was generated by the [openapi-generator]
|
This client/server was generated by the [openapi-generator]
|
||||||
(https://openapi-generator.tech) project.
|
(https://openapi-generator.tech) project. By using the
|
||||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
[OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote
|
||||||
-
|
server, you can easily generate a server stub.
|
||||||
|
|
||||||
To see how to make this your own, look here:
|
To see how to make this your own, look here:
|
||||||
|
|
||||||
@ -14,6 +15,9 @@ To see how to make this your own, look here:
|
|||||||
|
|
||||||
- API version: 2.3.4
|
- API version: 2.3.4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This autogenerated project defines an API crate `rust-server-test` which contains:
|
This autogenerated project defines an API crate `rust-server-test` which contains:
|
||||||
* An `Api` trait defining the API in Rust.
|
* An `Api` trait defining the API in Rust.
|
||||||
* Data types representing the underlying data model.
|
* Data types representing the underlying data model.
|
||||||
@ -21,15 +25,17 @@ This autogenerated project defines an API crate `rust-server-test` which contain
|
|||||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||||
|
|
||||||
It also contains an example server and client which make use of `rust-server-test`:
|
It also contains an example server and client which make use of `rust-server-test`:
|
||||||
* The example server starts up a web server using the `rust-server-test` router,
|
|
||||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
* The example server starts up a web server using the `rust-server-test`
|
||||||
* The example client provides a CLI which lets you invoke any single operation on the
|
router, and supplies a trivial implementation of `Api` which returns failure
|
||||||
`rust-server-test` client by passing appropriate arguments on the command line.
|
for every operation.
|
||||||
|
* The example client provides a CLI which lets you invoke
|
||||||
|
any single operation on the `rust-server-test` client by passing appropriate
|
||||||
|
arguments on the command line.
|
||||||
|
|
||||||
You can use the example server and client as a basis for your own code.
|
You can use the example server and client as a basis for your own code.
|
||||||
See below for [more detail on implementing a server](#writing-a-server).
|
See below for [more detail on implementing a server](#writing-a-server).
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Run examples with:
|
Run examples with:
|
||||||
@ -44,14 +50,14 @@ To pass in arguments to the examples, put them after `--`, for example:
|
|||||||
cargo run --example client -- --help
|
cargo run --example client -- --help
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running the server
|
### Running the example server
|
||||||
To run the server, follow these simple steps:
|
To run the server, follow these simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo run --example server
|
cargo run --example server
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running a client
|
### Running the example client
|
||||||
To run a client, follow one of the following simple steps:
|
To run a client, follow one of the following simple steps:
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -69,43 +75,23 @@ The examples can be run in HTTPS mode by passing in the flag `--https`, for exam
|
|||||||
cargo run --example server -- --https
|
cargo run --example server -- --https
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the keys/certificates from the examples directory. Note that the server chain is signed with
|
This will use the keys/certificates from the examples directory. Note that the
|
||||||
`CN=localhost`.
|
server chain is signed with `CN=localhost`.
|
||||||
|
|
||||||
|
## Using the generated library
|
||||||
|
|
||||||
## Writing a server
|
The generated library has a few optional features that can be activated through Cargo.
|
||||||
|
|
||||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
* `server`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a server implementation based on hyper
|
||||||
|
* To create the server stack you'll need to provide an implementation of the API trait to provide the server function.
|
||||||
|
* `client`
|
||||||
|
* This defaults to enabled and creates the basic skeleton of a client implementation based on hyper
|
||||||
|
* The constructed client implements the API trait by making remote API call.
|
||||||
|
* `conversions`
|
||||||
|
* This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types.
|
||||||
|
|
||||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`.
|
||||||
* Insert `rust-server-test` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "rust-server-test" ]`.
|
|
||||||
* Add `rust-server-test = {version = "2.3.4", path = "rust-server-test"}` under `[dependencies]` in the root `Cargo.toml`.
|
|
||||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `rust-server-test/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
|
||||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
|
||||||
* Remove `"optional = true"` from each of these lines if present.
|
|
||||||
|
|
||||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
|
||||||
```
|
|
||||||
cp rust-server-test/examples/server.rs src/main.rs
|
|
||||||
cp rust-server-test/examples/server_lib/mod.rs src/lib.rs
|
|
||||||
cp rust-server-test/examples/server_lib/server.rs src/server.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Now
|
|
||||||
|
|
||||||
* From `src/main.rs`, remove the `mod server_lib;` line, and uncomment and fill in the `extern crate` line with the name of this server crate.
|
|
||||||
* Move the block of imports "required by the service library" from `src/main.rs` to `src/lib.rs` and uncomment.
|
|
||||||
* Change the `let server = server::Server {};` line to `let server = SERVICE_NAME::server().unwrap();` where `SERVICE_NAME` is the name of the server crate.
|
|
||||||
* Run `cargo build` to check it builds.
|
|
||||||
* Run `cargo fmt` to reformat the code.
|
|
||||||
* Commit the result before making any further changes (lest format changes get confused with your own updates).
|
|
||||||
|
|
||||||
Now replace the implementations in `src/server.rs` with your own code as required.
|
|
||||||
|
|
||||||
## Updating your server to track API changes
|
|
||||||
|
|
||||||
Later, if the API changes, you can copy new sections from the autogenerated API stub into your implementation.
|
|
||||||
Alternatively, implement the now-missing methods based on the compiler's error messages.
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ extern crate futures;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate swagger;
|
extern crate swagger;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate uuid;
|
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
|
extern crate uuid;
|
||||||
|
|
||||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ extern crate chrono;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
|
|
||||||
use openssl::x509::X509_FILETYPE_PEM;
|
use openssl::x509::X509_FILETYPE_PEM;
|
||||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||||
use openssl::error::ErrorStack;
|
use openssl::error::ErrorStack;
|
||||||
|
@ -6,7 +6,6 @@ use futures::{self, Future};
|
|||||||
use chrono;
|
use chrono;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use swagger;
|
use swagger;
|
||||||
use swagger::{Has, XSpanIdString};
|
use swagger::{Has, XSpanIdString};
|
||||||
|
|
||||||
|
@ -1,40 +1,50 @@
|
|||||||
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, non_camel_case_types)]
|
||||||
extern crate serde;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
extern crate serde_json;
|
|
||||||
|
|
||||||
|
|
||||||
extern crate futures;
|
|
||||||
extern crate chrono;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate mime;
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
// Logically this should be in the client and server modules, but rust doesn't allow `macro_use` from a module.
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
extern crate swagger;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
|
// Crates for conversion support
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_derives;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate frunk_enum_derive;
|
||||||
|
#[cfg(feature = "conversion")]
|
||||||
|
extern crate frunk_core;
|
||||||
|
|
||||||
|
extern crate mime;
|
||||||
|
extern crate serde;
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
extern crate futures;
|
||||||
|
extern crate chrono;
|
||||||
|
extern crate swagger;
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub use futures::Future;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "client", feature = "server"))]
|
#[cfg(any(feature = "client", feature = "server"))]
|
||||||
mod mimetypes;
|
mod mimetypes;
|
||||||
|
|
||||||
|
#[deprecated(note = "Import swagger-rs directly")]
|
||||||
pub use swagger::{ApiError, ContextWrapper};
|
pub use swagger::{ApiError, ContextWrapper};
|
||||||
|
#[deprecated(note = "Import futures directly")]
|
||||||
|
pub use futures::Future;
|
||||||
|
|
||||||
pub const BASE_PATH: &'static str = "";
|
pub const BASE_PATH: &'static str = "";
|
||||||
pub const API_VERSION: &'static str = "2.3.4";
|
pub const API_VERSION: &'static str = "2.3.4";
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
#![allow(unused_imports, unused_qualifications, unused_extern_crates)]
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use serde::ser::Serializer;
|
use serde::ser::Serializer;
|
||||||
|
|
||||||
@ -10,8 +9,8 @@ use swagger;
|
|||||||
use std::string::ParseError;
|
use std::string::ParseError;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ANullableContainer {
|
pub struct ANullableContainer {
|
||||||
#[serde(rename = "NullableThing")]
|
#[serde(rename = "NullableThing")]
|
||||||
#[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")]
|
#[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")]
|
||||||
@ -36,6 +35,7 @@ impl ANullableContainer {
|
|||||||
|
|
||||||
/// An additionalPropertiesObject
|
/// An additionalPropertiesObject
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct AdditionalPropertiesObject {
|
pub struct AdditionalPropertiesObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ impl AdditionalPropertiesObject {
|
|||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct InlineObject {
|
pub struct InlineObject {
|
||||||
#[serde(rename = "id")]
|
#[serde(rename = "id")]
|
||||||
pub id: String,
|
pub id: String,
|
||||||
@ -70,6 +71,7 @@ impl InlineObject {
|
|||||||
|
|
||||||
/// An object of objects
|
/// An object of objects
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ObjectOfObjects {
|
pub struct ObjectOfObjects {
|
||||||
#[serde(rename = "inner")]
|
#[serde(rename = "inner")]
|
||||||
#[serde(skip_serializing_if="Option::is_none")]
|
#[serde(skip_serializing_if="Option::is_none")]
|
||||||
@ -87,6 +89,7 @@ impl ObjectOfObjects {
|
|||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "conversion", derive(LabelledGeneric))]
|
||||||
pub struct ObjectOfObjectsInner {
|
pub struct ObjectOfObjectsInner {
|
||||||
#[serde(rename = "required_thing")]
|
#[serde(rename = "required_thing")]
|
||||||
pub required_thing: String,
|
pub required_thing: String,
|
||||||
|
@ -8,7 +8,6 @@ extern crate mime;
|
|||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
extern crate percent_encoding;
|
extern crate percent_encoding;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user