Skip to content

Commit 1a831f7

Browse files
bjgillwing328
authored andcommitted
[rust-server] Plaintext support; encode params (#7082)
* MMORCH-428: Export the Authorization struct This is needed so that code can check that the version of Authorization in the auto-generated code is the same as the version it is using. If the versions are not exactly the same then the lookup into the TypeMap will not work. * Add Rust as a supported language for client and server. Clarify that there are two Rust client implementations, and one Rust server implementation. * Percent-encode path and query parameters in client URLs Fixes #122 Also don't include a question mark at the end of the path when there are no query paramters. Fixes #121 * Rust2 client: add --host and --port parameters to example client. Allows the example command-line client to override the default host and port. * Extract default host and port from Swagger file. * Derive 'Eq' and 'Ord' on enums * Rust2: improve server code structure. server.rs (main.rs) - main entry point for binary; starts the web server and points it at the server code within the library. server_lib/mod.rs (lib.rs) - root of library; creates the server. server_lib/server.rs (server.rs) - actual server code The old server_lib/mod.rs is now server_lib/server.rs; server_lib/mod.rs is new. This structure is easy to map onto a server implementation; unfortunately we can't get it exactly right here because of the limitations of cargo's examples/ folder. * Rust2: Explain fully how to use the example code in your project. * Added plaintext support * Linting * MGJ Markups
1 parent 20f48b0 commit 1a831f7

File tree

23 files changed

+1107
-455
lines changed

23 files changed

+1107
-455
lines changed

README.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
## Overview
2525
This is the swagger codegen project, which allows generation of API client libraries (SDK generation), server stubs and documentation automatically given an [OpenAPI Spec](https://github.com/OAI/OpenAPI-Specification). Currently, the following languages/frameworks are supported:
2626

27-
- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust**, **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
28-
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go**, **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework), **PHP** (Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust**, **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), Scalatra)
29-
- **API documentation generators**: **HTML**, **Confluence Wiki**
27+
- **API clients**: **ActionScript**, **Ada**, **Apex**, **Bash**, **C#** (.net 2.0, 3.5 or later), **C++** (cpprest, Qt5, Tizen), **Clojure**, **Dart**, **Elixir**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java), **Kotlin**, **Lua**, **Node.js** (ES5, ES6, AngularJS with Google Closure Compiler annotations) **Objective-C**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (rust, rust-server), **Scala** (akka, http4s, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x), **Typescript** (Angular1.x, Angular2.x, Fetch, jQuery, Node)
28+
- **Server stubs**: **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed), **Erlang**, **Go**, **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, RestEasy, Play Framework), **PHP** (Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** ([Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), Scalatra)
29+
- **API documentation generators**: **HTML**, **Confluence Wiki**
3030
- **Configuration files**: [**Apache2**](https://httpd.apache.org/)
3131
- **Others**: **JMeter**
3232

@@ -300,8 +300,8 @@ OPTIONS
300300
adds authorization headers when fetching the swagger definitions
301301
remotely. Pass in a URL-encoded string of name:header with a comma
302302
separating multiple values
303-
304-
...... (results omitted)
303+
304+
...... (results omitted)
305305
306306
-v, --verbose
307307
verbose mode
@@ -497,7 +497,7 @@ and `config.json` contains the following as an example:
497497
}
498498
```
499499

500-
Supported config options can be different per language. Running `config-help -l {lang}` will show available options.
500+
Supported config options can be different per language. Running `config-help -l {lang}` will show available options.
501501
**These options are applied via configuration file (e.g. config.json) or by passing them with `-D{optionName}={optionValue}`**. (If `-D{optionName}` does not work, please open a [ticket](https://github.com/swagger-api/swagger-codegen/issues/new) and we'll look into it)
502502

503503
```sh
@@ -789,7 +789,7 @@ Here are some companies/projects using Swagger Codegen in production. To add you
789789
- [High Technologies Center](http://htc-cs.com)
790790
- [IBM](https://www.ibm.com)
791791
- [IMS Health](http://www.imshealth.com/en/solution-areas/technology-and-applications)
792-
- [Individual Standard IVS](http://www.individual-standard.com)
792+
- [Individual Standard IVS](http://www.individual-standard.com)
793793
- [Intent HQ](http://www.intenthq.com)
794794
- [Kabuku](http://www.kabuku.co.jp/en)
795795
- [Kurio](https://kurio.co.id)
@@ -890,7 +890,7 @@ Presentations/Videos/Tutorials/Books
890890
- 2016/11/25 - [Swagger Codegen for Swift3 and NodeJS](https://normand1.github.io/blog/swift/swagger/codegen/2016/11/25/Swagger-Codegen-for-Swift3-and-NodeJS.html) by [David Norman](https://github.com/normand1)
891891
- 2016/12/08 - [Generate client side code using Swagger Codegen](https://carra-lucia-ltd.co.uk/2016/12/08/generate-client-side-code-using-swagger-codegen/) by [theFerkel](https://carra-lucia-ltd.co.uk/author/theferkel/)
892892
- 2017/01/16 - [Zero to API in 4 minutes](https://cidrblock.github.io/zero-to-api-in-4-minutes.html) by [Bradley A. Thornton](https://github.com/cidrblock)
893-
- 2017/02/09 - [「Swaggerを利用した新規サービス開発」というタイトルで登壇して来ました](https://techblog.recochoku.jp/1055) by [recotech](https://www.slideshare.net/recotech)
893+
- 2017/02/09 - [「Swaggerを利用した新規サービス開発」というタイトルで登壇して来ました](https://techblog.recochoku.jp/1055) by [recotech](https://www.slideshare.net/recotech)
894894
- 2017/03/03 - [Swagger Codegen の使い方の簡単な説明です](https://speakerdeck.com/wagyu298/swagger-codegen) by [wagyu298](https://github.com/wagyu298)
895895
- 2017/03/24 - [Using Open API Specification To Put Lyft SDK Support in the Fast Lane](https://medium.com/lyft-developer-platform/using-open-api-specification-to-put-lyft-sdk-support-in-the-fast-lane-7b623218e4ee) by [Val Polouchkine](https://github.com/vpolouchkine)
896896
- 2017/04/13 - [Automatically Generating your API Client with Swagger and Swagger Codegen](https://www.youtube.com/watch?v=EzKwi-u9jQo) by [Jesse Collis](https://github.com/jessedc) @ Melbourne Cocoaheads
@@ -903,7 +903,7 @@ Presentations/Videos/Tutorials/Books
903903
- 2017/07/11 - [OpenAPI development with Python](https://www.slideshare.net/TakuroWada/20170711-euro-python2017) by [和田拓朗](https://github.com/taxpon) at [EuroPython 2017](https://ep2017.europython.eu/en/)
904904
- 2017/07/29 - [How Square makes its SDKs](https://medium.com/square-corner-blog/how-square-makes-its-sdks-6a0fd7ea4b2d) by [Tristan Sokol](https://github.com/tristansokol) ([Square](https://github.com/square))
905905
- 2017/07/31 - [How to Generate a Deployable REST CXF3 Application from a Swagger-Contract](https://www.youtube.com/watch?v=gM63rJlUHZQ) by [Johannes Fiala](https://github.com/jfiala) @ Voxxed Days Vienna
906-
- 2017/08/11 - [Swagger Codegen 自动生成Retrofit 代码](https://juejin.im/entry/598d8eb86fb9a03c52459e2a) by [徐磊](http://www.jianshu.com/u/792c738b33fc)
906+
- 2017/08/11 - [Swagger Codegen 自动生成Retrofit 代码](https://juejin.im/entry/598d8eb86fb9a03c52459e2a) by [徐磊](http://www.jianshu.com/u/792c738b33fc)
907907
- 2017/08/24 - [APIs First](https://engineering.squarespace.com/blog/2017/apis-first) by [roykachouh](https://github.com/roykachouh) ([Square](https://github.com/square))
908908
- 2017/08/31 - [Bringing Jenkins Remote Access API To The Masses](http://blog.cliffano.com/2017/09/01/jenkins-world-2017/) by [Cliffano Subagio](http://cliffano.com) from [Shine Solutions](https://shinesolutions.com/) @ [Jenkins World 2017](https://jenkinsworld20162017.sched.com/)
909909
- 2017/09/08 - [Swagger Codegen で自動生成したクライアントSDKを使う(iOS編)](http://blog.techium.jp/entry/2017/09/08/071650) by [kfurue](http://profile.hatena.ne.jp/kfurue/)
@@ -928,12 +928,12 @@ Swagger Codegen core team members are contributors who have been making signific
928928
| Languages | Core Team (join date) |
929929
|:-------------|:-------------|
930930
| ActionScript | |
931-
| C++ | |
931+
| C++ | |
932932
| C# | @jimschubert (2016/05/01) |
933933
| Clojure | @xhh (2016/05/01) |
934-
| Dart | |
935-
| Groovy | |
936-
| Go | @guohuang (2016/05/01) @neilotoole (2016/05/01) |
934+
| Dart | |
935+
| Groovy | |
936+
| Go | @guohuang (2016/05/01) @neilotoole (2016/05/01) |
937937
| Java | @cbornet (2016/05/01) @xhh (2016/05/01) @epaul (2016/06/04) |
938938
| Java (Spring Cloud) | @cbornet (2016/07/19) |
939939
| Kotlin | @jimschubert (2016/05/01) |
@@ -960,7 +960,7 @@ Swagger Codegen core team members are contributors who have been making signific
960960
| Java JAX-RS | |
961961
| Java Play Framework | |
962962
| NancyFX | |
963-
| NodeJS | @kolyjjj (2016/05/01) |
963+
| NodeJS | @kolyjjj (2016/05/01) |
964964
| PHP Lumen | @abcsun (2016/05/01) |
965965
| PHP Silex | |
966966
| PHP Slim | |
@@ -1010,15 +1010,15 @@ Here is a list of template creators:
10101010
* R: @ramnov
10111011
* Rust: @farcaller
10121012
* Rust (rust-server): @metaswitch
1013-
* Scala (scalaz & http4s): @tbrown1979
1013+
* Scala (scalaz & http4s): @tbrown1979
10141014
* Swift: @tkqubo
10151015
* Swift 3: @hexelon
10161016
* Swift 4: @ehyche
10171017
* TypeScript (Node): @mhardorf
10181018
* TypeScript (Angular1): @mhardorf
10191019
* TypeScript (Fetch): @leonyu
10201020
* TypeScript (Angular2): @roni-frantchi
1021-
* TypeScript (jQuery): @bherila
1021+
* TypeScript (jQuery): @bherila
10221022
* Server Stubs
10231023
* C# ASP.NET5: @jimschubert
10241024
* C# NancyFX: @mstefaniuk
@@ -1083,7 +1083,7 @@ If you want to join the committee, please kindly apply by sending an email to wi
10831083
| Android | @jaz-ah (2017/09) |
10841084
| Apex | |
10851085
| Bash | @frol (2017/07) @bkryza (2017/08) @kenjones-cisco (2017/09) |
1086-
| C++ | @ravinikam (2017/07) @stkrwork (2017/07) @fvarose (2017/11) |
1086+
| C++ | @ravinikam (2017/07) @stkrwork (2017/07) @fvarose (2017/11) |
10871087
| C# | @mandrean (2017/08) @jimschubert (2017/09) |
10881088
| Clojure | |
10891089
| Dart | @ircecho (2017/07) |
@@ -1103,7 +1103,7 @@ If you want to join the committee, please kindly apply by sending an email to wi
11031103
| Python | @taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) @kenjones-cisco (2017/11)|
11041104
| R | |
11051105
| Ruby | @cliffano (2017/07) @zlx (2017/09) |
1106-
| Rust | @frol (2017/07) @farcaller (2017/08) |
1106+
| Rust | @frol (2017/07) @farcaller (2017/08) |
11071107
| Scala | @clasnake (2017/07) @jimschubert (2017/09) |
11081108
| Swift | @jgavris (2017/07) @ehyche (2017/08) @Edubits (2017/09) @jaz-ah (2017/09) |
11091109
| TypeScript | @TiFu (2017/07) @taxpon (2017/07) @sebastianhaas (2017/07) @kenisteward (2017/07) @Vrolijkx (2017/09) |

modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/RustServerCodegen.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
3434
private HashMap<String, String> modelXmlNames = new HashMap<String, String>();
3535

3636
protected String apiVersion = "1.0.0";
37+
protected String serverHost = "localhost";
3738
protected int serverPort = 8080;
3839
protected String projectName = "swagger-server";
3940
protected String apiPath = "rust-server";
@@ -148,7 +149,6 @@ public RustServerCodegen() {
148149
* are available in models, apis, and supporting files
149150
*/
150151
additionalProperties.put("apiVersion", apiVersion);
151-
additionalProperties.put("serverPort", serverPort);
152152
additionalProperties.put("apiPath", apiPath);
153153

154154
/*
@@ -168,6 +168,7 @@ public RustServerCodegen() {
168168
supportingFiles.add(new SupportingFile("example-server.mustache", "examples", "server.rs"));
169169
supportingFiles.add(new SupportingFile("example-client.mustache", "examples", "client.rs"));
170170
supportingFiles.add(new SupportingFile("example-server_lib.mustache", "examples/server_lib", "mod.rs"));
171+
supportingFiles.add(new SupportingFile("example-server_server.mustache", "examples/server_lib", "server.rs"));
171172
supportingFiles.add(new SupportingFile("example-ca.pem", "examples", "ca.pem"));
172173
supportingFiles.add(new SupportingFile("example-server-chain.pem", "examples", "server-chain.pem"));
173174
supportingFiles.add(new SupportingFile("example-server-key.pem", "examples", "server-key.pem"));
@@ -257,6 +258,23 @@ public void preprocessSwagger(Swagger swagger) {
257258
versionComponents.add("0");
258259
}
259260
info.setVersion(StringUtils.join(versionComponents, "."));
261+
262+
String host = swagger.getHost();
263+
if (host != null) {
264+
String[] parts = host.split(":");
265+
if (parts.length > 1) {
266+
serverHost = parts[0];
267+
try {
268+
serverPort = Integer.valueOf(parts[1]);
269+
} catch (NumberFormatException e) {
270+
LOGGER.warn("Port of Swagger host is not an integer : " + host, e);
271+
}
272+
} else {
273+
serverHost = host;
274+
}
275+
}
276+
additionalProperties.put("serverHost", serverHost);
277+
additionalProperties.put("serverPort", serverPort);
260278
}
261279

262280
@Override
@@ -512,6 +530,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
512530
LOGGER.debug("No consumes defined in operation. Using global consumes (" + swagger.getConsumes() + ") for " + op.operationId);
513531
}
514532

533+
boolean consumesPlainText = false;
515534
boolean consumesXml = false;
516535
// if "consumes" is defined (per operation or using global definition)
517536
if (consumes != null && !consumes.isEmpty()) {
@@ -523,6 +542,8 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
523542
if (mimeType.startsWith("Application/Xml")) {
524543
additionalProperties.put("usesXml", true);
525544
consumesXml = true;
545+
} else if (mimeType.startsWith("Text/Plain")) {
546+
consumesPlainText = true;
526547
}
527548

528549
mediaType.put("mediaType", mimeType);
@@ -545,6 +566,7 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
545566
}
546567

547568
boolean producesXml = false;
569+
boolean producesPlainText = false;
548570
if (produces != null && !produces.isEmpty()) {
549571
List<Map<String, String>> c = new ArrayList<Map<String, String>>();
550572
for (String key : produces) {
@@ -554,6 +576,8 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
554576
if (mimeType.startsWith("Application/Xml")) {
555577
additionalProperties.put("usesXml", true);
556578
producesXml = true;
579+
} else if (mimeType.startsWith("Text/Plain")) {
580+
producesPlainText = true;
557581
}
558582

559583
mediaType.put("mediaType", mimeType);
@@ -572,9 +596,14 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
572596
op.bodyParam.vendorExtensions.put("model_key", key);
573597
}
574598

599+
// Default to consuming json
575600
op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
576601
if (consumesXml) {
577602
op.bodyParam.vendorExtensions.put("consumesXml", true);
603+
} else if (consumesPlainText) {
604+
op.bodyParam.vendorExtensions.put("consumesPlainText", true);
605+
} else {
606+
op.bodyParam.vendorExtensions.put("consumesJson", true);
578607
}
579608

580609
}
@@ -586,8 +615,13 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
586615

587616
param.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase());
588617

618+
// Default to producing json if nothing else is specified
589619
if (consumesXml) {
590620
param.vendorExtensions.put("consumesXml", true);
621+
} else if (consumesPlainText) {
622+
param.vendorExtensions.put("consumesPlainText", true);
623+
} else {
624+
param.vendorExtensions.put("consumesJson", true);
591625
}
592626
}
593627
for (CodegenParameter param : op.headerParams) {
@@ -601,8 +635,13 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
601635
if (rsp.dataType != null) {
602636
rsp.vendorExtensions.put("uppercase_data_type", (rsp.dataType.replace("models::", "")).toUpperCase());
603637

638+
// Default to producing json if nothing else is specified
604639
if (producesXml) {
605640
rsp.vendorExtensions.put("producesXml", true);
641+
} else if (producesPlainText) {
642+
rsp.vendorExtensions.put("producesPlainText", true);
643+
} else {
644+
rsp.vendorExtensions.put("producesJson", true);
606645
}
607646

608647
// Check whether we're returning an object with a defined XML namespace.

modules/swagger-codegen/src/main/resources/rust-server/Cargo.mustache

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,19 @@ client = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored",
1313
server = ["serde_json", {{#usesXml}}"serde-xml-rs", {{/usesXml}}"serde_ignored", "hyper", "iron", "router", "bodyparser", "urlencoded", "uuid"{{#apiHasFile}}, "multipart"{{/apiHasFile}}]
1414

1515
[dependencies]
16-
bodyparser = {version = "0.7", optional = true}
16+
# Required by example server.
17+
#
1718
chrono = { version = "0.4", features = ["serde"] }
1819
futures = "0.1"
1920
hyper = {version = "0.10", optional = true}
2021
hyper-openssl = {version = "0.2", optional = true }
2122
iron = {version = "0.5", optional = true}
23+
swagger = "0.7"
24+
25+
# Not required by example server.
26+
#
27+
bodyparser = {version = "0.7", optional = true}
28+
url = "1.5"
2229
lazy_static = "0.2"
2330
log = "0.3.0"
2431
multipart = {version = "0.13", optional = true}
@@ -27,7 +34,6 @@ serde = "1.0"
2734
serde_derive = "1.0"
2835
serde_ignored = {version = "0.0.4", optional = true}
2936
serde_json = {version = "1.0", optional = true}
30-
swagger = "0.7"
3137
urlencoded = {version = "0.5", optional = true}
3238
uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
3339
# ToDo: this should be updated to point at the official crate once
@@ -36,3 +42,4 @@ uuid = {version = "0.5", optional = true, features = ["serde", "v4"]}
3642

3743
[dev-dependencies]
3844
clap = "2.25"
45+
error-chain = "0.11"

0 commit comments

Comments
 (0)