forked from loafle/openapi-generator-original
[Rust Server] Support OpenAPI v3 callbacks (#5405)
* [Rust Server] Support Callbacks * [Rust Server] Support callbacks in the examples * [Rust Server] Update features documentation * [Rust Server] Mark as supporting callbacks * Update samples * [Rust Server] Add tests for callbacks * [Rust Server] Fix README Don't suggest examples which don't exist
This commit is contained in:
committed by
GitHub
parent
8f8443d175
commit
b60fc900b2
@@ -163,7 +163,7 @@ sidebar_label: rust-server
|
||||
|MultiServer|✗|OAS3
|
||||
|ParameterizedServer|✗|OAS3
|
||||
|ParameterStyling|✗|OAS3
|
||||
|Callbacks|✗|OAS3
|
||||
|Callbacks|✓|OAS3
|
||||
|LinkObjects|✗|OAS3
|
||||
|
||||
### Parameter Feature
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.openapitools.codegen.utils.StringUtils.camelize;
|
||||
@@ -62,7 +63,8 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
protected String packageName;
|
||||
protected String packageVersion;
|
||||
protected String externCrateName;
|
||||
protected Map<String, Map<String, String>> pathSetMap = new HashMap<String, Map<String, String>>();
|
||||
protected Map<String, Map<String, String>> pathSetMap = new HashMap();
|
||||
protected Map<String, Map<String, String>> callbacksPathSetMap = new HashMap();
|
||||
|
||||
private static final String uuidType = "uuid::Uuid";
|
||||
private static final String bytesType = "swagger::ByteArray";
|
||||
@@ -92,7 +94,6 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
))
|
||||
.excludeGlobalFeatures(
|
||||
GlobalFeature.XMLStructureDefinitions,
|
||||
GlobalFeature.Callbacks,
|
||||
GlobalFeature.LinkObjects,
|
||||
GlobalFeature.ParameterStyling
|
||||
)
|
||||
@@ -234,15 +235,15 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
supportingFiles.add(new SupportingFile("cargo-config", ".cargo", "config"));
|
||||
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
|
||||
supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs"));
|
||||
supportingFiles.add(new SupportingFile("context.mustache", "src", "context.rs"));
|
||||
supportingFiles.add(new SupportingFile("models.mustache", "src", "models.rs"));
|
||||
supportingFiles.add(new SupportingFile("header.mustache", "src", "header.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-mod.mustache", "src/server", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-context.mustache", "src/server", "context.rs"));
|
||||
supportingFiles.add(new SupportingFile("client-mod.mustache", "src/client", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("mimetypes.mustache", "src", "mimetypes.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-server.mustache", "examples", "server.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-client.mustache", "examples", "client.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-server_lib.mustache", "examples/server_lib", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("server-mod.mustache", "src/server", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("client-mod.mustache", "src/client", "mod.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-server-main.mustache", "examples/server", "main.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-server-server.mustache", "examples/server", "server.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-client-main.mustache", "examples/client", "main.rs"));
|
||||
supportingFiles.add(new SupportingFile("example-ca.pem", "examples", "ca.pem"));
|
||||
supportingFiles.add(new SupportingFile("example-server-chain.pem", "examples", "server-chain.pem"));
|
||||
supportingFiles.add(new SupportingFile("example-server-key.pem", "examples", "server-key.pem"));
|
||||
@@ -587,21 +588,15 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return result;
|
||||
}
|
||||
|
||||
private String tidyUpRuntimeCallbackParam(String param) {
|
||||
return underscore(param.replace("-", "_").replace(".", "_").replace("{", "").replace("#", "_").replace("/", "_").replace("}", "").replace("$", "").replaceAll("_+", "_"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
|
||||
Map<String, Schema> definitions = ModelUtils.getSchemas(this.openAPI);
|
||||
CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers);
|
||||
|
||||
String pathFormatString = op.path;
|
||||
for (CodegenParameter param : op.pathParams) {
|
||||
// Replace {baseName} with {paramName} for format string
|
||||
String paramSearch = "{" + param.baseName + "}";
|
||||
String paramReplace = "{" + param.paramName + "}";
|
||||
|
||||
pathFormatString = pathFormatString.replace(paramSearch, paramReplace);
|
||||
}
|
||||
op.vendorExtensions.put("x-path-format-string", pathFormatString);
|
||||
|
||||
// The Rust code will need to contain a series of regular expressions.
|
||||
// For performance, we'll construct these at start-of-day and re-use
|
||||
// them. That means we need labels for them.
|
||||
@@ -612,6 +607,17 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
String pathId = basePathId;
|
||||
int pathIdTiebreaker = 2;
|
||||
boolean found = false;
|
||||
|
||||
Map<String, Map<String, String>> pathSetMap;
|
||||
|
||||
// The callback API is logically distinct from the main API, so
|
||||
// it uses a separate path set map.
|
||||
if (op.isCallbackRequest) {
|
||||
pathSetMap = this.callbacksPathSetMap;
|
||||
} else {
|
||||
pathSetMap = this.pathSetMap;
|
||||
}
|
||||
|
||||
while (pathSetMap.containsKey(pathId)) {
|
||||
Map<String, String> pathSetEntry = pathSetMap.get(pathId);
|
||||
if (pathSetEntry.get("path").equals(op.path)) {
|
||||
@@ -622,35 +628,94 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
pathIdTiebreaker++;
|
||||
}
|
||||
|
||||
// Save off the regular expression and path details in the
|
||||
boolean hasPathParams = !op.pathParams.isEmpty();
|
||||
|
||||
// String for matching for path using a regex
|
||||
// Don't prefix with '^' so that the templates can put the
|
||||
// basePath on the front.
|
||||
String regex = op.path;
|
||||
// String for formatting the path for a client to make a request
|
||||
String formatPath = op.path;
|
||||
|
||||
for (CodegenParameter param : op.pathParams) {
|
||||
// Replace {baseName} with {paramName} for format string
|
||||
String paramSearch = "{" + param.baseName + "}";
|
||||
String paramReplace = "{" + param.paramName + "}";
|
||||
|
||||
formatPath = formatPath.replace(paramSearch, paramReplace);
|
||||
}
|
||||
|
||||
// Handle runtime callback parameters. Runtime callback parameters
|
||||
// are different from regular path parameters:
|
||||
// - They begin with a "{$" sequence, which allows us to identify them.
|
||||
// - They can contain multiple path segments, so we need to use a different
|
||||
// regular expression.
|
||||
// - They may contain special characters such as "#", "." and "/" which aren't
|
||||
// valid in Rust identifiers.
|
||||
// In the future, we may support parsing them directly
|
||||
if (op.isCallbackRequest) {
|
||||
formatPath = formatPath.substring(1); // Callback paths are absolute so strip initial '/'
|
||||
|
||||
List<String> params = new ArrayList<String>();
|
||||
|
||||
Matcher match = Pattern.compile("\\{\\$[^}{]*\\}").matcher(op.path);
|
||||
|
||||
while (match.find()) {
|
||||
String param = match.group();
|
||||
|
||||
// Convert to a rust variable name
|
||||
String rustParam = tidyUpRuntimeCallbackParam(param);
|
||||
params.add(rustParam);
|
||||
|
||||
// Convert to a format arg
|
||||
String formatParam = "{" + rustParam + "}";
|
||||
|
||||
formatPath = formatPath.replace(param, formatParam);
|
||||
|
||||
// Convert to a regex
|
||||
String newParam = "(?P<" + rustParam + ">.*)";
|
||||
|
||||
regex = regex.replace(param, newParam);
|
||||
|
||||
hasPathParams = true;
|
||||
}
|
||||
|
||||
op.vendorExtensions.put("callbackParams", params);
|
||||
}
|
||||
|
||||
// Save off the regular expression and path details in the relevant
|
||||
// "pathSetMap", which we'll add to the source document that will be
|
||||
// processed by the templates.
|
||||
if (!found) {
|
||||
Map<String, String> pathSetEntry = new HashMap<String, String>();
|
||||
pathSetEntry.put("path", op.path);
|
||||
pathSetEntry.put("PATH_ID", pathId);
|
||||
if (!op.pathParams.isEmpty()) {
|
||||
|
||||
if (hasPathParams) {
|
||||
pathSetEntry.put("hasPathParams", "true");
|
||||
}
|
||||
|
||||
// Don't prefix with '^' so that the templates can put the
|
||||
// basePath on the front.
|
||||
String pathRegEx = op.path;
|
||||
for (CodegenParameter param : op.pathParams) {
|
||||
// Replace {baseName} with (?P<paramName>[^/?#]*) for regex
|
||||
// Replace {paramName} with (?P<paramName>[^/?#]*) for regex
|
||||
String paramSearch = "{" + param.baseName + "}";
|
||||
String paramReplace = "(?P<" + param.paramName + ">[^/?#]*)";
|
||||
|
||||
pathRegEx = pathRegEx.replace(paramSearch, paramReplace);
|
||||
regex = regex.replace(paramSearch, paramReplace);
|
||||
}
|
||||
|
||||
pathSetEntry.put("pathRegEx", pathRegEx + "$");
|
||||
pathSetEntry.put("pathRegEx", regex + "$");
|
||||
pathSetMap.put(pathId, pathSetEntry);
|
||||
}
|
||||
|
||||
op.vendorExtensions.put("operation_id", underscore(op.operationId));
|
||||
op.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
|
||||
op.vendorExtensions.put("path", op.path.replace("{", ":").replace("}", ""));
|
||||
op.vendorExtensions.put("x-path-format-string", formatPath);
|
||||
op.vendorExtensions.put("formatPath", formatPath);
|
||||
op.vendorExtensions.put("PATH_ID", pathId);
|
||||
op.vendorExtensions.put("hasPathParams", !op.pathParams.isEmpty());
|
||||
op.vendorExtensions.put("hasPathParams", hasPathParams);
|
||||
op.vendorExtensions.put("HttpMethod", op.httpMethod.toUpperCase(Locale.ROOT));
|
||||
for (CodegenParameter param : op.allParams) {
|
||||
processParam(param, op);
|
||||
@@ -866,98 +931,110 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
|
||||
for (CodegenOperation op : operationList) {
|
||||
boolean consumesPlainText = false;
|
||||
boolean consumesXml = false;
|
||||
postProcessOperationWithModels(op, allModels);
|
||||
}
|
||||
|
||||
if (op.consumes != null) {
|
||||
for (Map<String, String> consume : op.consumes) {
|
||||
if (consume.get("mediaType") != null) {
|
||||
String mediaType = consume.get("mediaType");
|
||||
return objs;
|
||||
}
|
||||
|
||||
if (isMimetypeXml(mediaType)) {
|
||||
additionalProperties.put("usesXml", true);
|
||||
consumesXml = true;
|
||||
} else if (isMimetypePlain(mediaType)) {
|
||||
consumesPlainText = true;
|
||||
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
|
||||
additionalProperties.put("usesUrlEncodedForm", true);
|
||||
} else if (isMimetypeMultipartFormData(mediaType)) {
|
||||
op.vendorExtensions.put("consumesMultipart", true);
|
||||
additionalProperties.put("apiUsesMultipartFormData", true);
|
||||
additionalProperties.put("apiUsesMultipart", true);
|
||||
} else if (isMimetypeMultipartRelated(mediaType)) {
|
||||
op.vendorExtensions.put("consumesMultipartRelated", true);
|
||||
additionalProperties.put("apiUsesMultipartRelated", true);
|
||||
additionalProperties.put("apiUsesMultipart", true);
|
||||
}
|
||||
private void postProcessOperationWithModels(CodegenOperation op, List<Object> allModels) {
|
||||
boolean consumesPlainText = false;
|
||||
boolean consumesXml = false;
|
||||
|
||||
if (op.consumes != null) {
|
||||
for (Map<String, String> consume : op.consumes) {
|
||||
if (consume.get("mediaType") != null) {
|
||||
String mediaType = consume.get("mediaType");
|
||||
|
||||
if (isMimetypeXml(mediaType)) {
|
||||
additionalProperties.put("usesXml", true);
|
||||
consumesXml = true;
|
||||
} else if (isMimetypePlain(mediaType)) {
|
||||
consumesPlainText = true;
|
||||
} else if (isMimetypeWwwFormUrlEncoded(mediaType)) {
|
||||
additionalProperties.put("usesUrlEncodedForm", true);
|
||||
} else if (isMimetypeMultipartFormData(mediaType)) {
|
||||
op.vendorExtensions.put("consumesMultipart", true);
|
||||
additionalProperties.put("apiUsesMultipartFormData", true);
|
||||
additionalProperties.put("apiUsesMultipart", true);
|
||||
} else if (isMimetypeMultipartRelated(mediaType)) {
|
||||
op.vendorExtensions.put("consumesMultipartRelated", true);
|
||||
additionalProperties.put("apiUsesMultipartRelated", true);
|
||||
additionalProperties.put("apiUsesMultipart", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op.bodyParam != null) {
|
||||
// Default to consuming json
|
||||
op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
|
||||
if (consumesXml) {
|
||||
op.bodyParam.vendorExtensions.put("consumesXml", true);
|
||||
} else if (consumesPlainText) {
|
||||
op.bodyParam.vendorExtensions.put("consumesPlainText", true);
|
||||
} else {
|
||||
op.bodyParam.vendorExtensions.put("consumesJson", true);
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter param : op.bodyParams) {
|
||||
processParam(param, op);
|
||||
|
||||
param.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
|
||||
|
||||
// Default to producing json if nothing else is specified
|
||||
if (consumesXml) {
|
||||
param.vendorExtensions.put("consumesXml", true);
|
||||
} else if (consumesPlainText) {
|
||||
param.vendorExtensions.put("consumesPlainText", true);
|
||||
} else {
|
||||
param.vendorExtensions.put("consumesJson", true);
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter param : op.formParams) {
|
||||
processParam(param, op);
|
||||
}
|
||||
|
||||
for (CodegenParameter header : op.headerParams) {
|
||||
header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
for (CodegenProperty header : op.responseHeaders) {
|
||||
if (header.dataType.equals(uuidType)) {
|
||||
additionalProperties.put("apiUsesUuid", true);
|
||||
}
|
||||
header.nameInCamelCase = toModelName(header.baseName);
|
||||
header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
if (op.authMethods != null) {
|
||||
boolean headerAuthMethods = false;
|
||||
|
||||
for (CodegenSecurity s : op.authMethods) {
|
||||
if (s.isApiKey && s.isKeyInHeader) {
|
||||
s.vendorExtensions.put("x-apiKeyName", toModelName(s.keyParamName));
|
||||
headerAuthMethods = true;
|
||||
}
|
||||
|
||||
if (s.isBasicBasic || s.isBasicBearer || s.isOAuth) {
|
||||
headerAuthMethods = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (headerAuthMethods) {
|
||||
op.vendorExtensions.put("hasHeaderAuthMethods", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return objs;
|
||||
if (op.bodyParam != null) {
|
||||
// Default to consuming json
|
||||
op.bodyParam.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
|
||||
if (consumesXml) {
|
||||
op.bodyParam.vendorExtensions.put("consumesXml", true);
|
||||
} else if (consumesPlainText) {
|
||||
op.bodyParam.vendorExtensions.put("consumesPlainText", true);
|
||||
} else {
|
||||
op.bodyParam.vendorExtensions.put("consumesJson", true);
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter param : op.bodyParams) {
|
||||
processParam(param, op);
|
||||
|
||||
param.vendorExtensions.put("uppercase_operation_id", underscore(op.operationId).toUpperCase(Locale.ROOT));
|
||||
|
||||
// Default to producing json if nothing else is specified
|
||||
if (consumesXml) {
|
||||
param.vendorExtensions.put("consumesXml", true);
|
||||
} else if (consumesPlainText) {
|
||||
param.vendorExtensions.put("consumesPlainText", true);
|
||||
} else {
|
||||
param.vendorExtensions.put("consumesJson", true);
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter param : op.formParams) {
|
||||
processParam(param, op);
|
||||
}
|
||||
|
||||
for (CodegenParameter header : op.headerParams) {
|
||||
header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
for (CodegenProperty header : op.responseHeaders) {
|
||||
if (header.dataType.equals(uuidType)) {
|
||||
additionalProperties.put("apiUsesUuid", true);
|
||||
}
|
||||
header.nameInCamelCase = toModelName(header.baseName);
|
||||
header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
if (op.authMethods != null) {
|
||||
boolean headerAuthMethods = false;
|
||||
|
||||
for (CodegenSecurity s : op.authMethods) {
|
||||
if (s.isApiKey && s.isKeyInHeader) {
|
||||
s.vendorExtensions.put("x-apiKeyName", toModelName(s.keyParamName));
|
||||
headerAuthMethods = true;
|
||||
}
|
||||
|
||||
if (s.isBasicBasic || s.isBasicBearer || s.isOAuth) {
|
||||
headerAuthMethods = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (headerAuthMethods) {
|
||||
op.vendorExtensions.put("hasHeaderAuthMethods", "true");
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenCallback callback : op.callbacks) {
|
||||
for (CodegenCallback.Url url : callback.urls) {
|
||||
for (CodegenOperation innerOp : url.requests) {
|
||||
postProcessOperationWithModels(innerOp, allModels);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1152,9 +1229,43 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
|
||||
generateYAMLSpecFile(objs);
|
||||
public Map<String, Object> postProcessSupportingFileData(Map<String, Object> bundle) {
|
||||
generateYAMLSpecFile(bundle);
|
||||
|
||||
addPathSetMapToBundle(pathSetMap, bundle);
|
||||
|
||||
// If we have callbacks, add the callbacks module, otherwise remove it
|
||||
boolean hasCallbacks = haveCallbacks(bundle);
|
||||
bundle.put("hasCallbacks", hasCallbacks);
|
||||
SupportingFile[] callbackFiles = new SupportingFile[] {
|
||||
new SupportingFile("client-callbacks.mustache", "src/client", "callbacks.rs"),
|
||||
new SupportingFile("server-callbacks.mustache", "src/server", "callbacks.rs"),
|
||||
new SupportingFile("example-client-server.mustache", "examples/client", "server.rs")
|
||||
};
|
||||
for (SupportingFile callbackFile : callbackFiles) {
|
||||
if (hasCallbacks) {
|
||||
supportingFiles.add(callbackFile);
|
||||
} else {
|
||||
supportingFiles.remove(callbackFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCallbacks) {
|
||||
Map<String, Object> callbackData = new HashMap();
|
||||
addPathSetMapToBundle(callbacksPathSetMap, callbackData);
|
||||
bundle.put("callbacks", callbackData);
|
||||
}
|
||||
|
||||
return super.postProcessSupportingFileData(bundle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a built path set map to the provided bundle
|
||||
*
|
||||
* @param pathSetMap A previously built path set map
|
||||
* @param bundle Bundle for the supporting files to add the data to.
|
||||
*/
|
||||
private static void addPathSetMapToBundle(Map<String, Map<String, String>> pathSetMap, Map<String, Object> bundle) {
|
||||
// We previously built a mapping from path to path ID and regular
|
||||
// expression - see fromOperation for details. Sort it and add an
|
||||
// index, and then add it to the objects that we're about to pass to
|
||||
@@ -1173,9 +1284,30 @@ public class RustServerCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
index++;
|
||||
pathSet.add(pathSetEntryValue);
|
||||
}
|
||||
objs.put("pathSet", pathSet);
|
||||
bundle.put("pathSet", pathSet);
|
||||
}
|
||||
|
||||
return super.postProcessSupportingFileData(objs);
|
||||
/**
|
||||
* Does the API being generated use callbacks?
|
||||
*
|
||||
* @param bundle Bundle data from DefaultGenerator which will be passed to the templates
|
||||
* @return true if any operation has a callback, false otherwise
|
||||
*/
|
||||
private static boolean haveCallbacks(Map<String, Object> bundle) {
|
||||
Map<String, Object> apiInfo = (Map<String, Object>) bundle.get("apiInfo");
|
||||
List<Object> apis = (List<Object>) apiInfo.get("apis");
|
||||
for (Object api : apis) {
|
||||
Map<String, Object> apiData = (Map<String, Object>) api;
|
||||
Map<String, Object> opss = (Map<String, Object>) apiData.get("operations");
|
||||
List<CodegenOperation> ops = (List<CodegenOperation>) opss.get("operation");
|
||||
for (CodegenOperation op : ops) {
|
||||
if (!op.callbacks.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,9 @@ client = [
|
||||
{{#usesUrlEncodedForm}}
|
||||
"serde_urlencoded",
|
||||
{{/usesUrlEncodedForm}}
|
||||
{{#hasCallbacks}}
|
||||
"tokio-tls", "regex", "percent-encoding", "lazy_static",
|
||||
{{/hasCallbacks}}
|
||||
"serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio", "url"
|
||||
]
|
||||
server = [
|
||||
@@ -34,6 +37,7 @@ server = [
|
||||
{{#apiUsesMultipartRelated}}
|
||||
"hyper_0_10", "mime_multipart",
|
||||
{{/apiUsesMultipartRelated}}
|
||||
{{! Anything added to the list below, should probably be added to the callbacks list above }}
|
||||
"serde_json", "serde_ignored", "hyper", "native-tls", "openssl", "tokio", "tokio-tls", "regex", "percent-encoding", "url", "lazy_static"
|
||||
]
|
||||
conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"]
|
||||
@@ -84,7 +88,7 @@ url = {version = "1.5", optional = true}
|
||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
||||
{{/usesUrlEncodedForm}}
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -100,8 +104,9 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
env_logger = "0.6"
|
||||
{{^apiUsesUuid}}
|
||||
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||
uuid = {version = "0.7", features = ["serde", "v4"]}
|
||||
{{/apiUsesUuid}}
|
||||
|
||||
[[example]]
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# Rust Server Generator Templates
|
||||
|
||||
The Rust Server Generator templates use Mustache Partials.
|
||||
|
||||
The following tree shows which templates include which:
|
||||
|
||||
- `api_doc.mustache`
|
||||
- `cargo-config`
|
||||
- `Cargo.mustache`
|
||||
- `context.mustache`
|
||||
- `client-callbacks-mod.mustache`
|
||||
- `server-imports.mustache`
|
||||
- `server-make-service.mustache`
|
||||
- `server-service-footer.mustache`
|
||||
- `server-service-header.mustache`
|
||||
- `server-operation.mustache`
|
||||
- `client-mod.mustache`
|
||||
- `client-imports.mustache`
|
||||
- `client-operation.mustache`
|
||||
- `example-ca.pem`
|
||||
- `example-client-main.mustache`
|
||||
- `example-client-server.mustache`
|
||||
- `example-server-chain.pem`
|
||||
- `example-server-common.mustache`
|
||||
- `example-server-key.pem`
|
||||
- `example-server-main.mustache`
|
||||
- `example-server-server.mustache`
|
||||
- `example-server-operation.mustache`
|
||||
- `gitignore`
|
||||
- `header.mustache`
|
||||
- `lib.mustache`
|
||||
- `response.mustache`
|
||||
- `mimetypes.mustache`
|
||||
- `mimetypes-request.mustache`
|
||||
- `mimetypes-response.mustache`
|
||||
- `model_doc.mustache`
|
||||
- `models.mustache`
|
||||
- `openapi.mustache`
|
||||
- `README.mustache`
|
||||
- `server-callbacks.mustache`
|
||||
- `client-imports.mustache`
|
||||
- `client-operation.mustache`
|
||||
- `server-service-header.mustache`
|
||||
- `server-mod.mustache`
|
||||
- `server-imports.mustache`
|
||||
- `server-make-service.mustache`
|
||||
- `server-service-footer.mustache`
|
||||
- `server-service-header.mustache`
|
||||
- `server-operation.mustache`
|
||||
- `server-paths.mustache`
|
||||
@@ -62,8 +62,20 @@ cargo run --example server
|
||||
### Running the example client
|
||||
To run a client, follow one of the following simple steps:
|
||||
|
||||
```{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
cargo run --example client {{{operationId}}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
```
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#vendorExtensions}}
|
||||
{{^noClientExample}}
|
||||
cargo run --example client {{{operationId}}}
|
||||
{{/noClientExample}}
|
||||
{{/vendorExtensions}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
```
|
||||
|
||||
### HTTPS
|
||||
|
||||
67
modules/openapi-generator/src/main/resources/rust-server/client-callbacks.mustache
vendored
Normal file
67
modules/openapi-generator/src/main/resources/rust-server/client-callbacks.mustache
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
{{>server-imports}}
|
||||
use CallbackApi as Api;
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
use {{{operationId}}}Response;
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
{{#callbacks}}
|
||||
{{>server-paths}}
|
||||
{{/callbacks}}
|
||||
|
||||
{{>server-make-service}}
|
||||
|
||||
{{>server-service-header}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>server-operation}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
{{>server-service-footer}}
|
||||
/// Request parser for `Api`.
|
||||
pub struct ApiRequestParser;
|
||||
impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
|
||||
&hyper::Method::{{{vendorExtensions.HttpMethod}}} if path.matched(paths::ID_{{{vendorExtensions.PATH_ID}}}) => Ok("{{{operationId}}}"),
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
53
modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache
vendored
Normal file
53
modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
use futures;
|
||||
use futures::{Future, Stream, future, stream};
|
||||
use hyper;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use hyper::{Body, Uri, Response};
|
||||
use hyper_tls::HttpsConnector;
|
||||
use serde_json;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::io::{Read, Error, ErrorKind};
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
use swagger;
|
||||
use swagger::client::Service;
|
||||
use swagger::connector;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
{{#apiUsesMultipartFormData}}
|
||||
use mime::Mime;
|
||||
use std::io::Cursor;
|
||||
use multipart::client::lazy::Multipart;
|
||||
{{/apiUsesMultipartFormData}}
|
||||
{{#apiUsesMultipartRelated}}
|
||||
use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_multipart::{Node, Part, generate_boundary, write_multipart};
|
||||
{{/apiUsesMultipartRelated}}
|
||||
{{#apiUsesUuid}}
|
||||
use uuid;
|
||||
{{/apiUsesUuid}}
|
||||
{{#usesXml}}
|
||||
use serde_xml_rs;
|
||||
{{/usesXml}}
|
||||
|
||||
use mimetypes;
|
||||
use models;
|
||||
use header;
|
||||
|
||||
define_encode_set! {
|
||||
/// This encode set is used for object IDs
|
||||
///
|
||||
/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`,
|
||||
/// the vertical bar (|) is encoded.
|
||||
pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
|
||||
}
|
||||
@@ -1,63 +1,12 @@
|
||||
use hyper;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use hyper::{Body, Uri, Response};
|
||||
use hyper_tls::HttpsConnector;
|
||||
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
use futures;
|
||||
use futures::{Future, Stream};
|
||||
use futures::{future, stream};
|
||||
use serde_json;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::io::{Read, Error, ErrorKind};
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use swagger::client::Service;
|
||||
|
||||
{{#apiUsesMultipartFormData}}
|
||||
use mime::Mime;
|
||||
use std::io::Cursor;
|
||||
use multipart::client::lazy::Multipart;
|
||||
{{/apiUsesMultipartFormData}}
|
||||
{{#apiUsesMultipartRelated}}
|
||||
use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_multipart::{Node, Part, generate_boundary, write_multipart};
|
||||
{{/apiUsesMultipartRelated}}
|
||||
{{#apiUsesUuid}}
|
||||
use uuid;
|
||||
{{/apiUsesUuid}}
|
||||
{{#usesXml}}
|
||||
use serde_xml_rs;
|
||||
{{/usesXml}}
|
||||
|
||||
{{>client-imports}}
|
||||
use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
|
||||
use mimetypes;
|
||||
use models;
|
||||
use header;
|
||||
|
||||
define_encode_set! {
|
||||
/// This encode set is used for object IDs
|
||||
///
|
||||
/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`,
|
||||
/// the vertical bar (|) is encoded.
|
||||
pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
|
||||
}
|
||||
{{#hasCallbacks}}
|
||||
pub mod callbacks;
|
||||
|
||||
{{/hasCallbacks}}
|
||||
/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes.
|
||||
fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> {
|
||||
// First convert to Uri, since a base path is a subset of Uri.
|
||||
@@ -80,7 +29,10 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<S
|
||||
/// A client that implements the API by making HTTP calls out to a server.
|
||||
pub struct Client<F>
|
||||
{
|
||||
/// Inner service
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
|
||||
/// Base path of the API
|
||||
base_path: String,
|
||||
}
|
||||
|
||||
@@ -144,7 +96,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
pub fn try_new_http(
|
||||
base_path: &str,
|
||||
) -> Result<Self, ClientInitError> {
|
||||
let http_connector = swagger::http_connector();
|
||||
let http_connector = connector::http_connector();
|
||||
|
||||
Self::try_new_with_connector(base_path, Some("http"), http_connector)
|
||||
}
|
||||
@@ -161,7 +113,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
where
|
||||
CA: AsRef<Path>,
|
||||
{
|
||||
let https_connector = swagger::https_connector(ca_certificate);
|
||||
let https_connector = connector::https_connector(ca_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
|
||||
@@ -184,14 +136,14 @@ impl Client<hyper::client::ResponseFuture>
|
||||
D: AsRef<Path>,
|
||||
{
|
||||
let https_connector =
|
||||
swagger::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
connector::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Client<F>
|
||||
{
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::client::Service`
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
|
||||
///
|
||||
/// This allows adding custom wrappers around the underlying transport, for example for logging.
|
||||
pub fn try_new_with_client_service(
|
||||
@@ -205,452 +157,19 @@ impl<F> Client<F>
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> Api<C> for Client<F> where
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}},
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send> {
|
||||
let mut uri = format!(
|
||||
"{}{{{basePathWithoutHost}}}{{{vendorExtensions.x-path-format-string}}}",
|
||||
self.base_path{{#pathParams}}, {{{paramName}}}=utf8_percent_encode(¶m_{{{paramName}}}.to_string(), ID_ENCODE_SET){{/pathParams}}
|
||||
);
|
||||
|
||||
// Query parameters
|
||||
let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
|
||||
{{#queryParams}}
|
||||
{{^required}}
|
||||
if let Some(param_{{{paramName}}}) = param_{{{paramName}}} {
|
||||
{{/required}}
|
||||
query_string.append_pair("{{{baseName}}}", ¶m_{{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#authMethods}}
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInQuery}}
|
||||
if let Some(auth_data) = (context as &dyn Has<Option<AuthData>>).get().as_ref() {
|
||||
if let AuthData::ApiKey(ref api_key) = *auth_data {
|
||||
query_string.append_pair("{{keyParamName}}", api_key);
|
||||
}
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
let query_string_str = query_string.finish();
|
||||
if !query_string_str.is_empty() {
|
||||
uri += "?";
|
||||
uri += &query_string_str;
|
||||
}
|
||||
|
||||
let uri = match Uri::from_str(&uri) {
|
||||
Ok(uri) => uri,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
|
||||
};
|
||||
|
||||
let mut request = match hyper::Request::builder()
|
||||
.method("{{{vendorExtensions.HttpMethod}}}")
|
||||
.uri(uri)
|
||||
.body(Body::empty()) {
|
||||
Ok(req) => req,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
let mut multipart = Multipart::new();
|
||||
|
||||
{{#vendorExtensions}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// For each parameter, encode as appropriate and add to the multipart body as a stream.
|
||||
{{/-first}}
|
||||
{{^isByteArray}}
|
||||
{{#jsonSchema}}
|
||||
|
||||
let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) {
|
||||
Ok(str) => str,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e)))),
|
||||
};
|
||||
|
||||
let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec();
|
||||
|
||||
let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse");
|
||||
|
||||
let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
|
||||
|
||||
multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime));
|
||||
{{/jsonSchema}}
|
||||
{{/isByteArray}}
|
||||
{{#isByteArray}}
|
||||
|
||||
let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec();
|
||||
|
||||
let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") {
|
||||
Ok(mime) => mime,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to get mime type: {:?}", err)))),
|
||||
};
|
||||
|
||||
let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
|
||||
|
||||
let filename = None as Option<&str> ;
|
||||
multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime));
|
||||
{{/isByteArray}}
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
|
||||
let mut fields = match multipart.prepare() {
|
||||
Ok(fields) => fields,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))),
|
||||
};
|
||||
|
||||
let mut body_string = String::new();
|
||||
match fields.read_to_string(&mut body_string) {
|
||||
Ok(_) => (),
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build body: {}", err)))),
|
||||
}
|
||||
let boundary = fields.boundary();
|
||||
|
||||
let multipart_header = format!("multipart/form-data;boundary={}", boundary);
|
||||
|
||||
*request.body_mut() = Body::from(body_string);
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))))
|
||||
});
|
||||
{{/consumesMultipart}}
|
||||
{{^consumesMultipart}}
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipartRelated}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
let params = &[
|
||||
{{/-first}}
|
||||
("{{{baseName}}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}format!("{:?}", param_{{{paramName}}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}param_{{{paramName}}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}),{{/vendorExtensions}}
|
||||
{{#-last}}
|
||||
];
|
||||
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
*request.body_mut() = Body::from(body.into_bytes());
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{#consumesMultipartRelated}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// Construct the Body for a multipart/related request. The mime 0.2.6 library
|
||||
// does not parse quoted-string parameters correctly. The boundary doesn't
|
||||
// need to be a quoted string if it does not contain a '/', hence ensure
|
||||
// no such boundary is used.
|
||||
let mut boundary = generate_boundary();
|
||||
for b in boundary.iter_mut() {
|
||||
if b == &('/' as u8) {
|
||||
*b = '=' as u8;
|
||||
}
|
||||
}
|
||||
|
||||
let mut body_parts = vec![];
|
||||
{{/-first}}
|
||||
|
||||
{{^required}}
|
||||
if let Some({{{paramName}}}) = param_{{{paramName}}} {
|
||||
{{/required}}
|
||||
let part = Node::Part(Part {
|
||||
headers: {
|
||||
let mut h = Headers::new();
|
||||
h.set(ContentType("{{{contentType}}}".parse().unwrap()));
|
||||
h.set(ContentId("{{{baseName}}}".parse().unwrap()));
|
||||
h
|
||||
},
|
||||
{{#isBinary}}
|
||||
body: {{#required}}param_{{/required}}{{{paramName}}}.0,
|
||||
{{/isBinary}}
|
||||
{{^isBinary}}
|
||||
body: serde_json::to_string(&{{{paramName}}})
|
||||
.expect("Impossible to fail to serialize")
|
||||
.into_bytes(),
|
||||
{{/isBinary}}
|
||||
});
|
||||
body_parts.push(part);
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
{{#-last}}
|
||||
|
||||
// Write the body into a vec.
|
||||
let mut body: Vec<u8> = vec![];
|
||||
write_multipart(&mut body, &boundary, &body_parts)
|
||||
.expect("Failed to write multipart body");
|
||||
|
||||
// Add the message body to the request object.
|
||||
*request.body_mut() = Body::from(body);
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE,
|
||||
match HeaderValue::from_bytes(
|
||||
&[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat()
|
||||
) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
{{#bodyParam}}
|
||||
{{#-first}}
|
||||
// Body parameter
|
||||
{{/-first}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesPlainText}}
|
||||
{{#isByteArray}}
|
||||
let body = param_{{{paramName}}}.0;
|
||||
{{/isByteArray}}
|
||||
{{^isByteArray}}
|
||||
let body = param_{{{paramName}}};
|
||||
{{/isByteArray}}
|
||||
{{/consumesPlainText}}
|
||||
{{#required}}
|
||||
{{#consumesXml}}
|
||||
let body = param_{{{paramName}}}.to_xml();
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize");
|
||||
{{/consumesJson}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let body = param_{{{paramName}}}.map(|ref body| {
|
||||
{{#consumesXml}}
|
||||
body.to_xml()
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
serde_json::to_string(body).expect("impossible to fail to serialize")
|
||||
{{/consumesJson}}
|
||||
});
|
||||
{{/required}}
|
||||
{{/vendorExtensions}}
|
||||
{{^required}}
|
||||
if let Some(body) = body {
|
||||
{{/required}}
|
||||
*request.body_mut() = Body::from(body);
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
{{/bodyParam}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
{{#vendorExtensions.hasHeaderAuthMethods}}
|
||||
if let Some(auth_data) = (context as &dyn Has<Option<AuthData>>).get().as_ref() {
|
||||
// Currently only authentication with Basic, API Key, and Bearer are supported
|
||||
match auth_data {
|
||||
{{#authMethods}}
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInHeader}}
|
||||
&AuthData::ApiKey(ref api_key) => {
|
||||
let header = match HeaderValue::from_str(&format!("{}", api_key)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create {{ vendorExtensions.x-apiKeyName }} header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
"{{vendorExtensions.x-apiKeyName}}",
|
||||
header);
|
||||
},
|
||||
{{/isKeyInHeader}}
|
||||
{{/isApiKey}}
|
||||
{{#isBasicBasic}}
|
||||
&AuthData::Basic(ref basic_header) => {
|
||||
let auth = swagger::auth::Header(basic_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
&AuthData::Bearer(ref bearer_header) => {
|
||||
let auth = swagger::auth::Header(bearer_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBearer}}
|
||||
{{#isOAuth}}
|
||||
{{^isBasicBearer}}
|
||||
&AuthData::Bearer(ref bearer_header) => {
|
||||
let auth = swagger::auth::Header(bearer_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBearer}}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
{{/vendorExtensions.hasHeaderAuthMethods}}
|
||||
{{#headerParams}}
|
||||
{{#-first}}
|
||||
|
||||
// Header parameters
|
||||
{{/-first}}
|
||||
{{^isMapContainer}}
|
||||
{{#required}}
|
||||
request.headers_mut().append(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue(param_{{{paramName}}}.clone()).into());
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
param_{{{paramName}}}.map(|value| request.headers_mut().append(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue(value.clone()).into()));
|
||||
{{/required}}
|
||||
{{/isMapContainer}}
|
||||
{{#isMapContainer}}
|
||||
let param_{{{paramName}}}: Option<{{{dataType}}}> = None;
|
||||
{{/isMapContainer}}
|
||||
{{/headerParams}}
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
match response.status().as_u16() {
|
||||
{{#responses}}
|
||||
{{{code}}} => {
|
||||
{{#headers}}
|
||||
let response_{{{name}}} = match response.headers().get(HeaderName::from_static("{{{nameInLowerCase}}}")) {
|
||||
Some(response_{{{name}}}) => response_{{{name}}}.clone(),
|
||||
None => return Box::new(future::err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found.")))) as Box<dyn Future<Item=_, Error=_> + Send>,
|
||||
};
|
||||
{{/headers}}
|
||||
let body = response.into_body();
|
||||
Box::new(
|
||||
{{#dataType}}
|
||||
body
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
{{#vendorExtensions}}
|
||||
{{#producesBytes}}
|
||||
Ok(swagger::ByteArray(body.to_vec()))
|
||||
{{/producesBytes}}
|
||||
{{^producesBytes}}
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
{{#producesXml}}
|
||||
// ToDo: this will move to swagger-rs and become a standard From conversion trait
|
||||
// once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
||||
serde_xml_rs::from_str::<{{{dataType}}}>(body)
|
||||
.map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))
|
||||
{{/producesXml}}
|
||||
{{#producesJson}}
|
||||
serde_json::from_str::<{{{dataType}}}>(body)
|
||||
.map_err(|e| e.into())
|
||||
{{/producesJson}}
|
||||
{{#producesPlainText}}
|
||||
Ok(body.to_string())
|
||||
{{/producesPlainText}}
|
||||
)
|
||||
{{/producesBytes}}
|
||||
{{/vendorExtensions}}
|
||||
)
|
||||
.map(move |body| {
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{^headers}}
|
||||
(body)
|
||||
{{/headers}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
body: body,
|
||||
{{/-first}}
|
||||
{{{name}}}: (*Into::<header::IntoHeaderValue<{{{dataType}}}>>::into(response_{{{name}}})).clone(),
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
})
|
||||
{{/dataType}}
|
||||
{{^dataType}}
|
||||
future::ok(
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
{{/-first}}
|
||||
{{{name}}}: (*Into::<header::IntoHeaderValue<{{{dataType}}}>>::into(response_{{{name}}})).clone(),
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
)
|
||||
{{/dataType}}
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
},
|
||||
{{/responses}}
|
||||
code => {
|
||||
let headers = response.headers().clone();
|
||||
Box::new(response.into_body()
|
||||
.take(100)
|
||||
.concat2()
|
||||
.then(move |body|
|
||||
future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
|
||||
code,
|
||||
headers,
|
||||
match body {
|
||||
Ok(ref body) => match str::from_utf8(body) {
|
||||
Ok(body) => Cow::from(body),
|
||||
Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
|
||||
},
|
||||
Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
|
||||
})))
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
/// Error type failing to create a Client
|
||||
#[derive(Debug)]
|
||||
pub enum ClientInitError {
|
||||
/// Invalid URL Scheme
|
||||
InvalidScheme,
|
||||
|
||||
/// Invalid URI
|
||||
InvalidUri(hyper::http::uri::InvalidUri),
|
||||
|
||||
/// Missing Hostname
|
||||
MissingHost,
|
||||
|
||||
/// SSL Connection Error
|
||||
SslError(openssl::error::ErrorStack)
|
||||
}
|
||||
|
||||
@@ -668,7 +187,8 @@ impl From<openssl::error::ErrorStack> for ClientInitError {
|
||||
|
||||
impl fmt::Display for ClientInitError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(self as &dyn fmt::Debug).fmt(f)
|
||||
let s: &dyn fmt::Debug = self;
|
||||
s.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,3 +197,18 @@ impl error::Error for ClientInitError {
|
||||
"Failed to produce a hyper client."
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> Api<C> for Client<F> where
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}},
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>client-operation}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
450
modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache
vendored
Normal file
450
modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}}: String,
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
{{#isCallbackRequest}}
|
||||
"{{vendorExtensions.x-path-format-string}}"
|
||||
{{/isCallbackRequest}}
|
||||
{{^isCallbackRequest}}
|
||||
"{}{{{basePathWithoutHost}}}{{vendorExtensions.x-path-format-string}}",
|
||||
self.base_path
|
||||
{{/isCallbackRequest}}
|
||||
{{#pathParams}}
|
||||
,{{{paramName}}}=utf8_percent_encode(¶m_{{{paramName}}}.to_string(), ID_ENCODE_SET)
|
||||
{{/pathParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
,{{.}}=callback_{{.}}
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
);
|
||||
|
||||
// Query parameters
|
||||
let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
|
||||
{{#queryParams}}
|
||||
{{^required}}
|
||||
if let Some(param_{{{paramName}}}) = param_{{{paramName}}} {
|
||||
{{/required}}
|
||||
query_string.append_pair("{{{baseName}}}", ¶m_{{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
{{/queryParams}}
|
||||
{{#authMethods}}
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInQuery}}
|
||||
if let Some(auth_data) = (context as &dyn Has<Option<AuthData>>).get().as_ref() {
|
||||
if let AuthData::ApiKey(ref api_key) = *auth_data {
|
||||
query_string.append_pair("{{keyParamName}}", api_key);
|
||||
}
|
||||
}
|
||||
{{/isKeyInQuery}}
|
||||
{{/isApiKey}}
|
||||
{{/authMethods}}
|
||||
let query_string_str = query_string.finish();
|
||||
if !query_string_str.is_empty() {
|
||||
uri += "?";
|
||||
uri += &query_string_str;
|
||||
}
|
||||
|
||||
let uri = match Uri::from_str(&uri) {
|
||||
Ok(uri) => uri,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
|
||||
};
|
||||
|
||||
let mut request = match hyper::Request::builder()
|
||||
.method("{{{vendorExtensions.HttpMethod}}}")
|
||||
.uri(uri)
|
||||
.body(Body::empty()) {
|
||||
Ok(req) => req,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
let mut multipart = Multipart::new();
|
||||
|
||||
{{#vendorExtensions}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// For each parameter, encode as appropriate and add to the multipart body as a stream.
|
||||
{{/-first}}
|
||||
|
||||
{{^isByteArray}}
|
||||
{{#jsonSchema}}
|
||||
let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) {
|
||||
Ok(str) => str,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to parse {{{paramName}}} to string: {}", e)))),
|
||||
};
|
||||
|
||||
let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec();
|
||||
|
||||
let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse");
|
||||
|
||||
let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
|
||||
|
||||
multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime));
|
||||
{{/jsonSchema}}
|
||||
{{/isByteArray}}
|
||||
{{#isByteArray}}
|
||||
let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec();
|
||||
|
||||
let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") {
|
||||
Ok(mime) => mime,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to get mime type: {:?}", err)))),
|
||||
};
|
||||
|
||||
let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec);
|
||||
|
||||
let filename = None as Option<&str> ;
|
||||
multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime));
|
||||
{{/isByteArray}}
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
let mut fields = match multipart.prepare() {
|
||||
Ok(fields) => fields,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))),
|
||||
};
|
||||
|
||||
let mut body_string = String::new();
|
||||
match fields.read_to_string(&mut body_string) {
|
||||
Ok(_) => (),
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build body: {}", err)))),
|
||||
}
|
||||
let boundary = fields.boundary();
|
||||
|
||||
let multipart_header = format!("multipart/form-data;boundary={}", boundary);
|
||||
|
||||
*request.body_mut() = Body::from(body_string);
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))))
|
||||
});
|
||||
|
||||
{{/consumesMultipart}}
|
||||
{{^consumesMultipart}}
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipartRelated}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
let params = &[
|
||||
{{/-first}}
|
||||
("{{{baseName}}}", {{#vendorExtensions}}{{#required}}Some({{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}format!("{:?}", param_{{{paramName}}}){{/isString}}){{/required}}{{^required}}{{#isString}}param_{{{paramName}}}{{/isString}}{{^isString}}param_{{{paramName}}}.map(|param| format!("{:?}", param)){{/isString}}{{/required}}{{/vendorExtensions}}),
|
||||
{{#-last}}
|
||||
];
|
||||
let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize");
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
*request.body_mut() = Body::from(body.into_bytes());
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{#consumesMultipartRelated}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// Construct the Body for a multipart/related request. The mime 0.2.6 library
|
||||
// does not parse quoted-string parameters correctly. The boundary doesn't
|
||||
// need to be a quoted string if it does not contain a '/', hence ensure
|
||||
// no such boundary is used.
|
||||
let mut boundary = generate_boundary();
|
||||
for b in boundary.iter_mut() {
|
||||
if b == &('/' as u8) {
|
||||
*b = '=' as u8;
|
||||
}
|
||||
}
|
||||
|
||||
let mut body_parts = vec![];
|
||||
{{/-first}}
|
||||
|
||||
{{#required}}
|
||||
{
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
if let Some({{{paramName}}}) = param_{{{paramName}}} {
|
||||
{{/required}}
|
||||
let part = Node::Part(Part {
|
||||
headers: {
|
||||
let mut h = Headers::new();
|
||||
h.set(ContentType("{{{contentType}}}".parse().unwrap()));
|
||||
h.set(ContentId("{{{baseName}}}".parse().unwrap()));
|
||||
h
|
||||
},
|
||||
{{#isBinary}}
|
||||
body: {{#required}}param_{{/required}}{{{paramName}}}.0,
|
||||
{{/isBinary}}
|
||||
{{^isBinary}}
|
||||
body: serde_json::to_string(&{{{paramName}}})
|
||||
.expect("Impossible to fail to serialize")
|
||||
.into_bytes(),
|
||||
{{/isBinary}}
|
||||
});
|
||||
body_parts.push(part);
|
||||
}
|
||||
{{#-last}}
|
||||
|
||||
// Write the body into a vec.
|
||||
let mut body: Vec<u8> = vec![];
|
||||
write_multipart(&mut body, &boundary, &body_parts)
|
||||
.expect("Failed to write multipart body");
|
||||
|
||||
// Add the message body to the request object.
|
||||
*request.body_mut() = Body::from(body);
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE,
|
||||
match HeaderValue::from_bytes(
|
||||
&[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat()
|
||||
) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
{{#bodyParam}}
|
||||
{{#-first}}
|
||||
// Body parameter
|
||||
{{/-first}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesPlainText}}
|
||||
{{#isByteArray}}
|
||||
let body = param_{{{paramName}}}.0;
|
||||
{{/isByteArray}}
|
||||
{{^isByteArray}}
|
||||
let body = param_{{{paramName}}};
|
||||
{{/isByteArray}}
|
||||
{{/consumesPlainText}}
|
||||
{{#required}}
|
||||
{{#consumesXml}}
|
||||
let body = param_{{{paramName}}}.to_xml();
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize");
|
||||
{{/consumesJson}}
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let body = param_{{{paramName}}}.map(|ref body| {
|
||||
{{#consumesXml}}
|
||||
body.to_xml()
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
serde_json::to_string(body).expect("impossible to fail to serialize")
|
||||
{{/consumesJson}}
|
||||
});
|
||||
{{/required}}
|
||||
{{/vendorExtensions}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/bodyParam}}
|
||||
{{#bodyParam}}
|
||||
{{^required}}
|
||||
if let Some(body) = body {
|
||||
{{/required}}
|
||||
*request.body_mut() = Body::from(body);
|
||||
{{^required}}
|
||||
}
|
||||
{{/required}}
|
||||
|
||||
let header = &mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}};
|
||||
request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/bodyParam}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
{{#hasAuthMethods}}
|
||||
if let Some(auth_data) = (context as &dyn Has<Option<AuthData>>).get().as_ref() {
|
||||
// Currently only authentication with Basic and Bearer are supported
|
||||
match auth_data {
|
||||
{{#authMethods}}
|
||||
{{#isBasicBasic}}
|
||||
&AuthData::Basic(ref basic_header) => {
|
||||
let auth = swagger::auth::Header(basic_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBasic}}
|
||||
{{#isBasicBearer}}
|
||||
&AuthData::Bearer(ref bearer_header) => {
|
||||
let auth = swagger::auth::Header(bearer_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBearer}}
|
||||
{{#isOAuth}}
|
||||
{{^isBasicBearer}}
|
||||
&AuthData::Bearer(ref bearer_header) => {
|
||||
let auth = swagger::auth::Header(bearer_header.clone());
|
||||
let header = match HeaderValue::from_str(&format!("{}", auth)) {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create Authorization header: {}", e))))
|
||||
};
|
||||
request.headers_mut().insert(
|
||||
hyper::header::AUTHORIZATION,
|
||||
header);
|
||||
},
|
||||
{{/isBasicBearer}}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
{{/hasAuthMethods}}
|
||||
{{#headerParams}}
|
||||
{{#-first}}
|
||||
// Header parameters
|
||||
{{/-first}}
|
||||
{{^isMapContainer}}
|
||||
{{#required}}
|
||||
request.headers_mut().append(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue(param_{{{paramName}}}.clone()).into());
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
param_{{{paramName}}}.map(|value| request.headers_mut().append(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue(value.clone()).into()));
|
||||
{{/required}}
|
||||
{{/isMapContainer}}
|
||||
{{#isMapContainer}}
|
||||
let param_{{{paramName}}}: Option<{{{dataType}}}> = None;
|
||||
{{/isMapContainer}}
|
||||
|
||||
{{/headerParams}}
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
match response.status().as_u16() {
|
||||
{{#responses}}
|
||||
{{{code}}} => {
|
||||
{{#headers}}
|
||||
let response_{{{name}}} = match response.headers().get(HeaderName::from_static("{{{nameInLowerCase}}}")) {
|
||||
Some(response_{{{name}}}) => response_{{{name}}}.clone(),
|
||||
None => return Box::new(future::err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found.")))) as Box<dyn Future<Item=_, Error=_> + Send>,
|
||||
};
|
||||
{{/headers}}
|
||||
let body = response.into_body();
|
||||
Box::new(
|
||||
{{#dataType}}
|
||||
body
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
{{#vendorExtensions}}
|
||||
{{#producesBytes}}
|
||||
Ok(swagger::ByteArray(body.to_vec()))
|
||||
{{/producesBytes}}
|
||||
{{^producesBytes}}
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
{{#producesXml}}
|
||||
// ToDo: this will move to swagger-rs and become a standard From conversion trait
|
||||
// once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream
|
||||
serde_xml_rs::from_str::<{{{dataType}}}>(body)
|
||||
.map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))
|
||||
{{/producesXml}}
|
||||
{{#producesJson}}
|
||||
serde_json::from_str::<{{{dataType}}}>(body)
|
||||
.map_err(|e| e.into())
|
||||
{{/producesJson}}
|
||||
{{#producesPlainText}}
|
||||
Ok(body.to_string())
|
||||
{{/producesPlainText}}
|
||||
)
|
||||
{{/producesBytes}}
|
||||
{{/vendorExtensions}}
|
||||
)
|
||||
.map(move |body| {
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{^headers}}
|
||||
(body)
|
||||
{{/headers}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
body: body,
|
||||
{{/-first}}
|
||||
{{{name}}}: (*Into::<header::IntoHeaderValue<{{{dataType}}}>>::into(response_{{{name}}})).clone(),
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
})
|
||||
{{/dataType}}
|
||||
{{^dataType}}
|
||||
future::ok(
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
{{/-first}}
|
||||
{{{name}}}: (*Into::<header::IntoHeaderValue<{{{dataType}}}>>::into(response_{{{name}}})).clone(),
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
)
|
||||
{{/dataType}}
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
},
|
||||
{{/responses}}
|
||||
code => {
|
||||
let headers = response.headers().clone();
|
||||
Box::new(response.into_body()
|
||||
.take(100)
|
||||
.concat2()
|
||||
.then(move |body|
|
||||
future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
|
||||
code,
|
||||
headers,
|
||||
match body {
|
||||
Ok(ref body) => match str::from_utf8(body) {
|
||||
Ok(body) => Cow::from(body),
|
||||
Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
|
||||
},
|
||||
Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
|
||||
})))
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
@@ -1,13 +1,27 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate {{{externCrateName}}};
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
{{#hasCallbacks}}
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate native_tls;
|
||||
extern crate tokio_tls;
|
||||
{{#apiUsesUuid}}
|
||||
extern crate uuid;
|
||||
{{/apiUsesUuid}}
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
mod server;
|
||||
{{/hasCallbacks}}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
@@ -17,15 +31,28 @@ use {{{externCrateName}}}::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#vendorExtensions}}{{^noClientExample}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#vendorExtensions}}
|
||||
{{^noClientExample}}
|
||||
"{{{operationId}}}",
|
||||
{{/noClientExample}}{{/vendorExtensions}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{/noClientExample}}
|
||||
{{/vendorExtensions}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -68,24 +95,40 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
{{#hasCallbacks}}
|
||||
|
||||
// We could do HTTPS here, but for simplicity we don't
|
||||
rt.spawn(server::create("127.0.0.1:8081", None));
|
||||
{{/hasCallbacks}}
|
||||
|
||||
match matches.value_of("operation") {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#vendorExtensions.noClientExample}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#vendorExtensions}}
|
||||
{{#noClientExample}}
|
||||
/* Disabled because there's no example.
|
||||
{{/vendorExtensions.noClientExample}}
|
||||
{{/noClientExample}}
|
||||
{{/vendorExtensions}}
|
||||
Some("{{{operationId}}}") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.{{{vendorExtensions.operation_id}}}(
|
||||
{{#allParams}}
|
||||
{{{vendorExtensions.example}}}{{^-last}},{{/-last}}
|
||||
{{/allParams}}
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
{{#vendorExtensions.noClientExample}}
|
||||
{{#vendorExtensions}}
|
||||
{{#noClientExample}}
|
||||
*/
|
||||
{{/vendorExtensions.noClientExample}}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{/noClientExample}}
|
||||
{{/vendorExtensions}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
36
modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache
vendored
Normal file
36
modules/openapi-generator/src/main/resources/rust-server/example-client-server.mustache
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{{>example-server-common}}
|
||||
use {{{externCrateName}}}::{CallbackApi, ApiError};
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
use {{{externCrateName}}}::{{{operationId}}}Response;
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
use {{{externCrateName}}}::client::callbacks::MakeService;
|
||||
|
||||
impl<C> CallbackApi<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>example-server-operation}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
84
modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache
vendored
Normal file
84
modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
//! Main library entry point for {{{externCrateName}}} implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
|
||||
|
||||
use {{{externCrateName}}}::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
{{{externCrateName}}}::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
69
modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache
vendored
Normal file
69
modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
//! Main binary entry point for {{{externCrateName}}} implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate {{{externCrateName}}};
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate {{{externCrateName}}};
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
{{#apiUsesUuid}}
|
||||
extern crate uuid;
|
||||
{{/apiUsesUuid}}
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:{{{serverPort}}}";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
19
modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache
vendored
Normal file
19
modules/openapi-generator/src/main/resources/rust-server/example-server-operation.mustache
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}}: String,
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
context: &C) -> Box<Future<Item={{{operationId}}}Response, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
28
modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache
vendored
Normal file
28
modules/openapi-generator/src/main/resources/rust-server/example-server-server.mustache
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{{>example-server-common}}
|
||||
|
||||
use {{{externCrateName}}}::{
|
||||
Api,
|
||||
ApiError,
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{{operationId}}}Response,
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
};
|
||||
use {{{externCrateName}}}::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>example-server-operation}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
//! Main binary entry point for {{{externCrateName}}} implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate {{{externCrateName}}};
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate {{{externCrateName}}};
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
{{#apiUsesUuid}}
|
||||
extern crate uuid;
|
||||
{{/apiUsesUuid}}
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = {{{externCrateName}}}::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
{{{externCrateName}}}::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:{{{serverPort}}}".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
//! Main library entry point for {{{externCrateName}}} implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
{{#apiUsesUuid}}use uuid;{{/apiUsesUuid}}
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use {{{externCrateName}}}::{Api, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
use {{{externCrateName}}}::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#summary}} /// {{{summary}}}{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{{operationId}}}Response, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{formatString}}}{{/vendorExtensions}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone());{{#allParams}}{{/allParams}}
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(any(feature = "server"))]
|
||||
{{#hasCallbacks}}
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
{{/hasCallbacks}}
|
||||
{{^hasCallbacks}}
|
||||
#[cfg(feature = "server")]
|
||||
{{/hasCallbacks}}
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
@@ -36,7 +41,7 @@ extern crate swagger;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate hyper;
|
||||
#[cfg(any(feature = "client"))]
|
||||
#[cfg(feature = "client")]
|
||||
extern crate hyper_tls;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate openssl;
|
||||
@@ -50,7 +55,12 @@ extern crate mime_multipart;
|
||||
{{/apiUsesMultipartRelated}}
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate native_tls;
|
||||
{{#hasCallbacks}}
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
{{/hasCallbacks}}
|
||||
{{^hasCallbacks}}
|
||||
#[cfg(feature = "server")]
|
||||
{{/hasCallbacks}}
|
||||
extern crate percent_encoding;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate serde_json;
|
||||
@@ -92,70 +102,57 @@ pub const BASE_PATH: &'static str = "{{{basePathWithoutHost}}}";
|
||||
pub const API_VERSION: &'static str = "{{{appVersion}}}";
|
||||
{{/appVersion}}
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum {{{operationId}}}Response {
|
||||
{{#responses}}
|
||||
{{#message}}
|
||||
/// {{{message}}}{{/message}}
|
||||
{{#vendorExtensions}}
|
||||
{{{x-responseId}}}
|
||||
{{/vendorExtensions}}
|
||||
{{^dataType}}
|
||||
{{#hasHeaders}}
|
||||
{
|
||||
{{/hasHeaders}}
|
||||
{{/dataType}}
|
||||
{{#dataType}}
|
||||
{{^hasHeaders}}
|
||||
{{#vendorExtensions}}
|
||||
{{#producesPlainText}}
|
||||
(String)
|
||||
{{/producesPlainText}}
|
||||
{{^producesPlainText}}
|
||||
( {{{dataType}}} )
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
{{/hasHeaders}}
|
||||
{{#hasHeaders}}
|
||||
{
|
||||
{{#vendorExtensions}}
|
||||
{{#producesPlainText}}
|
||||
body: String,
|
||||
{{/producesPlainText}}
|
||||
{{^producesPlainText}}
|
||||
body: {{{dataType}}},
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
{{/hasHeaders}}
|
||||
{{/dataType}}
|
||||
{{#headers}}
|
||||
{{{name}}}: {{{datatype}}},
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
{{^-last}}
|
||||
,
|
||||
{{/-last}}
|
||||
{{/responses}}
|
||||
}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>response}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
/// API
|
||||
pub trait Api<C> {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#summary}} /// {{{summary}}}{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
/// API without a `Context`
|
||||
pub trait ApiNoContext {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#summary}} /// {{{summary}}}{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
/// Trait to extend an API to make it easy to bind it to a context.
|
||||
@@ -171,20 +168,176 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
|
||||
}
|
||||
|
||||
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#summary}} /// {{{summary}}}{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send> {
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&self.context())
|
||||
}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
{{#hasCallbacks}}
|
||||
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>response}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
/// Callback API
|
||||
pub trait CallbackApi<C> {
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}}: String,
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
context: &C) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
/// Callback API without a `Context`
|
||||
pub trait CallbackApiNoContext {
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}}: String,
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>;
|
||||
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
/// Trait to extend an API to make it easy to bind it to a context.
|
||||
pub trait CallbackContextWrapperExt<'a, C> where Self: Sized {
|
||||
/// Binds this API to a context.
|
||||
fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>;
|
||||
}
|
||||
|
||||
impl<'a, T: CallbackApi<C> + Sized, C> CallbackContextWrapperExt<'a, C> for T {
|
||||
fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> {
|
||||
ContextWrapper::<T, C>::new(self, context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: CallbackApi<C>, C> CallbackApiNoContext for ContextWrapper<'a, T, C> {
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{#summary}}
|
||||
/// {{{summary}}}
|
||||
{{/summary}}
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
&self,
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}}: String,
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}},
|
||||
{{/allParams}}
|
||||
) -> Box<dyn Future<Item={{{operationId}}}Response, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}},
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
{{{paramName}}},
|
||||
{{/allParams}}
|
||||
&self.context())
|
||||
}
|
||||
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
{{/hasCallbacks}}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
pub mod client;
|
||||
|
||||
// Re-export Client as a top-level name
|
||||
#[cfg(feature = "client")]
|
||||
pub use self::client::Client;
|
||||
pub use client::Client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
@@ -193,5 +346,13 @@ pub mod server;
|
||||
#[cfg(feature = "server")]
|
||||
pub use self::server::Service;
|
||||
|
||||
{{#hasCallbacks}}
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
{{/hasCallbacks}}
|
||||
{{^hasCallbacks}}
|
||||
#[cfg(feature = "server")]
|
||||
{{/hasCallbacks}}
|
||||
pub mod context;
|
||||
|
||||
pub mod models;
|
||||
pub mod header;
|
||||
|
||||
22
modules/openapi-generator/src/main/resources/rust-server/mimetypes-request.mustache
vendored
Normal file
22
modules/openapi-generator/src/main/resources/rust-server/mimetypes-request.mustache
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{{^vendorExtensions.consumesMultipart}}
|
||||
{{#bodyParam}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{vendorExtensions.uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}";
|
||||
{{/bodyParam}}
|
||||
{{^bodyParam}}
|
||||
{{#vendorExtensions}}
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}";
|
||||
{{/-first}}
|
||||
{{/formParams}}
|
||||
{{#relatedParams}}
|
||||
{{#-first}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}multipart/related{{/consumes}}";
|
||||
{{/-first}}
|
||||
{{/relatedParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParam}}
|
||||
{{/vendorExtensions.consumesMultipart}}
|
||||
10
modules/openapi-generator/src/main/resources/rust-server/mimetypes-response.mustache
vendored
Normal file
10
modules/openapi-generator/src/main/resources/rust-server/mimetypes-response.mustache
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{{#responses}}
|
||||
{{#produces}}
|
||||
{{#-first}}
|
||||
{{#dataType}}
|
||||
/// Create &str objects for the response content types for {{{operationId}}}
|
||||
pub static {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}: &str = "{{{mimeType}}}";{{/vendorExtensions}}
|
||||
{{/dataType}}
|
||||
{{/-first}}
|
||||
{{/produces}}
|
||||
{{/responses}}
|
||||
@@ -1,22 +1,39 @@
|
||||
/// mime types for requests and responses
|
||||
|
||||
pub mod responses {
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}}
|
||||
/// Create &str objects for the response content types for {{{operationId}}}
|
||||
pub static {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}: &str = "{{{mimeType}}}";{{/vendorExtensions}}
|
||||
{{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>mimetypes-response}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>mimetypes-response}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{^vendorExtensions.consumesMultipart}}{{#bodyParam}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{vendorExtensions.uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}";
|
||||
{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}";
|
||||
{{/-first}}{{/formParams}}{{#relatedParams}}{{#-first}}
|
||||
/// Create &str objects for the request content types for {{{operationId}}}
|
||||
pub static {{{uppercase_operation_id}}}: &str = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}multipart/related{{/consumes}}";
|
||||
{{/-first}}{{/relatedParams}}{{/vendorExtensions}}{{/bodyParam}}{{/vendorExtensions.consumesMultipart}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>mimetypes-request}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>mimetypes-request}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
|
||||
47
modules/openapi-generator/src/main/resources/rust-server/response.mustache
vendored
Normal file
47
modules/openapi-generator/src/main/resources/rust-server/response.mustache
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum {{{operationId}}}Response {
|
||||
{{#responses}}
|
||||
{{#message}}
|
||||
/// {{{message}}}{{/message}}
|
||||
{{#vendorExtensions}}
|
||||
{{{x-responseId}}}
|
||||
{{/vendorExtensions}}
|
||||
{{^dataType}}
|
||||
{{#hasHeaders}}
|
||||
{
|
||||
{{/hasHeaders}}
|
||||
{{/dataType}}
|
||||
{{#dataType}}
|
||||
{{^hasHeaders}}
|
||||
{{#vendorExtensions}}
|
||||
{{#producesPlainText}}
|
||||
(String)
|
||||
{{/producesPlainText}}
|
||||
{{^producesPlainText}}
|
||||
({{{dataType}}})
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
{{/hasHeaders}}
|
||||
{{#hasHeaders}}
|
||||
{
|
||||
{{#vendorExtensions}}
|
||||
{{#producesPlainText}}
|
||||
body: String,
|
||||
{{/producesPlainText}}
|
||||
{{^producesPlainText}}
|
||||
body: {{{dataType}}},
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
{{/hasHeaders}}
|
||||
{{/dataType}}
|
||||
{{#headers}}
|
||||
{{{name}}}: {{{datatype}}}{{^-last}},{{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
{{^-last}}
|
||||
,
|
||||
{{/-last}}
|
||||
{{/responses}}
|
||||
}
|
||||
147
modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache
vendored
Normal file
147
modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
{{>client-imports}}
|
||||
use CallbackApi;
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
use {{{operationId}}}Response;
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
|
||||
/// A client that implements the API by making HTTP calls out to a server.
|
||||
pub struct Client<F>
|
||||
{
|
||||
/// Inner service
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl<F> fmt::Debug for Client<F>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Client")
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Clone for Client<F>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Client {
|
||||
client_service: self.client_service.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Client<hyper::client::ResponseFuture>
|
||||
{
|
||||
/// Create a client with a custom implementation of hyper::client::Connect.
|
||||
///
|
||||
/// Intended for use with custom implementations of connect for e.g. protocol logging
|
||||
/// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection,
|
||||
/// this function should be used in conjunction with
|
||||
/// `swagger::{http_connector, https_connector, https_mutual_connector}`.
|
||||
///
|
||||
/// For ordinary tcp connections, prefer the use of `new_http`, `new_https`
|
||||
/// and `new_https_mutual`, to avoid introducing a dependency on the underlying transport layer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect`
|
||||
pub fn new_with_connector<C>(
|
||||
connector_fn: Box<dyn Fn() -> C + Send + Sync>,
|
||||
) -> Self where
|
||||
C: hyper::client::connect::Connect + 'static,
|
||||
C::Transport: 'static,
|
||||
C::Future: 'static,
|
||||
{
|
||||
let connector = connector_fn();
|
||||
|
||||
let client_service = Box::new(hyper::client::Client::builder().build(connector));
|
||||
|
||||
Client {
|
||||
client_service: Arc::new(client_service),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an HTTP client.
|
||||
pub fn new_http() -> Self {
|
||||
let http_connector = connector::http_connector();
|
||||
Self::new_with_connector(http_connector)
|
||||
}
|
||||
|
||||
/// Create a client with a TLS connection to the server.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `ca_certificate` - Path to CA certificate used to authenticate the server
|
||||
pub fn new_https<CA>(
|
||||
ca_certificate: CA,
|
||||
) -> Self where
|
||||
CA: AsRef<Path>,
|
||||
{
|
||||
let https_connector = connector::https_connector(ca_certificate);
|
||||
Self::new_with_connector(https_connector)
|
||||
}
|
||||
|
||||
/// Create a client with a mutually authenticated TLS connection to the server.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `ca_certificate` - Path to CA certificate used to authenticate the server
|
||||
/// * `client_key` - Path to the client private key
|
||||
/// * `client_certificate` - Path to the client's public certificate associated with the private key
|
||||
pub fn new_https_mutual<CA, K, D>(
|
||||
ca_certificate: CA,
|
||||
client_key: K,
|
||||
client_certificate: D,
|
||||
) -> Self
|
||||
where
|
||||
CA: AsRef<Path>,
|
||||
K: AsRef<Path>,
|
||||
D: AsRef<Path>,
|
||||
{
|
||||
let https_connector =
|
||||
connector::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
Self::new_with_connector(https_connector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Client<F>
|
||||
{
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
|
||||
///
|
||||
/// This allows adding custom wrappers around the underlying transport, for example for logging.
|
||||
pub fn new_with_client_service(
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
) -> Self {
|
||||
Client {
|
||||
client_service: client_service,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> CallbackApi<C> for Client<F> where
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}},
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{#callbacks}}
|
||||
{{#urls}}
|
||||
{{#requests}}
|
||||
{{>client-operation}}
|
||||
{{/requests}}
|
||||
{{/urls}}
|
||||
{{/callbacks}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
}
|
||||
39
modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache
vendored
Normal file
39
modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap, BTreeSet};
|
||||
use std::marker::PhantomData;
|
||||
use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
{{#apiUsesMultipartRelated}}
|
||||
use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_0_2::{TopLevel, SubLevel, Mime as Mime2};
|
||||
use mime_multipart::{read_multipart_body, Node, Part};
|
||||
{{/apiUsesMultipartRelated}}
|
||||
{{#apiUsesUuid}}
|
||||
use uuid;
|
||||
{{/apiUsesUuid}}
|
||||
{{#apiUsesMultipartFormData}}
|
||||
use multipart::server::Multipart;
|
||||
use multipart::server::save::SaveResult;
|
||||
{{/apiUsesMultipartFormData}}
|
||||
{{#usesXml}}
|
||||
use serde_xml_rs;
|
||||
{{/usesXml}}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub use crate::context;
|
||||
36
modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache
vendored
Normal file
36
modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
pub struct MakeService<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static
|
||||
{
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
MakeService {
|
||||
api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, RC>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Service = Service<T, RC>;
|
||||
type Future = future::FutureResult<Self::Service, Self::MakeError>;
|
||||
type MakeError = Error;
|
||||
|
||||
fn make_service(&mut self, _ctx: &'a SC) -> Self::Future {
|
||||
future::FutureResult::from(Ok(Service::new(
|
||||
self.api_impl.clone(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
@@ -1,733 +1,42 @@
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap, BTreeSet};
|
||||
use std::marker::PhantomData;
|
||||
use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use url::form_urlencoded;
|
||||
{{#apiUsesMultipartRelated}}
|
||||
use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_0_2::{TopLevel, SubLevel, Mime as Mime2};
|
||||
use mime_multipart::{read_multipart_body, Node, Part};
|
||||
{{/apiUsesMultipartRelated}}
|
||||
{{#apiUsesMultipartFormData}}
|
||||
use multipart::server::Multipart;
|
||||
use multipart::server::save::SaveResult;
|
||||
{{/apiUsesMultipartFormData}}
|
||||
{{#usesXml}}
|
||||
use serde_xml_rs;
|
||||
{{/usesXml}}
|
||||
{{#apiUsesUuid}}
|
||||
use uuid;
|
||||
{{/apiUsesUuid}}
|
||||
|
||||
use mimetypes;
|
||||
|
||||
pub use swagger::auth::Authorization;
|
||||
|
||||
{{>server-imports}}
|
||||
use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub mod context;
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
|
||||
{{#pathSet}}
|
||||
r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
|
||||
{{/pathSet}}
|
||||
])
|
||||
.expect("Unable to create global regex set");
|
||||
}
|
||||
{{#pathSet}}
|
||||
pub static ID_{{{PATH_ID}}}: usize = {{{index}}};
|
||||
{{#hasPathParams}}
|
||||
lazy_static! {
|
||||
pub static ref REGEX_{{{PATH_ID}}}: regex::Regex =
|
||||
regex::Regex::new(r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}")
|
||||
.expect("Unable to create regex for {{{PATH_ID}}}");
|
||||
}
|
||||
{{/hasPathParams}}
|
||||
{{/pathSet}}
|
||||
}
|
||||
|
||||
pub struct MakeService<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static
|
||||
{
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
MakeService {
|
||||
api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, RC>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Service = Service<T, RC>;
|
||||
type Future = future::FutureResult<Self::Service, Self::MakeError>;
|
||||
type MakeError = Error;
|
||||
|
||||
fn make_service(&mut self, _ctx: &'a SC) -> Self::Future {
|
||||
future::FutureResult::from(Ok(Service::new(
|
||||
self.api_impl.clone(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Service<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> Service<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static {
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
Service {
|
||||
api_impl: api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::service::Service for Service<T, C>
|
||||
where
|
||||
T: Api<C> + Clone + Send + 'static,
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, C>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Future = Box<dyn Future<Item = Response<Self::ResBody>, Error = Self::Error> + Send>;
|
||||
|
||||
fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
|
||||
let api_impl = self.api_impl.clone();
|
||||
let (parts, body) = req.into_parts();
|
||||
let (method, uri, headers) = (parts.method, parts.uri, parts.headers);
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(uri.path());
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
// This match statement is duplicated below in `parse_operation_id()`.
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
|
||||
&hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => {
|
||||
{{#hasAuthMethods}}
|
||||
{
|
||||
let authorization = match (&context as &dyn Has<Option<Authorization>>).get() {
|
||||
&Some(ref authorization) => authorization,
|
||||
&None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::FORBIDDEN)
|
||||
.body(Body::from("Unauthenticated"))
|
||||
.expect("Unable to create Authentication Forbidden response"))),
|
||||
};
|
||||
|
||||
{{#authMethods}}
|
||||
{{#isOAuth}}
|
||||
// Authorization
|
||||
if let Scopes::Some(ref scopes) = authorization.scopes {
|
||||
let required_scopes: BTreeSet<String> = vec![
|
||||
{{#scopes}}
|
||||
"{{{scope}}}".to_string(), // {{{description}}}
|
||||
{{/scopes}}
|
||||
].into_iter().collect();
|
||||
|
||||
if !required_scopes.is_subset(scopes) {
|
||||
let missing_scopes = required_scopes.difference(scopes);
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::FORBIDDEN)
|
||||
.body(Body::from(missing_scopes.fold(
|
||||
"Insufficient authorization, missing scopes".to_string(),
|
||||
|s, scope| format!("{} {}", s, scope))
|
||||
))
|
||||
.expect("Unable to create Authentication Insufficient response")
|
||||
));
|
||||
}
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
}
|
||||
{{/hasAuthMethods}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
let boundary = match swagger::multipart::boundary(&headers) {
|
||||
Some(boundary) => boundary.to_string(),
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Couldn't find valid multipart body".to_string()))
|
||||
.expect("Unable to create Bad Request response for incorrect boundary"))),
|
||||
};
|
||||
{{/consumesMultipart}}
|
||||
{{#hasPathParams}}
|
||||
// Path parameters
|
||||
let path: &str = &uri.path().to_string();
|
||||
let path_params =
|
||||
paths::REGEX_{{{PATH_ID}}}
|
||||
.captures(&path)
|
||||
.unwrap_or_else(||
|
||||
panic!("Path {} matched RE {{{PATH_ID}}} in set but failed match against \"{}\"", path, paths::REGEX_{{{PATH_ID}}}.as_str())
|
||||
);
|
||||
{{/hasPathParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#pathParams}}
|
||||
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{paramName}}}"].as_bytes()).decode_utf8() {
|
||||
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse path parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid path parameter"))),
|
||||
},
|
||||
Err(_) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"])))
|
||||
.expect("Unable to create Bad Request response for invalid percent decode")))
|
||||
};
|
||||
{{/pathParams}}
|
||||
{{#headerParams}}
|
||||
{{#-first}}
|
||||
|
||||
// Header parameters
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} = headers.get(HeaderName::from_static("{{{nameInLowerCase}}}"));
|
||||
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}})) {
|
||||
Some(v) => Some(header::IntoHeaderValue::<{{{dataType}}}>::from(v)).0),
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing or invalid required header {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing required header {{{baseName}}}")))
|
||||
};
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let param_{{{paramName}}} = param_{{{paramName}}}.map(|p| {
|
||||
header::IntoHeaderValue::<{{{dataType}}}>::from((*p).clone()).0
|
||||
});
|
||||
{{/required}}
|
||||
{{/headerParams}}
|
||||
{{#queryParams}}
|
||||
{{#-first}}
|
||||
|
||||
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
|
||||
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.to_owned())
|
||||
{{#isListContainer}}
|
||||
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok())
|
||||
.collect::<Vec<_>>();
|
||||
{{^required}}
|
||||
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
|
||||
Some(param_{{{paramName}}})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
{{/required}}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
.nth(0);
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}"))),
|
||||
},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required query parameter {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing qeury parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}{{^required}}
|
||||
let param_{{{paramName}}} = param_{{{paramName}}}.and_then(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok());
|
||||
{{/required}}
|
||||
{{/isListContainer}}
|
||||
{{/queryParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipart}}
|
||||
{{#bodyParams}}
|
||||
{{#-first}}
|
||||
// Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesPlainText}}
|
||||
let mut unused_elements = Vec::new();
|
||||
{{/consumesPlainText}}
|
||||
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
|
||||
{{#consumesXml}}
|
||||
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(&*body);
|
||||
{{/consumesJson}}
|
||||
{{^consumesPlainText}}
|
||||
match serde_ignored::deserialize(deserializer, |path| {
|
||||
warn!("Ignoring unknown field in body: {}", path);
|
||||
unused_elements.push(path.to_string());
|
||||
}) {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
{{#required}}
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema"))),
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
Err(_) => None,
|
||||
{{/required}}
|
||||
}
|
||||
{{/consumesPlainText}}
|
||||
{{#consumesPlainText}}
|
||||
{{#isByteArray}}
|
||||
Some(swagger::ByteArray(body.to_vec()))
|
||||
{{/isByteArray}}
|
||||
{{#isString}}
|
||||
match String::from_utf8(body.to_vec()) {
|
||||
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8"))),
|
||||
}
|
||||
{{/isString}}
|
||||
{{/consumesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required body parameter {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{/-first}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{#consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
// Form Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
use std::io::Read;
|
||||
|
||||
// Read Form Parameters from body
|
||||
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
|
||||
SaveResult::Full(entries) => {
|
||||
entries
|
||||
},
|
||||
_ => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Unable to process all message parts")))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
},
|
||||
};
|
||||
{{#formParams}}
|
||||
let field_{{{paramName}}} = entries.fields.remove("{{{paramName}}}");
|
||||
let param_{{{paramName}}} = match field_{{{paramName}}} {
|
||||
Some(field) => {
|
||||
let mut reader = field[0].data.readable().expect("Unable to read field for {{{paramName}}}");
|
||||
{{^required}}
|
||||
Some({
|
||||
{{/required}}
|
||||
{{#isByteArray}}
|
||||
let mut data = vec![];
|
||||
reader.read_to_end(&mut data).expect("Reading saved binary data should never fail");
|
||||
swagger::ByteArray(data)
|
||||
{{/isByteArray}}
|
||||
{{^isByteArray}}
|
||||
{{#jsonSchema}}
|
||||
let mut data = String::new();
|
||||
reader.read_to_string(&mut data).expect("Reading saved String should never fail");
|
||||
let {{{paramName}}}_model: {{{dataType}}} = match serde_json::from_str(&data) {
|
||||
Ok(model) => model,
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("{{{paramName}}} data does not match API definition: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
}
|
||||
};
|
||||
{{{paramName}}}_model
|
||||
{{/jsonSchema}}
|
||||
{{/isByteArray}}
|
||||
{{^required}}
|
||||
})
|
||||
{{/required}}
|
||||
},
|
||||
None => {
|
||||
{{#required}}
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Missing required form parameter {{{paramName}}}")))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")))
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
None
|
||||
{{/required}}
|
||||
}
|
||||
};
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{^consumesMultipartRelated}}
|
||||
{{^consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
Box::new({
|
||||
{{
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// Form parameters
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} =
|
||||
{{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}
|
||||
{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}
|
||||
{{#isMapContainer}}None;{{/isMapContainer}}
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{#consumesMultipartRelated}}
|
||||
// Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
let mut unused_elements: Vec<String> = vec![];
|
||||
|
||||
// Get multipart chunks.
|
||||
|
||||
// Extract the top-level content type header.
|
||||
let content_type_mime = headers
|
||||
.get(CONTENT_TYPE)
|
||||
.ok_or("Missing content-type header".to_string())
|
||||
.and_then(|v| v.to_str().map_err(|e| format!("Couldn't read content-type header value for {{operationId}}: {}", e)))
|
||||
.and_then(|v| v.parse::<Mime2>().map_err(|_e| format!("Couldn't parse content-type header value for {{operationId}}")));
|
||||
|
||||
// Insert top-level content type header into a Headers object.
|
||||
let mut multi_part_headers = Headers::new();
|
||||
match content_type_mime {
|
||||
Ok(content_type_mime) => {
|
||||
multi_part_headers.set(ContentType(content_type_mime));
|
||||
},
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(e))
|
||||
.expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}")));
|
||||
}
|
||||
}
|
||||
|
||||
// &*body expresses the body as a byteslice, &mut provides a
|
||||
// mutable reference to that byteslice.
|
||||
let nodes = match read_multipart_body(&mut&*body, &multi_part_headers, false) {
|
||||
Ok(nodes) => nodes,
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Could not read multipart body for {{operationId}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}")));
|
||||
}
|
||||
};
|
||||
|
||||
{{#formParams}}
|
||||
let mut param_{{{paramName}}} = None;
|
||||
{{/formParams}}
|
||||
|
||||
for node in nodes {
|
||||
if let Node::Part(part) = node {
|
||||
let content_type = part.content_type().map(|x| format!("{}",x));
|
||||
match content_type.as_ref().map(|x| x.as_str()) {
|
||||
{{#formParams}}
|
||||
{{^isBinary}}
|
||||
Some("{{{contentType}}}") => {
|
||||
// Extract JSON part.
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice());
|
||||
let json_data: {{dataType}} = match serde_ignored::deserialize(deserializer, |path| {
|
||||
warn!("Ignoring unknown field in JSON part: {}", path);
|
||||
unused_elements.push(path.to_string());
|
||||
}) {
|
||||
Ok(json_data) => json_data,
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema")))
|
||||
};
|
||||
// Push JSON part to return object.
|
||||
param_{{{paramName}}}.get_or_insert(json_data);
|
||||
},
|
||||
{{/isBinary}}
|
||||
{{#isBinary}}
|
||||
Some("{{{contentType}}}") => {
|
||||
param_{{{paramName}}}.get_or_insert(swagger::ByteArray(part.body));
|
||||
},
|
||||
{{/isBinary}}
|
||||
{{/formParams}}
|
||||
Some(content_type) => {
|
||||
warn!("Ignoring unknown content type: {}", content_type);
|
||||
unused_elements.push(content_type.to_string());
|
||||
},
|
||||
None => {
|
||||
warn!("Missing content type");
|
||||
},
|
||||
}
|
||||
} else {
|
||||
unimplemented!("No support for handling unexpected parts");
|
||||
// unused_elements.push();
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the required multipart chunks are present.
|
||||
{{#formParams}}
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_required_binary_field {
|
||||
Some(x) => x,
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Missing required multipart/related parameter {{{paramName}}}")))
|
||||
.expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema")))
|
||||
};
|
||||
{{/required}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
Box::new(
|
||||
api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
{{#allParams}}
|
||||
param_{{{paramName}}}{{#isListContainer}}.as_ref(){{/isListContainer}},
|
||||
{{/allParams}}
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
{{#bodyParams}}{{#vendorExtensions}}{{^consumesPlainText}}
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str())
|
||||
.expect("Unable to create Warning header value"));
|
||||
}
|
||||
{{/consumesPlainText}}{{/vendorExtensions}}{{/bodyParams}}
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
{{#responses}}
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{#dataType}}{{^headers}}
|
||||
(body)
|
||||
{{/headers}}{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
body,
|
||||
{{/-first}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}{{/dataType}}
|
||||
{{^dataType}}{{#headers}}{{#-first}}
|
||||
{
|
||||
{{/-first}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}{{/dataType}}
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16({{{code}}}).expect("Unable to turn {{{code}}} into a StatusCode");
|
||||
{{#headers}}
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue({{name}}).into()
|
||||
);
|
||||
{{/headers}}
|
||||
{{#produces}}{{#-first}}{{#dataType}}
|
||||
{{#vendorExtensions}}
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}})
|
||||
.expect("Unable to create Content-Type header for {{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}"));
|
||||
{{/vendorExtensions}}
|
||||
{{/dataType}}{{/-first}}{{/produces}}
|
||||
{{#dataType}}
|
||||
{{#vendorExtensions}}
|
||||
{{#producesXml}}
|
||||
{{^has_namespace}}
|
||||
let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
|
||||
{{/has_namespace}}
|
||||
{{#has_namespace}}
|
||||
let mut namespaces = BTreeMap::new();
|
||||
// An empty string is used to indicate a global namespace in xmltree.
|
||||
namespaces.insert("".to_string(), {{{dataType}}}::NAMESPACE.to_string());
|
||||
let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize");
|
||||
{{/has_namespace}}
|
||||
{{/producesXml}}
|
||||
{{#producesJson}}
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
{{/producesJson}}
|
||||
{{#producesBytes}}
|
||||
let body = body.0;
|
||||
{{/producesBytes}}
|
||||
{{#producesPlainText}}
|
||||
let body = body;
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
*response.body_mut() = Body::from(body);
|
||||
{{/dataType}}
|
||||
},
|
||||
{{/responses}}
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipartRelated}}
|
||||
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))),
|
||||
}
|
||||
})
|
||||
) as Self::Future
|
||||
{{/consumesMultipartRelated}}
|
||||
{{^consumesMultipartRelated}}
|
||||
}}
|
||||
}) as Self::Future
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
{{#bodyParams}}
|
||||
{{#-first}}
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))),
|
||||
}
|
||||
})
|
||||
) as Self::Future
|
||||
{{/-first}}
|
||||
{{/bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
as Self::Future
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read multipart body")))
|
||||
.expect("Unable to create Bad Request response due to unable read multipart body"))),
|
||||
}
|
||||
})
|
||||
)
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
},
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
_ => Box::new(future::ok(
|
||||
Response::builder().status(StatusCode::NOT_FOUND)
|
||||
.body(Body::empty())
|
||||
.expect("Unable to create Not Found response")
|
||||
)) as Self::Future
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> Clone for Service<T, C> where T: Clone
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Service {
|
||||
api_impl: self.api_impl.clone(),
|
||||
marker: self.marker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
{{#hasCallbacks}}
|
||||
pub mod callbacks;
|
||||
|
||||
{{/hasCallbacks}}
|
||||
{{>server-paths}}
|
||||
{{>server-make-service}}
|
||||
{{>server-service-header}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
{{>server-operation}}
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
{{>server-service-footer}}
|
||||
/// Request parser for `Api`.
|
||||
pub struct ApiRequestParser;
|
||||
impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#apiInfo}}
|
||||
{{#apis}}
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
|
||||
&hyper::Method::{{{vendorExtensions.HttpMethod}}} if path.matched(paths::ID_{{{vendorExtensions.PATH_ID}}}) => Ok("{{{operationId}}}"),
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} _ => Err(()),
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
599
modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache
vendored
Normal file
599
modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
|
||||
&hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => {
|
||||
{{#hasAuthMethods}}
|
||||
{
|
||||
let authorization = match (&context as &dyn Has<Option<Authorization>>).get() {
|
||||
&Some(ref authorization) => authorization,
|
||||
&None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::FORBIDDEN)
|
||||
.body(Body::from("Unauthenticated"))
|
||||
.expect("Unable to create Authentication Forbidden response"))),
|
||||
};
|
||||
{{#authMethods}}
|
||||
{{#isOAuth}}
|
||||
|
||||
// Authorization
|
||||
if let Scopes::Some(ref scopes) = authorization.scopes {
|
||||
let required_scopes: BTreeSet<String> = vec![
|
||||
{{#scopes}}
|
||||
"{{{scope}}}".to_string(), // {{{description}}}
|
||||
{{/scopes}}
|
||||
].into_iter().collect();
|
||||
|
||||
if !required_scopes.is_subset(scopes) {
|
||||
let missing_scopes = required_scopes.difference(scopes);
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::FORBIDDEN)
|
||||
.body(Body::from(missing_scopes.fold(
|
||||
"Insufficient authorization, missing scopes".to_string(),
|
||||
|s, scope| format!("{} {}", s, scope))
|
||||
))
|
||||
.expect("Unable to create Authentication Insufficient response")
|
||||
));
|
||||
}
|
||||
}
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
}
|
||||
|
||||
{{/hasAuthMethods}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
let boundary = match swagger::multipart::boundary(&headers) {
|
||||
Some(boundary) => boundary.to_string(),
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Couldn't find valid multipart body".to_string()))
|
||||
.expect("Unable to create Bad Request response for incorrect boundary"))),
|
||||
};
|
||||
|
||||
{{/consumesMultipart}}
|
||||
{{#hasPathParams}}
|
||||
// Path parameters
|
||||
let path: &str = &uri.path().to_string();
|
||||
let path_params =
|
||||
paths::REGEX_{{{PATH_ID}}}
|
||||
.captures(&path)
|
||||
.unwrap_or_else(||
|
||||
panic!("Path {} matched RE {{{PATH_ID}}} in set but failed match against \"{}\"", path, paths::REGEX_{{{PATH_ID}}}.as_str())
|
||||
);
|
||||
|
||||
{{/hasPathParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#pathParams}}
|
||||
let param_{{{paramName}}} = match percent_encoding::percent_decode(path_params["{{{baseName}}}"].as_bytes()).decode_utf8() {
|
||||
Ok(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse path parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid path parameter"))),
|
||||
},
|
||||
Err(_) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"])))
|
||||
.expect("Unable to create Bad Request response for invalid percent decode")))
|
||||
};
|
||||
|
||||
{{/pathParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
let callback_{{.}} = path_params["{{{.}}}"].to_string();
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#headerParams}}
|
||||
{{#-first}}
|
||||
// Header parameters
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} = headers.get(HeaderName::from_static("{{{nameInLowerCase}}}"));
|
||||
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(v) => header::IntoHeaderValue::<{{{dataType}}}>::from((*v).clone()).0,
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing or invalid required header {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing required header {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let param_{{{paramName}}} = param_{{{paramName}}}.map(|p| {
|
||||
header::IntoHeaderValue::<{{{dataType}}}>::from((*p).clone()).0
|
||||
});
|
||||
{{/required}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/headerParams}}
|
||||
{{#queryParams}}
|
||||
{{#-first}}
|
||||
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
|
||||
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.to_owned())
|
||||
{{#isListContainer}}
|
||||
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok())
|
||||
.collect::<Vec<_>>();
|
||||
{{^required}}
|
||||
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
|
||||
Some(param_{{{paramName}}})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
{{/required}}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
.nth(0);
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(param_{{{paramName}}}) => match param_{{{paramName}}}.parse::<{{{dataType}}}>() {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}"))),
|
||||
},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required query parameter {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing qeury parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let param_{{{paramName}}} = param_{{{paramName}}}.and_then(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok());
|
||||
{{/required}}
|
||||
{{/isListContainer}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/queryParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipart}}
|
||||
{{#bodyParams}}
|
||||
{{#-first}}
|
||||
// Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesPlainText}}
|
||||
let mut unused_elements = Vec::new();
|
||||
{{/consumesPlainText}}
|
||||
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
|
||||
{{#consumesXml}}
|
||||
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
|
||||
{{/consumesXml}}
|
||||
{{#consumesJson}}
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(&*body);
|
||||
{{/consumesJson}}
|
||||
{{^consumesPlainText}}
|
||||
match serde_ignored::deserialize(deserializer, |path| {
|
||||
warn!("Ignoring unknown field in body: {}", path);
|
||||
unused_elements.push(path.to_string());
|
||||
}) {
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
{{#required}}
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema"))),
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
Err(_) => None,
|
||||
{{/required}}
|
||||
}
|
||||
{{/consumesPlainText}}
|
||||
{{#consumesPlainText}}
|
||||
{{#isByteArray}}
|
||||
Some(swagger::ByteArray(body.to_vec()))
|
||||
{{/isByteArray}}
|
||||
{{#isString}}
|
||||
match String::from_utf8(body.to_vec()) {
|
||||
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8"))),
|
||||
}
|
||||
{{/isString}}
|
||||
{{/consumesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required body parameter {{{baseName}}}"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{/-first}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{#consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
// Form Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
use std::io::Read;
|
||||
|
||||
// Read Form Parameters from body
|
||||
let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary).save().temp() {
|
||||
SaveResult::Full(entries) => {
|
||||
entries
|
||||
},
|
||||
_ => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Unable to process all message parts")))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
},
|
||||
};
|
||||
{{#formParams}}
|
||||
let field_{{{paramName}}} = entries.fields.remove("{{{paramName}}}");
|
||||
let param_{{{paramName}}} = match field_{{{paramName}}} {
|
||||
Some(field) => {
|
||||
let mut reader = field[0].data.readable().expect("Unable to read field for {{{paramName}}}");
|
||||
{{^required}}
|
||||
Some({
|
||||
{{/required}}
|
||||
{{#isByteArray}}
|
||||
let mut data = vec![];
|
||||
reader.read_to_end(&mut data).expect("Reading saved binary data should never fail");
|
||||
swagger::ByteArray(data)
|
||||
{{/isByteArray}}
|
||||
{{^isByteArray}}
|
||||
{{#jsonSchema}}
|
||||
let mut data = String::new();
|
||||
reader.read_to_string(&mut data).expect("Reading saved String should never fail");
|
||||
let {{{paramName}}}_model: {{{dataType}}} = match serde_json::from_str(&data) {
|
||||
Ok(model) => model,
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("{{{paramName}}} data does not match API definition : {}", e)))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")))
|
||||
}
|
||||
};
|
||||
{{{paramName}}}_model
|
||||
{{/jsonSchema}}
|
||||
{{/isByteArray}}
|
||||
{{^required}}
|
||||
})
|
||||
{{/required}}
|
||||
},
|
||||
None => {
|
||||
{{#required}}
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Missing required form parameter {{{paramName}}}")))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")))
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
None
|
||||
{{/required}}
|
||||
}
|
||||
};
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{^consumesMultipartRelated}}
|
||||
{{^consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
Box::new({
|
||||
{{
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// Form parameters
|
||||
{{/-first}}
|
||||
let param_{{{paramName}}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{#consumesMultipartRelated}}
|
||||
// Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
Box::new(body.concat2()
|
||||
.then(move |result| -> Self::Future {
|
||||
match result {
|
||||
Ok(body) => {
|
||||
let mut unused_elements: Vec<String> = vec![];
|
||||
|
||||
// Get multipart chunks.
|
||||
|
||||
// Extract the top-level content type header.
|
||||
let content_type_mime = headers
|
||||
.get(CONTENT_TYPE)
|
||||
.ok_or("Missing content-type header".to_string())
|
||||
.and_then(|v| v.to_str().map_err(|e| format!("Couldn't read content-type header value for {{operationId}}: {}", e)))
|
||||
.and_then(|v| v.parse::<Mime2>().map_err(|_e| format!("Couldn't parse content-type header value for {{operationId}}")));
|
||||
|
||||
// Insert top-level content type header into a Headers object.
|
||||
let mut multi_part_headers = Headers::new();
|
||||
match content_type_mime {
|
||||
Ok(content_type_mime) => {
|
||||
multi_part_headers.set(ContentType(content_type_mime));
|
||||
},
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(e))
|
||||
.expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}")));
|
||||
}
|
||||
}
|
||||
|
||||
// &*body expresses the body as a byteslice, &mut provides a
|
||||
// mutable reference to that byteslice.
|
||||
let nodes = match read_multipart_body(&mut&*body, &multi_part_headers, false) {
|
||||
Ok(nodes) => nodes,
|
||||
Err(e) => {
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Could not read multipart body for {{operationId}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}")));
|
||||
}
|
||||
};
|
||||
|
||||
{{#formParams}}
|
||||
let mut param_{{{paramName}}} = None;
|
||||
{{/formParams}}
|
||||
|
||||
for node in nodes {
|
||||
if let Node::Part(part) = node {
|
||||
let content_type = part.content_type().map(|x| format!("{}",x));
|
||||
match content_type.as_ref().map(|x| x.as_str()) {
|
||||
{{#formParams}}
|
||||
{{^isBinary}}
|
||||
Some("{{{contentType}}}") => {
|
||||
// Extract JSON part.
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice());
|
||||
let json_data: {{dataType}} = match serde_ignored::deserialize(deserializer, |path| {
|
||||
warn!("Ignoring unknown field in JSON part: {}", path);
|
||||
unused_elements.push(path.to_string());
|
||||
}) {
|
||||
Ok(json_data) => json_data,
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema")))
|
||||
};
|
||||
// Push JSON part to return object.
|
||||
param_{{{paramName}}}.get_or_insert(json_data);
|
||||
},
|
||||
{{/isBinary}}
|
||||
{{#isBinary}}
|
||||
Some("{{{contentType}}}") => {
|
||||
param_{{{paramName}}}.get_or_insert(swagger::ByteArray(part.body));
|
||||
},
|
||||
{{/isBinary}}
|
||||
{{/formParams}}
|
||||
Some(content_type) => {
|
||||
warn!("Ignoring unknown content type: {}", content_type);
|
||||
unused_elements.push(content_type.to_string());
|
||||
},
|
||||
None => {
|
||||
warn!("Missing content type");
|
||||
},
|
||||
}
|
||||
} else {
|
||||
unimplemented!("No support for handling unexpected parts");
|
||||
// unused_elements.push();
|
||||
}
|
||||
}
|
||||
|
||||
{{#formParams}}
|
||||
{{#-first}}
|
||||
// Check that the required multipart chunks are present.
|
||||
{{/-first}}
|
||||
{{#required}}
|
||||
let param_{{{paramName}}} = match param_required_binary_field {
|
||||
Some(x) => x,
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Missing required multipart/related parameter {{{paramName}}}")))
|
||||
.expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema")))
|
||||
};
|
||||
{{/required}}
|
||||
{{#-last}}
|
||||
|
||||
{{/-last}}
|
||||
{{/formParams}}
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
Box::new(
|
||||
api_impl.{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(
|
||||
{{#vendorExtensions}}
|
||||
{{#callbackParams}}
|
||||
callback_{{.}},
|
||||
{{/callbackParams}}
|
||||
{{/vendorExtensions}}
|
||||
{{#allParams}}
|
||||
param_{{{paramName}}}{{#isListContainer}}.as_ref(){{/isListContainer}},
|
||||
{{/allParams}}
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
{{#bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesPlainText}}
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str())
|
||||
.expect("Unable to create Warning header value"));
|
||||
}
|
||||
|
||||
{{/consumesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
{{#responses}}
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{#dataType}}
|
||||
{{^headers}}
|
||||
(body)
|
||||
{{/headers}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
body,
|
||||
{{/-first}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
{{/dataType}}
|
||||
{{^dataType}}
|
||||
{{#headers}}
|
||||
{{#-first}}
|
||||
{
|
||||
{{/-first}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}
|
||||
{{/dataType}}
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16({{{code}}}).expect("Unable to turn {{{code}}} into a StatusCode");
|
||||
{{#headers}}
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("{{{nameInLowerCase}}}"),
|
||||
header::IntoHeaderValue({{name}}).into()
|
||||
);
|
||||
{{/headers}}
|
||||
{{#produces}}
|
||||
{{#-first}}
|
||||
{{#dataType}}
|
||||
{{#vendorExtensions}}
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}})
|
||||
.expect("Unable to create Content-Type header for {{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}"));
|
||||
{{/vendorExtensions}}
|
||||
{{/dataType}}
|
||||
{{/-first}}
|
||||
{{/produces}}
|
||||
{{#dataType}}
|
||||
{{#vendorExtensions}}
|
||||
{{#producesXml}}
|
||||
{{^has_namespace}}
|
||||
let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
|
||||
{{/has_namespace}}
|
||||
{{#has_namespace}}
|
||||
let mut namespaces = BTreeMap::new();
|
||||
|
||||
// An empty string is used to indicate a global namespace in xmltree.
|
||||
namespaces.insert("".to_string(), {{{dataType}}}::NAMESPACE.to_string());
|
||||
let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize");
|
||||
{{/has_namespace}}
|
||||
{{/producesXml}}
|
||||
{{#producesJson}}
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
{{/producesJson}}
|
||||
{{#producesBytes}}
|
||||
let body = body.0;
|
||||
{{/producesBytes}}
|
||||
{{#producesPlainText}}
|
||||
let body = body;
|
||||
{{/producesPlainText}}
|
||||
{{/vendorExtensions}}
|
||||
*response.body_mut() = Body::from(body);
|
||||
{{/dataType}}
|
||||
},
|
||||
{{/responses}}
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
{{#vendorExtensions}}
|
||||
{{^consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipartRelated}}
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))),
|
||||
}
|
||||
})
|
||||
) as Self::Future
|
||||
{{/consumesMultipartRelated}}
|
||||
{{^consumesMultipartRelated}}
|
||||
}}
|
||||
}) as Self::Future
|
||||
{{/consumesMultipartRelated}}
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
{{#bodyParams}}
|
||||
{{#-first}}
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to unable to read body parameter {{{baseName}}}"))),
|
||||
}
|
||||
})
|
||||
) as Self::Future
|
||||
{{/-first}}
|
||||
{{/bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
{{#consumesMultipart}}
|
||||
{{^bodyParams}}
|
||||
{{#vendorExtensions}}
|
||||
as Self::Future
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't read multipart body")))
|
||||
.expect("Unable to create Bad Request response due to unable read multipart body"))),
|
||||
}
|
||||
})
|
||||
)
|
||||
{{/vendorExtensions}}
|
||||
{{/bodyParams}}
|
||||
{{/consumesMultipart}}
|
||||
{{/vendorExtensions}}
|
||||
},
|
||||
22
modules/openapi-generator/src/main/resources/rust-server/server-paths.mustache
vendored
Normal file
22
modules/openapi-generator/src/main/resources/rust-server/server-paths.mustache
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
|
||||
{{#pathSet}}
|
||||
r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
|
||||
{{/pathSet}}
|
||||
])
|
||||
.expect("Unable to create global regex set");
|
||||
}
|
||||
{{#pathSet}}
|
||||
pub static ID_{{{PATH_ID}}}: usize = {{{index}}};
|
||||
{{#hasPathParams}}
|
||||
lazy_static! {
|
||||
pub static ref REGEX_{{{PATH_ID}}}: regex::Regex =
|
||||
regex::Regex::new(r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}")
|
||||
.expect("Unable to create regex for {{{PATH_ID}}}");
|
||||
}
|
||||
{{/hasPathParams}}
|
||||
{{/pathSet}}
|
||||
}
|
||||
18
modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache
vendored
Normal file
18
modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
_ => Box::new(future::ok(
|
||||
Response::builder().status(StatusCode::NOT_FOUND)
|
||||
.body(Body::empty())
|
||||
.expect("Unable to create Not Found response")
|
||||
)) as Self::Future
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> Clone for Service<T, C> where T: Clone
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Service {
|
||||
api_impl: self.api_impl.clone(),
|
||||
marker: self.marker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
40
modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache
vendored
Normal file
40
modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
pub struct Service<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> Service<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static {
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
Service {
|
||||
api_impl: api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::service::Service for Service<T, C>
|
||||
where
|
||||
T: Api<C> + Clone + Send + 'static,
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<Authorization>>{{/hasAuthMethods}} + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, C>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Future = Box<dyn Future<Item = Response<Self::ResBody>, Error = Self::Error> + Send>;
|
||||
|
||||
fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
|
||||
let api_impl = self.api_impl.clone();
|
||||
let (parts, body) = req.into_parts();
|
||||
let (method, uri, headers) = (parts.method, parts.uri, parts.headers);
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(uri.path());
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
{{!
|
||||
This match statement is duplicated below in `parse_operation_id()`.
|
||||
Please update both places if changing how this code is autogenerated.
|
||||
}}
|
||||
match &method {
|
||||
@@ -246,6 +246,49 @@ paths:
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
/register-callback:
|
||||
post:
|
||||
parameters:
|
||||
- name: url
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uri
|
||||
callbacks:
|
||||
callback:
|
||||
'{$request.query.url}/callback':
|
||||
post:
|
||||
responses:
|
||||
'204':
|
||||
description: OK
|
||||
responses:
|
||||
'204':
|
||||
description: OK
|
||||
/callback-with-header:
|
||||
post:
|
||||
parameters:
|
||||
- name: url
|
||||
in: query
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uri
|
||||
callbacks:
|
||||
callback:
|
||||
'{$request.query.url}/callback-with-header':
|
||||
post:
|
||||
parameters:
|
||||
- name: Information
|
||||
in: header
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: OK
|
||||
responses:
|
||||
'204':
|
||||
description: OK
|
||||
/rfc7807:
|
||||
get:
|
||||
responses:
|
||||
@@ -276,6 +319,7 @@ paths:
|
||||
application/merge-patch+json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/anotherXmlObject"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
authScheme:
|
||||
|
||||
@@ -50,7 +50,7 @@ url = {version = "1.5", optional = true}
|
||||
|
||||
# Client-specific
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -66,7 +66,8 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||
env_logger = "0.6"
|
||||
uuid = {version = "0.7", features = ["serde", "v4"]}
|
||||
|
||||
[[example]]
|
||||
name = "client"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate multipart_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
#[allow(unused_imports)]
|
||||
@@ -18,17 +18,17 @@ use multipart_v3::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
|
||||
"MultipartRelatedRequestPost",
|
||||
|
||||
"MultipartRequestPost",
|
||||
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -71,29 +71,26 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
match matches.value_of("operation") {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
match matches.value_of("operation") {
|
||||
Some("MultipartRelatedRequestPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.multipart_related_request_post(
|
||||
swagger::ByteArray(Vec::from("BINARY_DATA_HERE")),
|
||||
None,
|
||||
Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE")))
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("MultipartRequestPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.multipart_request_post(
|
||||
"string_field_example".to_string(),
|
||||
swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")),
|
||||
Some("optional_string_field_example".to_string()),
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
//! Main binary entry point for multipart_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate multipart_v3;
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate multipart_v3;
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = multipart_v3::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
multipart_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//! Main binary entry point for multipart_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate multipart_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate multipart_v3;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:80";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
//! Main library entry point for multipart_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
|
||||
use multipart_v3::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
multipart_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use multipart_v3::{
|
||||
Api,
|
||||
ApiError,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse,
|
||||
};
|
||||
use multipart_v3::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
fn multipart_related_request_post(
|
||||
&self,
|
||||
required_binary_field: swagger::ByteArray,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
optional_binary_field: Option<swagger::ByteArray>,
|
||||
context: &C) -> Box<Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("multipart_related_request_post({:?}, {:?}, {:?}) - X-Span-ID: {:?}", required_binary_field, object_field, optional_binary_field, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn multipart_request_post(
|
||||
&self,
|
||||
string_field: String,
|
||||
binary_field: swagger::ByteArray,
|
||||
optional_string_field: Option<String>,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
context: &C) -> Box<Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("multipart_request_post(\"{}\", {:?}, {:?}, {:?}) - X-Span-ID: {:?}", string_field, binary_field, optional_string_field, object_field, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
//! Main library entry point for multipart_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use multipart_v3::{Api, ApiError,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
use multipart_v3::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
|
||||
|
||||
fn multipart_related_request_post(&self, required_binary_field: swagger::ByteArray, object_field: Option<models::MultipartRequestObjectField>, optional_binary_field: Option<swagger::ByteArray>, context: &C) -> Box<Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("multipart_related_request_post({:?}, {:?}, {:?}) - X-Span-ID: {:?}", required_binary_field, object_field, optional_binary_field, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn multipart_request_post(&self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option<String>, object_field: Option<models::MultipartRequestObjectField>, context: &C) -> Box<Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("multipart_request_post(\"{}\", {:?}, {:?}, {:?}) - X-Span-ID: {:?}", string_field, binary_field, optional_string_field, object_field, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
use futures;
|
||||
use futures::{Future, Stream, future, stream};
|
||||
use hyper;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use hyper::{Body, Uri, Response};
|
||||
use hyper_tls::HttpsConnector;
|
||||
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
use futures;
|
||||
use futures::{Future, Stream};
|
||||
use futures::{future, stream};
|
||||
use serde_json;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
@@ -22,9 +18,11 @@ use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use swagger::client::Service;
|
||||
|
||||
use swagger::connector;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
use mime::Mime;
|
||||
use std::io::Cursor;
|
||||
use multipart::client::lazy::Multipart;
|
||||
@@ -32,11 +30,6 @@ use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_multipart::{Node, Part, generate_boundary, write_multipart};
|
||||
|
||||
use {Api,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
|
||||
use mimetypes;
|
||||
use models;
|
||||
use header;
|
||||
@@ -49,6 +42,11 @@ define_encode_set! {
|
||||
pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
|
||||
}
|
||||
|
||||
use {Api,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
|
||||
/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes.
|
||||
fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> {
|
||||
// First convert to Uri, since a base path is a subset of Uri.
|
||||
@@ -71,7 +69,10 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<S
|
||||
/// A client that implements the API by making HTTP calls out to a server.
|
||||
pub struct Client<F>
|
||||
{
|
||||
/// Inner service
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
|
||||
/// Base path of the API
|
||||
base_path: String,
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
pub fn try_new_http(
|
||||
base_path: &str,
|
||||
) -> Result<Self, ClientInitError> {
|
||||
let http_connector = swagger::http_connector();
|
||||
let http_connector = connector::http_connector();
|
||||
|
||||
Self::try_new_with_connector(base_path, Some("http"), http_connector)
|
||||
}
|
||||
@@ -152,7 +153,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
where
|
||||
CA: AsRef<Path>,
|
||||
{
|
||||
let https_connector = swagger::https_connector(ca_certificate);
|
||||
let https_connector = connector::https_connector(ca_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
|
||||
@@ -175,14 +176,14 @@ impl Client<hyper::client::ResponseFuture>
|
||||
D: AsRef<Path>,
|
||||
{
|
||||
let https_connector =
|
||||
swagger::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
connector::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Client<F>
|
||||
{
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::client::Service`
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
|
||||
///
|
||||
/// This allows adding custom wrappers around the underlying transport, for example for logging.
|
||||
pub fn try_new_with_client_service(
|
||||
@@ -196,12 +197,58 @@ impl<F> Client<F>
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type failing to create a Client
|
||||
#[derive(Debug)]
|
||||
pub enum ClientInitError {
|
||||
/// Invalid URL Scheme
|
||||
InvalidScheme,
|
||||
|
||||
/// Invalid URI
|
||||
InvalidUri(hyper::http::uri::InvalidUri),
|
||||
|
||||
/// Missing Hostname
|
||||
MissingHost,
|
||||
|
||||
/// SSL Connection Error
|
||||
SslError(openssl::error::ErrorStack)
|
||||
}
|
||||
|
||||
impl From<hyper::http::uri::InvalidUri> for ClientInitError {
|
||||
fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
|
||||
ClientInitError::InvalidUri(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<openssl::error::ErrorStack> for ClientInitError {
|
||||
fn from(err: openssl::error::ErrorStack) -> ClientInitError {
|
||||
ClientInitError::SslError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ClientInitError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s: &dyn fmt::Debug = self;
|
||||
s.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for ClientInitError {
|
||||
fn description(&self) -> &str {
|
||||
"Failed to produce a hyper client."
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> Api<C> for Client<F> where
|
||||
C: Has<XSpanIdString> ,
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
|
||||
fn multipart_related_request_post(&self, param_required_binary_field: swagger::ByteArray, param_object_field: Option<models::MultipartRequestObjectField>, param_optional_binary_field: Option<swagger::ByteArray>, context: &C) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send> {
|
||||
fn multipart_related_request_post(
|
||||
&self,
|
||||
param_required_binary_field: swagger::ByteArray,
|
||||
param_object_field: Option<models::MultipartRequestObjectField>,
|
||||
param_optional_binary_field: Option<swagger::ByteArray>,
|
||||
context: &C) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/multipart_related_request",
|
||||
self.base_path
|
||||
@@ -269,6 +316,7 @@ impl<C, F> Api<C> for Client<F> where
|
||||
body_parts.push(part);
|
||||
}
|
||||
|
||||
{
|
||||
let part = Node::Part(Part {
|
||||
headers: {
|
||||
let mut h = Headers::new();
|
||||
@@ -279,6 +327,7 @@ impl<C, F> Api<C> for Client<F> where
|
||||
body: param_required_binary_field.0,
|
||||
});
|
||||
body_parts.push(part);
|
||||
}
|
||||
|
||||
// Write the body into a vec.
|
||||
let mut body: Vec<u8> = vec![];
|
||||
@@ -297,14 +346,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -338,10 +385,16 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn multipart_request_post(&self, param_string_field: String, param_binary_field: swagger::ByteArray, param_optional_string_field: Option<String>, param_object_field: Option<models::MultipartRequestObjectField>, context: &C) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send> {
|
||||
fn multipart_request_post(
|
||||
&self,
|
||||
param_string_field: String,
|
||||
param_binary_field: swagger::ByteArray,
|
||||
param_optional_string_field: Option<String>,
|
||||
param_object_field: Option<models::MultipartRequestObjectField>,
|
||||
context: &C) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/multipart_request",
|
||||
self.base_path
|
||||
@@ -422,7 +475,6 @@ impl<C, F> Api<C> for Client<F> where
|
||||
|
||||
let filename = None as Option<&str> ;
|
||||
multipart.add_stream("binary_field", binary_field_cursor, filename, Some(binary_field_mime));
|
||||
|
||||
let mut fields = match multipart.prepare() {
|
||||
Ok(fields) => fields,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build request: {}", err)))),
|
||||
@@ -449,7 +501,6 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -483,39 +534,6 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClientInitError {
|
||||
InvalidScheme,
|
||||
InvalidUri(hyper::http::uri::InvalidUri),
|
||||
MissingHost,
|
||||
SslError(openssl::error::ErrorStack)
|
||||
}
|
||||
|
||||
impl From<hyper::http::uri::InvalidUri> for ClientInitError {
|
||||
fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
|
||||
ClientInitError::InvalidUri(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<openssl::error::ErrorStack> for ClientInitError {
|
||||
fn from(err: openssl::error::ErrorStack) -> ClientInitError {
|
||||
ClientInitError::SslError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ClientInitError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(self as &dyn fmt::Debug).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for ClientInitError {
|
||||
fn description(&self) -> &str {
|
||||
"Failed to produce a hyper client."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(any(feature = "server"))]
|
||||
#[cfg(feature = "server")]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
@@ -34,7 +34,7 @@ extern crate swagger;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate hyper;
|
||||
#[cfg(any(feature = "client"))]
|
||||
#[cfg(feature = "client")]
|
||||
extern crate hyper_tls;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate openssl;
|
||||
@@ -82,7 +82,6 @@ pub use futures::Future;
|
||||
pub const BASE_PATH: &'static str = "";
|
||||
pub const API_VERSION: &'static str = "1.0.7";
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum MultipartRelatedRequestPostResponse {
|
||||
/// OK
|
||||
@@ -95,26 +94,41 @@ pub enum MultipartRequestPostResponse {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
/// API
|
||||
pub trait Api<C> {
|
||||
fn multipart_related_request_post(
|
||||
&self,
|
||||
required_binary_field: swagger::ByteArray,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
optional_binary_field: Option<swagger::ByteArray>,
|
||||
context: &C) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multipart_related_request_post(&self, required_binary_field: swagger::ByteArray, object_field: Option<models::MultipartRequestObjectField>, optional_binary_field: Option<swagger::ByteArray>, context: &C) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multipart_request_post(&self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option<String>, object_field: Option<models::MultipartRequestObjectField>, context: &C) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>;
|
||||
fn multipart_request_post(
|
||||
&self,
|
||||
string_field: String,
|
||||
binary_field: swagger::ByteArray,
|
||||
optional_string_field: Option<String>,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
context: &C) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// API without a `Context`
|
||||
pub trait ApiNoContext {
|
||||
fn multipart_related_request_post(
|
||||
&self,
|
||||
required_binary_field: swagger::ByteArray,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
optional_binary_field: Option<swagger::ByteArray>,
|
||||
) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multipart_related_request_post(&self, required_binary_field: swagger::ByteArray, object_field: Option<models::MultipartRequestObjectField>, optional_binary_field: Option<swagger::ByteArray>) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multipart_request_post(&self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option<String>, object_field: Option<models::MultipartRequestObjectField>) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>;
|
||||
fn multipart_request_post(
|
||||
&self,
|
||||
string_field: String,
|
||||
binary_field: swagger::ByteArray,
|
||||
optional_string_field: Option<String>,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
@@ -131,14 +145,24 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
|
||||
}
|
||||
|
||||
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
|
||||
|
||||
|
||||
fn multipart_related_request_post(&self, required_binary_field: swagger::ByteArray, object_field: Option<models::MultipartRequestObjectField>, optional_binary_field: Option<swagger::ByteArray>) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send> {
|
||||
fn multipart_related_request_post(
|
||||
&self,
|
||||
required_binary_field: swagger::ByteArray,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
optional_binary_field: Option<swagger::ByteArray>,
|
||||
) -> Box<dyn Future<Item=MultipartRelatedRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().multipart_related_request_post(required_binary_field, object_field, optional_binary_field, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn multipart_request_post(&self, string_field: String, binary_field: swagger::ByteArray, optional_string_field: Option<String>, object_field: Option<models::MultipartRequestObjectField>) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send> {
|
||||
fn multipart_request_post(
|
||||
&self,
|
||||
string_field: String,
|
||||
binary_field: swagger::ByteArray,
|
||||
optional_string_field: Option<String>,
|
||||
object_field: Option<models::MultipartRequestObjectField>,
|
||||
) -> Box<dyn Future<Item=MultipartRequestPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().multipart_request_post(string_field, binary_field, optional_string_field, object_field, &self.context())
|
||||
}
|
||||
|
||||
@@ -149,7 +173,7 @@ pub mod client;
|
||||
|
||||
// Re-export Client as a top-level name
|
||||
#[cfg(feature = "client")]
|
||||
pub use self::client::Client;
|
||||
pub use client::Client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
@@ -158,5 +182,8 @@ pub mod server;
|
||||
#[cfg(feature = "server")]
|
||||
pub use self::server::Service;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod context;
|
||||
|
||||
pub mod models;
|
||||
pub mod header;
|
||||
|
||||
@@ -6,8 +6,8 @@ pub mod responses {
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
|
||||
/// Create &str objects for the request content types for MultipartRelatedRequestPost
|
||||
pub static MULTIPART_RELATED_REQUEST_POST: &str = "multipart/related";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,14 +5,16 @@ use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use url::form_urlencoded;
|
||||
use hyper_0_10::header::{Headers, ContentType};
|
||||
header! { (ContentId, "Content-ID") => [String] }
|
||||
use mime_0_2::{TopLevel, SubLevel, Mime as Mime2};
|
||||
@@ -20,20 +22,16 @@ use mime_multipart::{read_multipart_body, Node, Part};
|
||||
use multipart::server::Multipart;
|
||||
use multipart::server::save::SaveResult;
|
||||
|
||||
use mimetypes;
|
||||
|
||||
pub use swagger::auth::Authorization;
|
||||
|
||||
use {Api,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub mod context;
|
||||
pub use crate::context;
|
||||
|
||||
use {Api,
|
||||
MultipartRelatedRequestPostResponse,
|
||||
MultipartRequestPostResponse
|
||||
};
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
@@ -121,8 +119,6 @@ where
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
// This match statement is duplicated below in `parse_operation_id()`.
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
|
||||
// MultipartRelatedRequestPost - POST /multipart_related_request
|
||||
@@ -223,6 +219,7 @@ where
|
||||
.body(Body::from(format!("Missing required multipart/related parameter required_binary_field")))
|
||||
.expect("Unable to create Bad Request response for missing multipart/related parameter required_binary_field due to schema")))
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.multipart_related_request_post(
|
||||
param_required_binary_field,
|
||||
@@ -236,15 +233,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MultipartRelatedRequestPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -258,7 +251,6 @@ where
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
@@ -278,6 +270,7 @@ where
|
||||
.body(Body::from("Couldn't find valid multipart body".to_string()))
|
||||
.expect("Unable to create Bad Request response for incorrect boundary"))),
|
||||
};
|
||||
|
||||
// Form Body parameters (note that non-required body parameters will ignore garbage
|
||||
// values, rather than causing a 400 response). Produce warning header and logs for
|
||||
// any unused fields.
|
||||
@@ -311,8 +304,8 @@ where
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("string_field data does not match API definition: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
.body(Body::from(format!("string_field data does not match API definition : {}", e)))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter string_field")))
|
||||
}
|
||||
};
|
||||
string_field_model
|
||||
@@ -338,8 +331,8 @@ where
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("optional_string_field data does not match API definition: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
.body(Body::from(format!("optional_string_field data does not match API definition : {}", e)))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter optional_string_field")))
|
||||
}
|
||||
};
|
||||
optional_string_field_model
|
||||
@@ -362,8 +355,8 @@ where
|
||||
return Box::new(future::ok(
|
||||
Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("object_field data does not match API definition: {}", e)))
|
||||
.expect("Unable to create Bad Request response due to failure to process all message")))
|
||||
.body(Body::from(format!("object_field data does not match API definition : {}", e)))
|
||||
.expect("Unable to create Bad Request due to missing required form parameter object_field")))
|
||||
}
|
||||
};
|
||||
object_field_model
|
||||
@@ -403,15 +396,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MultipartRequestPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -461,10 +450,8 @@ impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
|
||||
// MultipartRelatedRequestPost - POST /multipart_related_request
|
||||
&hyper::Method::POST if path.matched(paths::ID_MULTIPART_RELATED_REQUEST) => Ok("MultipartRelatedRequestPost"),
|
||||
|
||||
// MultipartRequestPost - POST /multipart_request
|
||||
&hyper::Method::POST if path.matched(paths::ID_MULTIPART_REQUEST) => Ok("MultipartRequestPost"),
|
||||
_ => Err(()),
|
||||
|
||||
@@ -8,6 +8,7 @@ license = "Unlicense"
|
||||
[features]
|
||||
default = ["client", "server"]
|
||||
client = [
|
||||
"tokio-tls", "regex", "percent-encoding", "lazy_static",
|
||||
"serde_json", "serde_ignored", "hyper", "hyper-tls", "native-tls", "openssl", "tokio", "url"
|
||||
]
|
||||
server = [
|
||||
@@ -44,7 +45,7 @@ url = {version = "1.5", optional = true}
|
||||
|
||||
# Client-specific
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -60,6 +61,7 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
env_logger = "0.6"
|
||||
|
||||
[[example]]
|
||||
name = "client"
|
||||
|
||||
@@ -61,12 +61,14 @@ cargo run --example server
|
||||
To run a client, follow one of the following simple steps:
|
||||
|
||||
```
|
||||
cargo run --example client CallbackWithHeaderPost
|
||||
cargo run --example client MandatoryRequestHeaderGet
|
||||
cargo run --example client MergePatchJsonGet
|
||||
cargo run --example client MultigetGet
|
||||
cargo run --example client MultipleAuthSchemeGet
|
||||
cargo run --example client ParamgetGet
|
||||
cargo run --example client ReadonlyAuthSchemeGet
|
||||
cargo run --example client RegisterCallbackPost
|
||||
cargo run --example client RequiredOctetStreamPut
|
||||
cargo run --example client ResponsesWithHeadersGet
|
||||
cargo run --example client Rfc7807Get
|
||||
@@ -110,12 +112,14 @@ All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[****](docs/default_api.md#) | **POST** /callback-with-header |
|
||||
[****](docs/default_api.md#) | **GET** /mandatory-request-header |
|
||||
[****](docs/default_api.md#) | **GET** /merge-patch-json |
|
||||
[****](docs/default_api.md#) | **GET** /multiget | Get some stuff.
|
||||
[****](docs/default_api.md#) | **GET** /multiple_auth_scheme |
|
||||
[****](docs/default_api.md#) | **GET** /paramget | Get some stuff with parameters.
|
||||
[****](docs/default_api.md#) | **GET** /readonly_auth_scheme |
|
||||
[****](docs/default_api.md#) | **POST** /register-callback |
|
||||
[****](docs/default_api.md#) | **PUT** /required_octet_stream |
|
||||
[****](docs/default_api.md#) | **GET** /responses_with_headers |
|
||||
[****](docs/default_api.md#) | **GET** /rfc7807 |
|
||||
|
||||
@@ -241,6 +241,60 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: Success
|
||||
/register-callback:
|
||||
post:
|
||||
callbacks:
|
||||
callback:
|
||||
'{$request.query.url}/callback':
|
||||
post:
|
||||
operationId: callback_CallbackPost
|
||||
responses:
|
||||
"204":
|
||||
description: OK
|
||||
x-callback-request: true
|
||||
parameters:
|
||||
- explode: true
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
schema:
|
||||
format: uri
|
||||
type: string
|
||||
style: form
|
||||
responses:
|
||||
"204":
|
||||
description: OK
|
||||
/callback-with-header:
|
||||
post:
|
||||
callbacks:
|
||||
callback:
|
||||
'{$request.query.url}/callback-with-header':
|
||||
post:
|
||||
operationId: callback_CallbackWithHeaderPost
|
||||
parameters:
|
||||
- explode: false
|
||||
in: header
|
||||
name: Information
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
style: simple
|
||||
responses:
|
||||
"204":
|
||||
description: OK
|
||||
x-callback-request: true
|
||||
parameters:
|
||||
- explode: true
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
schema:
|
||||
format: uri
|
||||
type: string
|
||||
style: form
|
||||
responses:
|
||||
"204":
|
||||
description: OK
|
||||
/rfc7807:
|
||||
get:
|
||||
responses:
|
||||
|
||||
@@ -4,12 +4,14 @@ All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
****](default_api.md#) | **POST** /callback-with-header |
|
||||
****](default_api.md#) | **GET** /mandatory-request-header |
|
||||
****](default_api.md#) | **GET** /merge-patch-json |
|
||||
****](default_api.md#) | **GET** /multiget | Get some stuff.
|
||||
****](default_api.md#) | **GET** /multiple_auth_scheme |
|
||||
****](default_api.md#) | **GET** /paramget | Get some stuff with parameters.
|
||||
****](default_api.md#) | **GET** /readonly_auth_scheme |
|
||||
****](default_api.md#) | **POST** /register-callback |
|
||||
****](default_api.md#) | **PUT** /required_octet_stream |
|
||||
****](default_api.md#) | **GET** /responses_with_headers |
|
||||
****](default_api.md#) | **GET** /rfc7807 |
|
||||
@@ -22,6 +24,31 @@ Method | HTTP request | Description
|
||||
****](default_api.md#) | **PUT** /xml |
|
||||
|
||||
|
||||
# ****
|
||||
> (url)
|
||||
|
||||
|
||||
### Required Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**url** | **String**| |
|
||||
|
||||
### Return type
|
||||
|
||||
(empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: Not defined
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# ****
|
||||
> (x_header)
|
||||
|
||||
@@ -169,6 +196,31 @@ This endpoint does not need any parameter.
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# ****
|
||||
> (url)
|
||||
|
||||
|
||||
### Required Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**url** | **String**| |
|
||||
|
||||
### Return type
|
||||
|
||||
(empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: Not defined
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# ****
|
||||
> (body)
|
||||
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate openapi_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate native_tls;
|
||||
extern crate tokio_tls;
|
||||
extern crate uuid;
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
mod server;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
#[allow(unused_imports)]
|
||||
use openapi_v3::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
ApiError,
|
||||
CallbackWithHeaderPostResponse,
|
||||
MandatoryRequestHeaderGetResponse,
|
||||
MergePatchJsonGetResponse,
|
||||
MultigetGetResponse,
|
||||
MultipleAuthSchemeGetResponse,
|
||||
ParamgetGetResponse,
|
||||
ReadonlyAuthSchemeGetResponse,
|
||||
RegisterCallbackPostResponse,
|
||||
RequiredOctetStreamPutResponse,
|
||||
ResponsesWithHeadersGetResponse,
|
||||
Rfc7807GetResponse,
|
||||
@@ -32,45 +44,33 @@ use openapi_v3::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
XmlPutResponse
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
|
||||
"CallbackWithHeaderPost",
|
||||
"MandatoryRequestHeaderGet",
|
||||
|
||||
"MergePatchJsonGet",
|
||||
|
||||
"MultigetGet",
|
||||
|
||||
"MultipleAuthSchemeGet",
|
||||
|
||||
"ParamgetGet",
|
||||
|
||||
"ReadonlyAuthSchemeGet",
|
||||
|
||||
"RegisterCallbackPost",
|
||||
"RequiredOctetStreamPut",
|
||||
|
||||
"ResponsesWithHeadersGet",
|
||||
|
||||
"Rfc7807Get",
|
||||
|
||||
"UntypedPropertyGet",
|
||||
|
||||
"UuidGet",
|
||||
|
||||
"XmlExtraPost",
|
||||
|
||||
"XmlOtherPost",
|
||||
|
||||
"XmlOtherPut",
|
||||
|
||||
"XmlPost",
|
||||
|
||||
"XmlPut",
|
||||
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -113,131 +113,115 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
match matches.value_of("operation") {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
// We could do HTTPS here, but for simplicity we don't
|
||||
rt.spawn(server::create("127.0.0.1:8081", None));
|
||||
|
||||
match matches.value_of("operation") {
|
||||
Some("CallbackWithHeaderPost") => {
|
||||
let result = rt.block_on(client.callback_with_header_post(
|
||||
"url_example".to_string()
|
||||
));
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
Some("MandatoryRequestHeaderGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.mandatory_request_header_get(
|
||||
"x_header_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("MergePatchJsonGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.merge_patch_json_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("MultigetGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.multiget_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("MultipleAuthSchemeGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.multiple_auth_scheme_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("ParamgetGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.paramget_get(
|
||||
Some(serde_json::from_str::<uuid::Uuid>("38400000-8cf0-11bd-b23e-10b96e4ef00d").expect("Failed to parse JSON example")),
|
||||
None,
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("ReadonlyAuthSchemeGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.readonly_auth_scheme_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
Some("RegisterCallbackPost") => {
|
||||
let result = rt.block_on(client.register_callback_post(
|
||||
"url_example".to_string()
|
||||
));
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("RequiredOctetStreamPut") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.required_octet_stream_put(
|
||||
swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE"))
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("ResponsesWithHeadersGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.responses_with_headers_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Rfc7807Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.rfc7807_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("UntypedPropertyGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.untyped_property_get(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("UuidGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.uuid_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("XmlExtraPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.xml_extra_post(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("XmlOtherPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.xml_other_post(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("XmlOtherPut") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.xml_other_put(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("XmlPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.xml_post(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("XmlPut") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.xml_put(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
//! Main library entry point for openapi_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
use uuid;
|
||||
|
||||
use openapi_v3::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
use openapi_v3::{CallbackApi, ApiError};
|
||||
use openapi_v3::CallbackCallbackWithHeaderPostResponse;
|
||||
use openapi_v3::CallbackCallbackPostResponse;
|
||||
use openapi_v3::client::callbacks::MakeService;
|
||||
|
||||
impl<C> CallbackApi<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
fn callback_callback_with_header_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
information: Option<String>,
|
||||
context: &C) -> Box<Future<Item=CallbackCallbackWithHeaderPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("callback_callback_with_header_post({:?}) - X-Span-ID: {:?}", information, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn callback_callback_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
context: &C) -> Box<Future<Item=CallbackCallbackPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("callback_callback_post() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
//! Main binary entry point for openapi_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate openapi_v3;
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate openapi_v3;
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate uuid;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = openapi_v3::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//! Main binary entry point for openapi_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate openapi_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate openapi_v3;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate uuid;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:80";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
//! Main library entry point for openapi_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
use uuid;
|
||||
|
||||
use openapi_v3::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use openapi_v3::{
|
||||
Api,
|
||||
ApiError,
|
||||
CallbackWithHeaderPostResponse,
|
||||
MandatoryRequestHeaderGetResponse,
|
||||
MergePatchJsonGetResponse,
|
||||
MultigetGetResponse,
|
||||
MultipleAuthSchemeGetResponse,
|
||||
ParamgetGetResponse,
|
||||
ReadonlyAuthSchemeGetResponse,
|
||||
RegisterCallbackPostResponse,
|
||||
RequiredOctetStreamPutResponse,
|
||||
ResponsesWithHeadersGetResponse,
|
||||
Rfc7807GetResponse,
|
||||
UntypedPropertyGetResponse,
|
||||
UuidGetResponse,
|
||||
XmlExtraPostResponse,
|
||||
XmlOtherPostResponse,
|
||||
XmlOtherPutResponse,
|
||||
XmlPostResponse,
|
||||
XmlPutResponse,
|
||||
};
|
||||
use openapi_v3::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
fn callback_with_header_post(
|
||||
&self,
|
||||
url: String,
|
||||
context: &C) -> Box<Future<Item=CallbackWithHeaderPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("callback_with_header_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn mandatory_request_header_get(
|
||||
&self,
|
||||
x_header: String,
|
||||
context: &C) -> Box<Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("mandatory_request_header_get(\"{}\") - X-Span-ID: {:?}", x_header, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn merge_patch_json_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("merge_patch_json_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get some stuff.
|
||||
fn multiget_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=MultigetGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("multiget_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn multiple_auth_scheme_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("multiple_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get some stuff with parameters.
|
||||
fn paramget_get(
|
||||
&self,
|
||||
uuid: Option<uuid::Uuid>,
|
||||
some_object: Option<models::ObjectParam>,
|
||||
some_list: Option<models::MyIdList>,
|
||||
context: &C) -> Box<Future<Item=ParamgetGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("paramget_get({:?}, {:?}, {:?}) - X-Span-ID: {:?}", uuid, some_object, some_list, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn readonly_auth_scheme_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("readonly_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn register_callback_post(
|
||||
&self,
|
||||
url: String,
|
||||
context: &C) -> Box<Future<Item=RegisterCallbackPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("register_callback_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn required_octet_stream_put(
|
||||
&self,
|
||||
body: swagger::ByteArray,
|
||||
context: &C) -> Box<Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("required_octet_stream_put({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn responses_with_headers_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("responses_with_headers_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn rfc7807_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("rfc7807_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn untyped_property_get(
|
||||
&self,
|
||||
object_untyped_props: Option<models::ObjectUntypedProps>,
|
||||
context: &C) -> Box<Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("untyped_property_get({:?}) - X-Span-ID: {:?}", object_untyped_props, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn uuid_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=UuidGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("uuid_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn xml_extra_post(
|
||||
&self,
|
||||
duplicate_xml_object: Option<models::DuplicateXmlObject>,
|
||||
context: &C) -> Box<Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("xml_extra_post({:?}) - X-Span-ID: {:?}", duplicate_xml_object, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn xml_other_post(
|
||||
&self,
|
||||
another_xml_object: Option<models::AnotherXmlObject>,
|
||||
context: &C) -> Box<Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("xml_other_post({:?}) - X-Span-ID: {:?}", another_xml_object, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn xml_other_put(
|
||||
&self,
|
||||
string: Option<models::AnotherXmlArray>,
|
||||
context: &C) -> Box<Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("xml_other_put({:?}) - X-Span-ID: {:?}", string, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Post an array
|
||||
fn xml_post(
|
||||
&self,
|
||||
string: Option<models::XmlArray>,
|
||||
context: &C) -> Box<Future<Item=XmlPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("xml_post({:?}) - X-Span-ID: {:?}", string, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn xml_put(
|
||||
&self,
|
||||
xml_object: Option<models::XmlObject>,
|
||||
context: &C) -> Box<Future<Item=XmlPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("xml_put({:?}) - X-Span-ID: {:?}", xml_object, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
//! Main library entry point for openapi_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use uuid;
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use openapi_v3::{Api, ApiError,
|
||||
MandatoryRequestHeaderGetResponse,
|
||||
MergePatchJsonGetResponse,
|
||||
MultigetGetResponse,
|
||||
MultipleAuthSchemeGetResponse,
|
||||
ParamgetGetResponse,
|
||||
ReadonlyAuthSchemeGetResponse,
|
||||
RequiredOctetStreamPutResponse,
|
||||
ResponsesWithHeadersGetResponse,
|
||||
Rfc7807GetResponse,
|
||||
UntypedPropertyGetResponse,
|
||||
UuidGetResponse,
|
||||
XmlExtraPostResponse,
|
||||
XmlOtherPostResponse,
|
||||
XmlOtherPutResponse,
|
||||
XmlPostResponse,
|
||||
XmlPutResponse
|
||||
};
|
||||
use openapi_v3::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
|
||||
|
||||
fn mandatory_request_header_get(&self, x_header: String, context: &C) -> Box<Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("mandatory_request_header_get(\"{}\") - X-Span-ID: {:?}", x_header, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn merge_patch_json_get(&self, context: &C) -> Box<Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("merge_patch_json_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get some stuff.
|
||||
fn multiget_get(&self, context: &C) -> Box<Future<Item=MultigetGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("multiget_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn multiple_auth_scheme_get(&self, context: &C) -> Box<Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("multiple_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get some stuff with parameters.
|
||||
fn paramget_get(&self, uuid: Option<uuid::Uuid>, some_object: Option<models::ObjectParam>, some_list: Option<models::MyIdList>, context: &C) -> Box<Future<Item=ParamgetGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("paramget_get({:?}, {:?}, {:?}) - X-Span-ID: {:?}", uuid, some_object, some_list, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn readonly_auth_scheme_get(&self, context: &C) -> Box<Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("readonly_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn required_octet_stream_put(&self, body: swagger::ByteArray, context: &C) -> Box<Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("required_octet_stream_put({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn responses_with_headers_get(&self, context: &C) -> Box<Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("responses_with_headers_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn rfc7807_get(&self, context: &C) -> Box<Future<Item=Rfc7807GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("rfc7807_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn untyped_property_get(&self, object_untyped_props: Option<models::ObjectUntypedProps>, context: &C) -> Box<Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("untyped_property_get({:?}) - X-Span-ID: {:?}", object_untyped_props, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn uuid_get(&self, context: &C) -> Box<Future<Item=UuidGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("uuid_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn xml_extra_post(&self, duplicate_xml_object: Option<models::DuplicateXmlObject>, context: &C) -> Box<Future<Item=XmlExtraPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("xml_extra_post({:?}) - X-Span-ID: {:?}", duplicate_xml_object, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn xml_other_post(&self, another_xml_object: Option<models::AnotherXmlObject>, context: &C) -> Box<Future<Item=XmlOtherPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("xml_other_post({:?}) - X-Span-ID: {:?}", another_xml_object, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn xml_other_put(&self, string: Option<models::AnotherXmlArray>, context: &C) -> Box<Future<Item=XmlOtherPutResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("xml_other_put({:?}) - X-Span-ID: {:?}", string, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Post an array
|
||||
fn xml_post(&self, string: Option<models::XmlArray>, context: &C) -> Box<Future<Item=XmlPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("xml_post({:?}) - X-Span-ID: {:?}", string, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn xml_put(&self, xml_object: Option<models::XmlObject>, context: &C) -> Box<Future<Item=XmlPutResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("xml_put({:?}) - X-Span-ID: {:?}", xml_object, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap, BTreeSet};
|
||||
use std::marker::PhantomData;
|
||||
use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use uuid;
|
||||
use serde_xml_rs;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub use crate::context;
|
||||
|
||||
use CallbackApi as Api;
|
||||
use CallbackCallbackWithHeaderPostResponse;
|
||||
use CallbackCallbackPostResponse;
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
|
||||
r"^/(?P<request_query_url>.*)/callback$",
|
||||
r"^/(?P<request_query_url>.*)/callback-with-header$"
|
||||
])
|
||||
.expect("Unable to create global regex set");
|
||||
}
|
||||
pub static ID_REQUEST_QUERY_URL_CALLBACK: usize = 0;
|
||||
lazy_static! {
|
||||
pub static ref REGEX_REQUEST_QUERY_URL_CALLBACK: regex::Regex =
|
||||
regex::Regex::new(r"^/(?P<request_query_url>.*)/callback$")
|
||||
.expect("Unable to create regex for REQUEST_QUERY_URL_CALLBACK");
|
||||
}
|
||||
pub static ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER: usize = 1;
|
||||
lazy_static! {
|
||||
pub static ref REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER: regex::Regex =
|
||||
regex::Regex::new(r"^/(?P<request_query_url>.*)/callback-with-header$")
|
||||
.expect("Unable to create regex for REQUEST_QUERY_URL_CALLBACK_WITH_HEADER");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct MakeService<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> + Has<Option<Authorization>> + 'static
|
||||
{
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
MakeService {
|
||||
api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, SC, RC> hyper::service::MakeService<&'a SC> for MakeService<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> + Has<Option<Authorization>> + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, RC>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Service = Service<T, RC>;
|
||||
type Future = future::FutureResult<Self::Service, Self::MakeError>;
|
||||
type MakeError = Error;
|
||||
|
||||
fn make_service(&mut self, _ctx: &'a SC) -> Self::Future {
|
||||
future::FutureResult::from(Ok(Service::new(
|
||||
self.api_impl.clone(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct Service<T, RC> {
|
||||
api_impl: T,
|
||||
marker: PhantomData<RC>,
|
||||
}
|
||||
|
||||
impl<T, RC> Service<T, RC>
|
||||
where
|
||||
T: Api<RC> + Clone + Send + 'static,
|
||||
RC: Has<XSpanIdString> + Has<Option<Authorization>> + 'static {
|
||||
pub fn new(api_impl: T) -> Self {
|
||||
Service {
|
||||
api_impl: api_impl,
|
||||
marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> hyper::service::Service for Service<T, C>
|
||||
where
|
||||
T: Api<C> + Clone + Send + 'static,
|
||||
C: Has<XSpanIdString> + Has<Option<Authorization>> + 'static + Send
|
||||
{
|
||||
type ReqBody = ContextualPayload<Body, C>;
|
||||
type ResBody = Body;
|
||||
type Error = Error;
|
||||
type Future = Box<dyn Future<Item = Response<Self::ResBody>, Error = Self::Error> + Send>;
|
||||
|
||||
fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future {
|
||||
let api_impl = self.api_impl.clone();
|
||||
let (parts, body) = req.into_parts();
|
||||
let (method, uri, headers) = (parts.method, parts.uri, parts.headers);
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(uri.path());
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
match &method {
|
||||
|
||||
// CallbackCallbackWithHeaderPost - POST /{$request.query.url}/callback-with-header
|
||||
&hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => {
|
||||
// Path parameters
|
||||
let path: &str = &uri.path().to_string();
|
||||
let path_params =
|
||||
paths::REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER
|
||||
.captures(&path)
|
||||
.unwrap_or_else(||
|
||||
panic!("Path {} matched RE REQUEST_QUERY_URL_CALLBACK_WITH_HEADER in set but failed match against \"{}\"", path, paths::REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER.as_str())
|
||||
);
|
||||
|
||||
let callback_request_query_url = path_params["request_query_url"].to_string();
|
||||
// Header parameters
|
||||
let param_information = headers.get(HeaderName::from_static("information"));
|
||||
|
||||
let param_information = param_information.map(|p| {
|
||||
header::IntoHeaderValue::<String>::from((*p).clone()).0
|
||||
});
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
api_impl.callback_callback_with_header_post(
|
||||
callback_request_query_url,
|
||||
param_information,
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
CallbackCallbackWithHeaderPostResponse::OK
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
}}
|
||||
}) as Self::Future
|
||||
},
|
||||
|
||||
// CallbackCallbackPost - POST /{$request.query.url}/callback
|
||||
&hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => {
|
||||
// Path parameters
|
||||
let path: &str = &uri.path().to_string();
|
||||
let path_params =
|
||||
paths::REGEX_REQUEST_QUERY_URL_CALLBACK
|
||||
.captures(&path)
|
||||
.unwrap_or_else(||
|
||||
panic!("Path {} matched RE REQUEST_QUERY_URL_CALLBACK in set but failed match against \"{}\"", path, paths::REGEX_REQUEST_QUERY_URL_CALLBACK.as_str())
|
||||
);
|
||||
|
||||
let callback_request_query_url = path_params["request_query_url"].to_string();
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
api_impl.callback_callback_post(
|
||||
callback_request_query_url,
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
CallbackCallbackPostResponse::OK
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
}}
|
||||
}) as Self::Future
|
||||
},
|
||||
|
||||
_ => Box::new(future::ok(
|
||||
Response::builder().status(StatusCode::NOT_FOUND)
|
||||
.body(Body::empty())
|
||||
.expect("Unable to create Not Found response")
|
||||
)) as Self::Future
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, C> Clone for Service<T, C> where T: Clone
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Service {
|
||||
api_impl: self.api_impl.clone(),
|
||||
marker: self.marker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request parser for `Api`.
|
||||
pub struct ApiRequestParser;
|
||||
impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
// CallbackCallbackWithHeaderPost - POST /{$request.query.url}/callback-with-header
|
||||
&hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => Ok("CallbackCallbackWithHeaderPost"),
|
||||
// CallbackCallbackPost - POST /{$request.query.url}/callback
|
||||
&hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => Ok("CallbackCallbackPost"),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(any(feature = "server"))]
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
@@ -31,13 +31,13 @@ extern crate swagger;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate hyper;
|
||||
#[cfg(any(feature = "client"))]
|
||||
#[cfg(feature = "client")]
|
||||
extern crate hyper_tls;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate openssl;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate native_tls;
|
||||
#[cfg(feature = "server")]
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate percent_encoding;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate serde_json;
|
||||
@@ -73,6 +73,11 @@ pub use futures::Future;
|
||||
pub const BASE_PATH: &'static str = "";
|
||||
pub const API_VERSION: &'static str = "1.0.7";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CallbackWithHeaderPostResponse {
|
||||
/// OK
|
||||
OK
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum MandatoryRequestHeaderGetResponse {
|
||||
@@ -84,38 +89,38 @@ pub enum MandatoryRequestHeaderGetResponse {
|
||||
pub enum MergePatchJsonGetResponse {
|
||||
/// merge-patch+json-encoded response
|
||||
Merge
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum MultigetGetResponse {
|
||||
/// JSON rsp
|
||||
JSONRsp
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
,
|
||||
/// XML rsp
|
||||
XMLRsp
|
||||
( models::InlineResponse201 )
|
||||
(models::InlineResponse201)
|
||||
,
|
||||
/// octet rsp
|
||||
OctetRsp
|
||||
( swagger::ByteArray )
|
||||
(swagger::ByteArray)
|
||||
,
|
||||
/// string rsp
|
||||
StringRsp
|
||||
(String)
|
||||
(String)
|
||||
,
|
||||
/// Duplicate Response long text. One.
|
||||
DuplicateResponseLongText
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
,
|
||||
/// Duplicate Response long text. Two.
|
||||
DuplicateResponseLongText_2
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
,
|
||||
/// Duplicate Response long text. Three.
|
||||
DuplicateResponseLongText_3
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -128,7 +133,7 @@ pub enum MultipleAuthSchemeGetResponse {
|
||||
pub enum ParamgetGetResponse {
|
||||
/// JSON rsp
|
||||
JSONRsp
|
||||
( models::AnotherXmlObject )
|
||||
(models::AnotherXmlObject)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -137,6 +142,12 @@ pub enum ReadonlyAuthSchemeGetResponse {
|
||||
CheckThatLimitingToASingleRequiredAuthSchemeWorks
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum RegisterCallbackPostResponse {
|
||||
/// OK
|
||||
OK
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum RequiredOctetStreamPutResponse {
|
||||
/// OK
|
||||
@@ -147,17 +158,17 @@ pub enum RequiredOctetStreamPutResponse {
|
||||
pub enum ResponsesWithHeadersGetResponse {
|
||||
/// Success
|
||||
Success
|
||||
{
|
||||
body: String,
|
||||
{
|
||||
body: String,
|
||||
success_info: String,
|
||||
object_header: models::ObjectHeader,
|
||||
object_header: models::ObjectHeader
|
||||
}
|
||||
,
|
||||
/// Precondition Failed
|
||||
PreconditionFailed
|
||||
{
|
||||
further_info: String,
|
||||
failure_info: String,
|
||||
failure_info: String
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,15 +176,15 @@ pub enum ResponsesWithHeadersGetResponse {
|
||||
pub enum Rfc7807GetResponse {
|
||||
/// OK
|
||||
OK
|
||||
( models::ObjectWithArrayOfObjects )
|
||||
(models::ObjectWithArrayOfObjects)
|
||||
,
|
||||
/// NotFound
|
||||
NotFound
|
||||
( models::ObjectWithArrayOfObjects )
|
||||
(models::ObjectWithArrayOfObjects)
|
||||
,
|
||||
/// NotAcceptable
|
||||
NotAcceptable
|
||||
( models::ObjectWithArrayOfObjects )
|
||||
(models::ObjectWithArrayOfObjects)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -186,7 +197,7 @@ pub enum UntypedPropertyGetResponse {
|
||||
pub enum UuidGetResponse {
|
||||
/// Duplicate Response long text. One.
|
||||
DuplicateResponseLongText
|
||||
( uuid::Uuid )
|
||||
(uuid::Uuid)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -234,110 +245,187 @@ pub enum XmlPutResponse {
|
||||
BadRequest
|
||||
}
|
||||
|
||||
|
||||
/// API
|
||||
pub trait Api<C> {
|
||||
fn callback_with_header_post(
|
||||
&self,
|
||||
url: String,
|
||||
context: &C) -> Box<dyn Future<Item=CallbackWithHeaderPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn mandatory_request_header_get(
|
||||
&self,
|
||||
x_header: String,
|
||||
context: &C) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn mandatory_request_header_get(&self, x_header: String, context: &C) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn merge_patch_json_get(&self, context: &C) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>;
|
||||
fn merge_patch_json_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get some stuff.
|
||||
fn multiget_get(&self, context: &C) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send>;
|
||||
fn multiget_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multiple_auth_scheme_get(&self, context: &C) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
fn multiple_auth_scheme_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get some stuff with parameters.
|
||||
fn paramget_get(&self, uuid: Option<uuid::Uuid>, some_object: Option<models::ObjectParam>, some_list: Option<models::MyIdList>, context: &C) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send>;
|
||||
fn paramget_get(
|
||||
&self,
|
||||
uuid: Option<uuid::Uuid>,
|
||||
some_object: Option<models::ObjectParam>,
|
||||
some_list: Option<models::MyIdList>,
|
||||
context: &C) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn readonly_auth_scheme_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn readonly_auth_scheme_get(&self, context: &C) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
fn register_callback_post(
|
||||
&self,
|
||||
url: String,
|
||||
context: &C) -> Box<dyn Future<Item=RegisterCallbackPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn required_octet_stream_put(
|
||||
&self,
|
||||
body: swagger::ByteArray,
|
||||
context: &C) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn required_octet_stream_put(&self, body: swagger::ByteArray, context: &C) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>;
|
||||
fn responses_with_headers_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn rfc7807_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn responses_with_headers_get(&self, context: &C) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>;
|
||||
fn untyped_property_get(
|
||||
&self,
|
||||
object_untyped_props: Option<models::ObjectUntypedProps>,
|
||||
context: &C) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn uuid_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn rfc7807_get(&self, context: &C) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>;
|
||||
fn xml_extra_post(
|
||||
&self,
|
||||
duplicate_xml_object: Option<models::DuplicateXmlObject>,
|
||||
context: &C) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn xml_other_post(
|
||||
&self,
|
||||
another_xml_object: Option<models::AnotherXmlObject>,
|
||||
context: &C) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn untyped_property_get(&self, object_untyped_props: Option<models::ObjectUntypedProps>, context: &C) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn uuid_get(&self, context: &C) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_extra_post(&self, duplicate_xml_object: Option<models::DuplicateXmlObject>, context: &C) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_other_post(&self, another_xml_object: Option<models::AnotherXmlObject>, context: &C) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_other_put(&self, string: Option<models::AnotherXmlArray>, context: &C) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>;
|
||||
fn xml_other_put(
|
||||
&self,
|
||||
string: Option<models::AnotherXmlArray>,
|
||||
context: &C) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Post an array
|
||||
fn xml_post(&self, string: Option<models::XmlArray>, context: &C) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send>;
|
||||
fn xml_post(
|
||||
&self,
|
||||
string: Option<models::XmlArray>,
|
||||
context: &C) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_put(&self, xml_object: Option<models::XmlObject>, context: &C) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send>;
|
||||
fn xml_put(
|
||||
&self,
|
||||
xml_object: Option<models::XmlObject>,
|
||||
context: &C) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// API without a `Context`
|
||||
pub trait ApiNoContext {
|
||||
fn callback_with_header_post(
|
||||
&self,
|
||||
url: String,
|
||||
) -> Box<dyn Future<Item=CallbackWithHeaderPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn mandatory_request_header_get(
|
||||
&self,
|
||||
x_header: String,
|
||||
) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn mandatory_request_header_get(&self, x_header: String) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn merge_patch_json_get(&self) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>;
|
||||
fn merge_patch_json_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get some stuff.
|
||||
fn multiget_get(&self) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send>;
|
||||
fn multiget_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn multiple_auth_scheme_get(&self) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
fn multiple_auth_scheme_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get some stuff with parameters.
|
||||
fn paramget_get(&self, uuid: Option<uuid::Uuid>, some_object: Option<models::ObjectParam>, some_list: Option<models::MyIdList>) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send>;
|
||||
fn paramget_get(
|
||||
&self,
|
||||
uuid: Option<uuid::Uuid>,
|
||||
some_object: Option<models::ObjectParam>,
|
||||
some_list: Option<models::MyIdList>,
|
||||
) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn readonly_auth_scheme_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn readonly_auth_scheme_get(&self) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>;
|
||||
fn register_callback_post(
|
||||
&self,
|
||||
url: String,
|
||||
) -> Box<dyn Future<Item=RegisterCallbackPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn required_octet_stream_put(
|
||||
&self,
|
||||
body: swagger::ByteArray,
|
||||
) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn required_octet_stream_put(&self, body: swagger::ByteArray) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>;
|
||||
fn responses_with_headers_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn rfc7807_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn responses_with_headers_get(&self) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>;
|
||||
fn untyped_property_get(
|
||||
&self,
|
||||
object_untyped_props: Option<models::ObjectUntypedProps>,
|
||||
) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn uuid_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn rfc7807_get(&self) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>;
|
||||
fn xml_extra_post(
|
||||
&self,
|
||||
duplicate_xml_object: Option<models::DuplicateXmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn xml_other_post(
|
||||
&self,
|
||||
another_xml_object: Option<models::AnotherXmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn untyped_property_get(&self, object_untyped_props: Option<models::ObjectUntypedProps>) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn uuid_get(&self) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_extra_post(&self, duplicate_xml_object: Option<models::DuplicateXmlObject>) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_other_post(&self, another_xml_object: Option<models::AnotherXmlObject>) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_other_put(&self, string: Option<models::AnotherXmlArray>) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>;
|
||||
fn xml_other_put(
|
||||
&self,
|
||||
string: Option<models::AnotherXmlArray>,
|
||||
) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Post an array
|
||||
fn xml_post(&self, string: Option<models::XmlArray>) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send>;
|
||||
fn xml_post(
|
||||
&self,
|
||||
string: Option<models::XmlArray>,
|
||||
) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn xml_put(&self, xml_object: Option<models::XmlObject>) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send>;
|
||||
fn xml_put(
|
||||
&self,
|
||||
xml_object: Option<models::XmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
@@ -354,95 +442,237 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
|
||||
}
|
||||
|
||||
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
|
||||
fn callback_with_header_post(
|
||||
&self,
|
||||
url: String,
|
||||
) -> Box<dyn Future<Item=CallbackWithHeaderPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().callback_with_header_post(url, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn mandatory_request_header_get(&self, x_header: String) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send> {
|
||||
fn mandatory_request_header_get(
|
||||
&self,
|
||||
x_header: String,
|
||||
) -> Box<dyn Future<Item=MandatoryRequestHeaderGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().mandatory_request_header_get(x_header, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn merge_patch_json_get(&self) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send> {
|
||||
fn merge_patch_json_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MergePatchJsonGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().merge_patch_json_get(&self.context())
|
||||
}
|
||||
|
||||
/// Get some stuff.
|
||||
fn multiget_get(&self) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send> {
|
||||
fn multiget_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MultigetGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().multiget_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn multiple_auth_scheme_get(&self) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send> {
|
||||
fn multiple_auth_scheme_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=MultipleAuthSchemeGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().multiple_auth_scheme_get(&self.context())
|
||||
}
|
||||
|
||||
/// Get some stuff with parameters.
|
||||
fn paramget_get(&self, uuid: Option<uuid::Uuid>, some_object: Option<models::ObjectParam>, some_list: Option<models::MyIdList>) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send> {
|
||||
fn paramget_get(
|
||||
&self,
|
||||
uuid: Option<uuid::Uuid>,
|
||||
some_object: Option<models::ObjectParam>,
|
||||
some_list: Option<models::MyIdList>,
|
||||
) -> Box<dyn Future<Item=ParamgetGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().paramget_get(uuid, some_object, some_list, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn readonly_auth_scheme_get(&self) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send> {
|
||||
fn readonly_auth_scheme_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=ReadonlyAuthSchemeGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().readonly_auth_scheme_get(&self.context())
|
||||
}
|
||||
|
||||
fn register_callback_post(
|
||||
&self,
|
||||
url: String,
|
||||
) -> Box<dyn Future<Item=RegisterCallbackPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().register_callback_post(url, &self.context())
|
||||
}
|
||||
|
||||
fn required_octet_stream_put(&self, body: swagger::ByteArray) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send> {
|
||||
fn required_octet_stream_put(
|
||||
&self,
|
||||
body: swagger::ByteArray,
|
||||
) -> Box<dyn Future<Item=RequiredOctetStreamPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().required_octet_stream_put(body, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn responses_with_headers_get(&self) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send> {
|
||||
fn responses_with_headers_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=ResponsesWithHeadersGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().responses_with_headers_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn rfc7807_get(&self) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send> {
|
||||
fn rfc7807_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Rfc7807GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().rfc7807_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn untyped_property_get(&self, object_untyped_props: Option<models::ObjectUntypedProps>) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send> {
|
||||
fn untyped_property_get(
|
||||
&self,
|
||||
object_untyped_props: Option<models::ObjectUntypedProps>,
|
||||
) -> Box<dyn Future<Item=UntypedPropertyGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().untyped_property_get(object_untyped_props, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn uuid_get(&self) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send> {
|
||||
fn uuid_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=UuidGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().uuid_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn xml_extra_post(&self, duplicate_xml_object: Option<models::DuplicateXmlObject>) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send> {
|
||||
fn xml_extra_post(
|
||||
&self,
|
||||
duplicate_xml_object: Option<models::DuplicateXmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlExtraPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().xml_extra_post(duplicate_xml_object, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn xml_other_post(&self, another_xml_object: Option<models::AnotherXmlObject>) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send> {
|
||||
fn xml_other_post(
|
||||
&self,
|
||||
another_xml_object: Option<models::AnotherXmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlOtherPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().xml_other_post(another_xml_object, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn xml_other_put(&self, string: Option<models::AnotherXmlArray>) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send> {
|
||||
fn xml_other_put(
|
||||
&self,
|
||||
string: Option<models::AnotherXmlArray>,
|
||||
) -> Box<dyn Future<Item=XmlOtherPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().xml_other_put(string, &self.context())
|
||||
}
|
||||
|
||||
/// Post an array
|
||||
fn xml_post(&self, string: Option<models::XmlArray>) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send> {
|
||||
fn xml_post(
|
||||
&self,
|
||||
string: Option<models::XmlArray>,
|
||||
) -> Box<dyn Future<Item=XmlPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().xml_post(string, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn xml_put(&self, xml_object: Option<models::XmlObject>) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send> {
|
||||
fn xml_put(
|
||||
&self,
|
||||
xml_object: Option<models::XmlObject>,
|
||||
) -> Box<dyn Future<Item=XmlPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().xml_put(xml_object, &self.context())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CallbackCallbackWithHeaderPostResponse {
|
||||
/// OK
|
||||
OK
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum CallbackCallbackPostResponse {
|
||||
/// OK
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
/// Callback API
|
||||
pub trait CallbackApi<C> {
|
||||
fn callback_callback_with_header_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
information: Option<String>,
|
||||
context: &C) -> Box<dyn Future<Item=CallbackCallbackWithHeaderPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn callback_callback_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
context: &C) -> Box<dyn Future<Item=CallbackCallbackPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// Callback API without a `Context`
|
||||
pub trait CallbackApiNoContext {
|
||||
fn callback_callback_with_header_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
information: Option<String>,
|
||||
) -> Box<dyn Future<Item=CallbackCallbackWithHeaderPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn callback_callback_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
) -> Box<dyn Future<Item=CallbackCallbackPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// Trait to extend an API to make it easy to bind it to a context.
|
||||
pub trait CallbackContextWrapperExt<'a, C> where Self: Sized {
|
||||
/// Binds this API to a context.
|
||||
fn with_context(self: &'a Self, context: C) -> ContextWrapper<'a, Self, C>;
|
||||
}
|
||||
|
||||
impl<'a, T: CallbackApi<C> + Sized, C> CallbackContextWrapperExt<'a, C> for T {
|
||||
fn with_context(self: &'a T, context: C) -> ContextWrapper<'a, T, C> {
|
||||
ContextWrapper::<T, C>::new(self, context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: CallbackApi<C>, C> CallbackApiNoContext for ContextWrapper<'a, T, C> {
|
||||
fn callback_callback_with_header_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
information: Option<String>,
|
||||
) -> Box<dyn Future<Item=CallbackCallbackWithHeaderPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().callback_callback_with_header_post(
|
||||
callback_request_query_url,
|
||||
information,
|
||||
&self.context())
|
||||
}
|
||||
|
||||
fn callback_callback_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
) -> Box<dyn Future<Item=CallbackCallbackPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().callback_callback_post(
|
||||
callback_request_query_url,
|
||||
&self.context())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
pub mod client;
|
||||
|
||||
// Re-export Client as a top-level name
|
||||
#[cfg(feature = "client")]
|
||||
pub use self::client::Client;
|
||||
pub use client::Client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
@@ -451,5 +681,8 @@ pub mod server;
|
||||
#[cfg(feature = "server")]
|
||||
pub use self::server::Service;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
pub mod context;
|
||||
|
||||
pub mod models;
|
||||
pub mod header;
|
||||
|
||||
@@ -3,58 +3,74 @@
|
||||
pub mod responses {
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for MergePatchJsonGet
|
||||
pub static MERGE_PATCH_JSON_GET_MERGE: &str = "application/merge-patch+json";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_JSON_RSP: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_XML_RSP: &str = "application/xml";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_OCTET_RSP: &str = "application/octet-stream";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_STRING_RSP: &str = "text/plain";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_2: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the response content types for MultigetGet
|
||||
pub static MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_3: &str = "application/json";
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for ParamgetGet
|
||||
pub static PARAMGET_GET_JSON_RSP: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for ResponsesWithHeadersGet
|
||||
pub static RESPONSES_WITH_HEADERS_GET_SUCCESS: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the response content types for Rfc7807Get
|
||||
pub static RFC7807_GET_OK: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the response content types for Rfc7807Get
|
||||
pub static RFC7807_GET_NOT_FOUND: &str = "application/problem+json";
|
||||
|
||||
/// Create &str objects for the response content types for Rfc7807Get
|
||||
pub static RFC7807_GET_NOT_ACCEPTABLE: &str = "application/problem+xml";
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for UuidGet
|
||||
pub static UUID_GET_DUPLICATE_RESPONSE_LONG_TEXT: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for RequiredOctetStreamPut
|
||||
pub static REQUIRED_OCTET_STREAM_PUT: &str = "application/octet-stream";
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for UntypedPropertyGet
|
||||
pub static UNTYPED_PROPERTY_GET: &str = "application/json";
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for XmlExtraPost
|
||||
pub static XML_EXTRA_POST: &str = "application/xml";
|
||||
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
use futures;
|
||||
use futures::{Future, Stream, future, stream};
|
||||
use hyper;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use hyper::{Body, Uri, Response};
|
||||
use hyper_tls::HttpsConnector;
|
||||
use serde_json;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
use std::collections::{HashMap, BTreeMap};
|
||||
use std::io::{Read, Error, ErrorKind};
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
use swagger;
|
||||
use swagger::client::Service;
|
||||
use swagger::connector;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
use uuid;
|
||||
use serde_xml_rs;
|
||||
|
||||
use mimetypes;
|
||||
use models;
|
||||
use header;
|
||||
|
||||
define_encode_set! {
|
||||
/// This encode set is used for object IDs
|
||||
///
|
||||
/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`,
|
||||
/// the vertical bar (|) is encoded.
|
||||
pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
|
||||
}
|
||||
|
||||
use CallbackApi;
|
||||
use CallbackCallbackWithHeaderPostResponse;
|
||||
use CallbackCallbackPostResponse;
|
||||
|
||||
/// A client that implements the API by making HTTP calls out to a server.
|
||||
pub struct Client<F>
|
||||
{
|
||||
/// Inner service
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl<F> fmt::Debug for Client<F>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Client")
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Clone for Client<F>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Client {
|
||||
client_service: self.client_service.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Client<hyper::client::ResponseFuture>
|
||||
{
|
||||
/// Create a client with a custom implementation of hyper::client::Connect.
|
||||
///
|
||||
/// Intended for use with custom implementations of connect for e.g. protocol logging
|
||||
/// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection,
|
||||
/// this function should be used in conjunction with
|
||||
/// `swagger::{http_connector, https_connector, https_mutual_connector}`.
|
||||
///
|
||||
/// For ordinary tcp connections, prefer the use of `new_http`, `new_https`
|
||||
/// and `new_https_mutual`, to avoid introducing a dependency on the underlying transport layer.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `connector_fn` - Function which returns an implementation of `hyper::client::Connect`
|
||||
pub fn new_with_connector<C>(
|
||||
connector_fn: Box<dyn Fn() -> C + Send + Sync>,
|
||||
) -> Self where
|
||||
C: hyper::client::connect::Connect + 'static,
|
||||
C::Transport: 'static,
|
||||
C::Future: 'static,
|
||||
{
|
||||
let connector = connector_fn();
|
||||
|
||||
let client_service = Box::new(hyper::client::Client::builder().build(connector));
|
||||
|
||||
Client {
|
||||
client_service: Arc::new(client_service),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an HTTP client.
|
||||
pub fn new_http() -> Self {
|
||||
let http_connector = connector::http_connector();
|
||||
Self::new_with_connector(http_connector)
|
||||
}
|
||||
|
||||
/// Create a client with a TLS connection to the server.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `ca_certificate` - Path to CA certificate used to authenticate the server
|
||||
pub fn new_https<CA>(
|
||||
ca_certificate: CA,
|
||||
) -> Self where
|
||||
CA: AsRef<Path>,
|
||||
{
|
||||
let https_connector = connector::https_connector(ca_certificate);
|
||||
Self::new_with_connector(https_connector)
|
||||
}
|
||||
|
||||
/// Create a client with a mutually authenticated TLS connection to the server.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `ca_certificate` - Path to CA certificate used to authenticate the server
|
||||
/// * `client_key` - Path to the client private key
|
||||
/// * `client_certificate` - Path to the client's public certificate associated with the private key
|
||||
pub fn new_https_mutual<CA, K, D>(
|
||||
ca_certificate: CA,
|
||||
client_key: K,
|
||||
client_certificate: D,
|
||||
) -> Self
|
||||
where
|
||||
CA: AsRef<Path>,
|
||||
K: AsRef<Path>,
|
||||
D: AsRef<Path>,
|
||||
{
|
||||
let https_connector =
|
||||
connector::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
Self::new_with_connector(https_connector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Client<F>
|
||||
{
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
|
||||
///
|
||||
/// This allows adding custom wrappers around the underlying transport, for example for logging.
|
||||
pub fn new_with_client_service(
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
) -> Self {
|
||||
Client {
|
||||
client_service: client_service,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> CallbackApi<C> for Client<F> where
|
||||
C: Has<XSpanIdString> + Has<Option<AuthData>>,
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
fn callback_callback_with_header_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
param_information: Option<String>,
|
||||
context: &C) -> Box<dyn Future<Item=CallbackCallbackWithHeaderPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{request_query_url}/callback-with-header"
|
||||
,request_query_url=callback_request_query_url
|
||||
);
|
||||
|
||||
// Query parameters
|
||||
let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
|
||||
let query_string_str = query_string.finish();
|
||||
if !query_string_str.is_empty() {
|
||||
uri += "?";
|
||||
uri += &query_string_str;
|
||||
}
|
||||
|
||||
let uri = match Uri::from_str(&uri) {
|
||||
Ok(uri) => uri,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
|
||||
};
|
||||
|
||||
let mut request = match hyper::Request::builder()
|
||||
.method("POST")
|
||||
.uri(uri)
|
||||
.body(Body::empty()) {
|
||||
Ok(req) => req,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
// Header parameters
|
||||
param_information.map(|value| request.headers_mut().append(
|
||||
HeaderName::from_static("information"),
|
||||
header::IntoHeaderValue(value.clone()).into()));
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
match response.status().as_u16() {
|
||||
204 => {
|
||||
let body = response.into_body();
|
||||
Box::new(
|
||||
future::ok(
|
||||
CallbackCallbackWithHeaderPostResponse::OK
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
},
|
||||
code => {
|
||||
let headers = response.headers().clone();
|
||||
Box::new(response.into_body()
|
||||
.take(100)
|
||||
.concat2()
|
||||
.then(move |body|
|
||||
future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
|
||||
code,
|
||||
headers,
|
||||
match body {
|
||||
Ok(ref body) => match str::from_utf8(body) {
|
||||
Ok(body) => Cow::from(body),
|
||||
Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
|
||||
},
|
||||
Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
|
||||
})))
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn callback_callback_post(
|
||||
&self,
|
||||
callback_request_query_url: String,
|
||||
context: &C) -> Box<dyn Future<Item=CallbackCallbackPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{request_query_url}/callback"
|
||||
,request_query_url=callback_request_query_url
|
||||
);
|
||||
|
||||
// Query parameters
|
||||
let mut query_string = url::form_urlencoded::Serializer::new("".to_owned());
|
||||
let query_string_str = query_string.finish();
|
||||
if !query_string_str.is_empty() {
|
||||
uri += "?";
|
||||
uri += &query_string_str;
|
||||
}
|
||||
|
||||
let uri = match Uri::from_str(&uri) {
|
||||
Ok(uri) => uri,
|
||||
Err(err) => return Box::new(future::err(ApiError(format!("Unable to build URI: {}", err)))),
|
||||
};
|
||||
|
||||
let mut request = match hyper::Request::builder()
|
||||
.method("POST")
|
||||
.uri(uri)
|
||||
.body(Body::empty()) {
|
||||
Ok(req) => req,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
match response.status().as_u16() {
|
||||
204 => {
|
||||
let body = response.into_body();
|
||||
Box::new(
|
||||
future::ok(
|
||||
CallbackCallbackPostResponse::OK
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
},
|
||||
code => {
|
||||
let headers = response.headers().clone();
|
||||
Box::new(response.into_body()
|
||||
.take(100)
|
||||
.concat2()
|
||||
.then(move |body|
|
||||
future::err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}",
|
||||
code,
|
||||
headers,
|
||||
match body {
|
||||
Ok(ref body) => match str::from_utf8(body) {
|
||||
Ok(body) => Cow::from(body),
|
||||
Err(e) => Cow::from(format!("<Body was not UTF8: {:?}>", e)),
|
||||
},
|
||||
Err(e) => Cow::from(format!("<Failed to read body: {}>", e)),
|
||||
})))
|
||||
)
|
||||
) as Box<dyn Future<Item=_, Error=_> + Send>
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,28 +5,34 @@ use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use url::form_urlencoded;
|
||||
use serde_xml_rs;
|
||||
use uuid;
|
||||
use serde_xml_rs;
|
||||
|
||||
use mimetypes;
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub use swagger::auth::Authorization;
|
||||
pub use crate::context;
|
||||
|
||||
use {Api,
|
||||
CallbackWithHeaderPostResponse,
|
||||
MandatoryRequestHeaderGetResponse,
|
||||
MergePatchJsonGetResponse,
|
||||
MultigetGetResponse,
|
||||
MultipleAuthSchemeGetResponse,
|
||||
ParamgetGetResponse,
|
||||
ReadonlyAuthSchemeGetResponse,
|
||||
RegisterCallbackPostResponse,
|
||||
RequiredOctetStreamPutResponse,
|
||||
ResponsesWithHeadersGetResponse,
|
||||
Rfc7807GetResponse,
|
||||
@@ -37,25 +43,23 @@ use {Api,
|
||||
XmlOtherPutResponse,
|
||||
XmlPostResponse,
|
||||
XmlPutResponse
|
||||
};
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub mod context;
|
||||
pub mod callbacks;
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![
|
||||
r"^/callback-with-header$",
|
||||
r"^/mandatory-request-header$",
|
||||
r"^/merge-patch-json$",
|
||||
r"^/multiget$",
|
||||
r"^/multiple_auth_scheme$",
|
||||
r"^/paramget$",
|
||||
r"^/readonly_auth_scheme$",
|
||||
r"^/register-callback$",
|
||||
r"^/required_octet_stream$",
|
||||
r"^/responses_with_headers$",
|
||||
r"^/rfc7807$",
|
||||
@@ -67,20 +71,22 @@ mod paths {
|
||||
])
|
||||
.expect("Unable to create global regex set");
|
||||
}
|
||||
pub static ID_MANDATORY_REQUEST_HEADER: usize = 0;
|
||||
pub static ID_MERGE_PATCH_JSON: usize = 1;
|
||||
pub static ID_MULTIGET: usize = 2;
|
||||
pub static ID_MULTIPLE_AUTH_SCHEME: usize = 3;
|
||||
pub static ID_PARAMGET: usize = 4;
|
||||
pub static ID_READONLY_AUTH_SCHEME: usize = 5;
|
||||
pub static ID_REQUIRED_OCTET_STREAM: usize = 6;
|
||||
pub static ID_RESPONSES_WITH_HEADERS: usize = 7;
|
||||
pub static ID_RFC7807: usize = 8;
|
||||
pub static ID_UNTYPED_PROPERTY: usize = 9;
|
||||
pub static ID_UUID: usize = 10;
|
||||
pub static ID_XML: usize = 11;
|
||||
pub static ID_XML_EXTRA: usize = 12;
|
||||
pub static ID_XML_OTHER: usize = 13;
|
||||
pub static ID_CALLBACK_WITH_HEADER: usize = 0;
|
||||
pub static ID_MANDATORY_REQUEST_HEADER: usize = 1;
|
||||
pub static ID_MERGE_PATCH_JSON: usize = 2;
|
||||
pub static ID_MULTIGET: usize = 3;
|
||||
pub static ID_MULTIPLE_AUTH_SCHEME: usize = 4;
|
||||
pub static ID_PARAMGET: usize = 5;
|
||||
pub static ID_READONLY_AUTH_SCHEME: usize = 6;
|
||||
pub static ID_REGISTER_CALLBACK: usize = 7;
|
||||
pub static ID_REQUIRED_OCTET_STREAM: usize = 8;
|
||||
pub static ID_RESPONSES_WITH_HEADERS: usize = 9;
|
||||
pub static ID_RFC7807: usize = 10;
|
||||
pub static ID_UNTYPED_PROPERTY: usize = 11;
|
||||
pub static ID_UUID: usize = 12;
|
||||
pub static ID_XML: usize = 13;
|
||||
pub static ID_XML_EXTRA: usize = 14;
|
||||
pub static ID_XML_OTHER: usize = 15;
|
||||
}
|
||||
|
||||
pub struct MakeService<T, RC> {
|
||||
@@ -155,23 +161,76 @@ where
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
// This match statement is duplicated below in `parse_operation_id()`.
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
|
||||
// CallbackWithHeaderPost - POST /callback-with-header
|
||||
&hyper::Method::POST if path.matched(paths::ID_CALLBACK_WITH_HEADER) => {
|
||||
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
|
||||
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
|
||||
let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.to_owned())
|
||||
.nth(0);
|
||||
let param_url = match param_url {
|
||||
Some(param_url) => match param_url.parse::<String>() {
|
||||
Ok(param_url) => param_url,
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid query parameter url"))),
|
||||
},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required query parameter url"))
|
||||
.expect("Unable to create Bad Request response for missing qeury parameter url"))),
|
||||
};
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
api_impl.callback_with_header_post(
|
||||
param_url,
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
CallbackWithHeaderPostResponse::OK
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
}}
|
||||
}) as Self::Future
|
||||
},
|
||||
|
||||
// MandatoryRequestHeaderGet - GET /mandatory-request-header
|
||||
&hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => {
|
||||
|
||||
// Header parameters
|
||||
let param_x_header = headers.get(HeaderName::from_static("x-header"));
|
||||
|
||||
let param_x_header = match param_x_header)) {
|
||||
Some(v) => Some(header::IntoHeaderValue::<String>::from(v)).0),
|
||||
let param_x_header = match param_x_header {
|
||||
Some(v) => header::IntoHeaderValue::<String>::from((*v).clone()).0,
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing or invalid required header X-Header"))
|
||||
.expect("Unable to create Bad Request response for missing required header X-Header")))
|
||||
.expect("Unable to create Bad Request response for missing required header X-Header"))),
|
||||
};
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
@@ -185,15 +244,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MandatoryRequestHeaderGetResponse::Success
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -225,22 +280,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MergePatchJsonGetResponse::Merge
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MERGE_PATCH_JSON_GET_MERGE)
|
||||
.expect("Unable to create Content-Type header for MERGE_PATCH_JSON_GET_MERGE"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -274,118 +323,82 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MultigetGetResponse::JSONRsp
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_JSON_RSP)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_JSON_RSP"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::XMLRsp
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_XML_RSP)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_XML_RSP"));
|
||||
|
||||
let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::OctetRsp
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(202).expect("Unable to turn 202 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_OCTET_RSP)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_OCTET_RSP"));
|
||||
|
||||
let body = body.0;
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::StringRsp
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(203).expect("Unable to turn 203 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_STRING_RSP)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_STRING_RSP"));
|
||||
|
||||
let body = body;
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::DuplicateResponseLongText
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::DuplicateResponseLongText_2
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(205).expect("Unable to turn 205 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_2)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_2"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
MultigetGetResponse::DuplicateResponseLongText_3
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(206).expect("Unable to turn 206 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_3)
|
||||
.expect("Unable to create Content-Type header for MULTIGET_GET_DUPLICATE_RESPONSE_LONG_TEXT_3"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -436,6 +449,7 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
@@ -448,15 +462,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -476,21 +486,18 @@ where
|
||||
|
||||
// ParamgetGet - GET /paramget
|
||||
&hyper::Method::GET if path.matched(paths::ID_PARAMGET) => {
|
||||
|
||||
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
|
||||
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
|
||||
let param_uuid = query_params.iter().filter(|e| e.0 == "uuid").map(|e| e.1.to_owned())
|
||||
.nth(0);
|
||||
|
||||
let param_uuid = param_uuid.and_then(|param_uuid| param_uuid.parse::<>().ok());
|
||||
let param_some_object = query_params.iter().filter(|e| e.0 == "someObject").map(|e| e.1.to_owned())
|
||||
.nth(0);
|
||||
|
||||
let param_some_object = param_some_object.and_then(|param_some_object| param_some_object.parse::<>().ok());
|
||||
let param_some_list = query_params.iter().filter(|e| e.0 == "someList").map(|e| e.1.to_owned())
|
||||
.nth(0);
|
||||
|
||||
let param_some_list = param_some_list.and_then(|param_some_list| param_some_list.parse::<>().ok());
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
@@ -506,22 +513,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
ParamgetGetResponse::JSONRsp
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::PARAMGET_GET_JSON_RSP)
|
||||
.expect("Unable to create Content-Type header for PARAMGET_GET_JSON_RSP"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -571,6 +572,7 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
@@ -583,15 +585,66 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
// Application code returned an error. This should not happen, as the implementation should
|
||||
// return a valid response.
|
||||
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
|
||||
*response.body_mut() = Body::from("An internal error occurred");
|
||||
},
|
||||
}
|
||||
|
||||
future::ok(response)
|
||||
}
|
||||
))
|
||||
}}
|
||||
}) as Self::Future
|
||||
},
|
||||
|
||||
// RegisterCallbackPost - POST /register-callback
|
||||
&hyper::Method::POST if path.matched(paths::ID_REGISTER_CALLBACK) => {
|
||||
// Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response)
|
||||
let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::<Vec<_>>();
|
||||
let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.to_owned())
|
||||
.nth(0);
|
||||
let param_url = match param_url {
|
||||
Some(param_url) => match param_url.parse::<String>() {
|
||||
Ok(param_url) => param_url,
|
||||
Err(e) => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e)))
|
||||
.expect("Unable to create Bad Request response for invalid query parameter url"))),
|
||||
},
|
||||
None => return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.body(Body::from("Missing required query parameter url"))
|
||||
.expect("Unable to create Bad Request response for missing qeury parameter url"))),
|
||||
};
|
||||
|
||||
Box::new({
|
||||
{{
|
||||
Box::new(
|
||||
api_impl.register_callback_post(
|
||||
param_url,
|
||||
&context
|
||||
).then(move |result| {
|
||||
let mut response = Response::new(Body::empty());
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("x-span-id"),
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
RegisterCallbackPostResponse::OK
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -630,6 +683,7 @@ where
|
||||
.body(Body::from("Missing required body parameter body"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter body"))),
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.required_octet_stream_put(
|
||||
param_body,
|
||||
@@ -641,15 +695,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
RequiredOctetStreamPutResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -687,19 +737,14 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
ResponsesWithHeadersGetResponse::Success
|
||||
|
||||
{
|
||||
body,
|
||||
success_info,
|
||||
|
||||
object_header
|
||||
}
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
response.headers_mut().insert(
|
||||
@@ -710,23 +755,18 @@ where
|
||||
HeaderName::from_static("object-header"),
|
||||
header::IntoHeaderValue(object_header).into()
|
||||
);
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::RESPONSES_WITH_HEADERS_GET_SUCCESS)
|
||||
.expect("Unable to create Content-Type header for RESPONSES_WITH_HEADERS_GET_SUCCESS"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
ResponsesWithHeadersGetResponse::PreconditionFailed
|
||||
|
||||
|
||||
{
|
||||
further_info,
|
||||
failure_info
|
||||
}
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(412).expect("Unable to turn 412 into a StatusCode");
|
||||
response.headers_mut().insert(
|
||||
@@ -737,7 +777,6 @@ where
|
||||
HeaderName::from_static("failure-info"),
|
||||
header::IntoHeaderValue(failure_info).into()
|
||||
);
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -769,54 +808,38 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Rfc7807GetResponse::OK
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::RFC7807_GET_OK)
|
||||
.expect("Unable to create Content-Type header for RFC7807_GET_OK"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
Rfc7807GetResponse::NotFound
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::RFC7807_GET_NOT_FOUND)
|
||||
.expect("Unable to create Content-Type header for RFC7807_GET_NOT_FOUND"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
Rfc7807GetResponse::NotAcceptable
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(406).expect("Unable to turn 406 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::RFC7807_GET_NOT_ACCEPTABLE)
|
||||
.expect("Unable to create Content-Type header for RFC7807_GET_NOT_ACCEPTABLE"));
|
||||
|
||||
let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -858,6 +881,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.untyped_property_get(
|
||||
param_object_untyped_props,
|
||||
@@ -869,7 +893,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -880,11 +903,8 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -922,22 +942,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
UuidGetResponse::DuplicateResponseLongText
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::UUID_GET_DUPLICATE_RESPONSE_LONG_TEXT)
|
||||
.expect("Unable to create Content-Type header for UUID_GET_DUPLICATE_RESPONSE_LONG_TEXT"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -979,6 +993,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.xml_extra_post(
|
||||
param_duplicate_xml_object,
|
||||
@@ -990,7 +1005,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -1001,18 +1015,12 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
XmlExtraPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
XmlExtraPostResponse::BadRequest
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1058,6 +1066,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.xml_other_post(
|
||||
param_another_xml_object,
|
||||
@@ -1069,7 +1078,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -1080,18 +1088,12 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
XmlOtherPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
XmlOtherPostResponse::BadRequest
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1137,6 +1139,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.xml_other_put(
|
||||
param_string,
|
||||
@@ -1148,7 +1151,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -1159,18 +1161,12 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
XmlOtherPutResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
XmlOtherPutResponse::BadRequest
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1216,6 +1212,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.xml_post(
|
||||
param_string,
|
||||
@@ -1227,7 +1224,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -1238,18 +1234,12 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
XmlPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
XmlPostResponse::BadRequest
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1295,6 +1285,7 @@ where
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.xml_put(
|
||||
param_xml_object,
|
||||
@@ -1306,7 +1297,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -1317,18 +1307,12 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
XmlPutResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode");
|
||||
|
||||
},
|
||||
XmlPutResponse::BadRequest
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1377,52 +1361,40 @@ impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
|
||||
// CallbackWithHeaderPost - POST /callback-with-header
|
||||
&hyper::Method::POST if path.matched(paths::ID_CALLBACK_WITH_HEADER) => Ok("CallbackWithHeaderPost"),
|
||||
// MandatoryRequestHeaderGet - GET /mandatory-request-header
|
||||
&hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => Ok("MandatoryRequestHeaderGet"),
|
||||
|
||||
// MergePatchJsonGet - GET /merge-patch-json
|
||||
&hyper::Method::GET if path.matched(paths::ID_MERGE_PATCH_JSON) => Ok("MergePatchJsonGet"),
|
||||
|
||||
// MultigetGet - GET /multiget
|
||||
&hyper::Method::GET if path.matched(paths::ID_MULTIGET) => Ok("MultigetGet"),
|
||||
|
||||
// MultipleAuthSchemeGet - GET /multiple_auth_scheme
|
||||
&hyper::Method::GET if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => Ok("MultipleAuthSchemeGet"),
|
||||
|
||||
// ParamgetGet - GET /paramget
|
||||
&hyper::Method::GET if path.matched(paths::ID_PARAMGET) => Ok("ParamgetGet"),
|
||||
|
||||
// ReadonlyAuthSchemeGet - GET /readonly_auth_scheme
|
||||
&hyper::Method::GET if path.matched(paths::ID_READONLY_AUTH_SCHEME) => Ok("ReadonlyAuthSchemeGet"),
|
||||
|
||||
// RegisterCallbackPost - POST /register-callback
|
||||
&hyper::Method::POST if path.matched(paths::ID_REGISTER_CALLBACK) => Ok("RegisterCallbackPost"),
|
||||
// RequiredOctetStreamPut - PUT /required_octet_stream
|
||||
&hyper::Method::PUT if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => Ok("RequiredOctetStreamPut"),
|
||||
|
||||
// ResponsesWithHeadersGet - GET /responses_with_headers
|
||||
&hyper::Method::GET if path.matched(paths::ID_RESPONSES_WITH_HEADERS) => Ok("ResponsesWithHeadersGet"),
|
||||
|
||||
// Rfc7807Get - GET /rfc7807
|
||||
&hyper::Method::GET if path.matched(paths::ID_RFC7807) => Ok("Rfc7807Get"),
|
||||
|
||||
// UntypedPropertyGet - GET /untyped_property
|
||||
&hyper::Method::GET if path.matched(paths::ID_UNTYPED_PROPERTY) => Ok("UntypedPropertyGet"),
|
||||
|
||||
// UuidGet - GET /uuid
|
||||
&hyper::Method::GET if path.matched(paths::ID_UUID) => Ok("UuidGet"),
|
||||
|
||||
// XmlExtraPost - POST /xml_extra
|
||||
&hyper::Method::POST if path.matched(paths::ID_XML_EXTRA) => Ok("XmlExtraPost"),
|
||||
|
||||
// XmlOtherPost - POST /xml_other
|
||||
&hyper::Method::POST if path.matched(paths::ID_XML_OTHER) => Ok("XmlOtherPost"),
|
||||
|
||||
// XmlOtherPut - PUT /xml_other
|
||||
&hyper::Method::PUT if path.matched(paths::ID_XML_OTHER) => Ok("XmlOtherPut"),
|
||||
|
||||
// XmlPost - POST /xml
|
||||
&hyper::Method::POST if path.matched(paths::ID_XML) => Ok("XmlPost"),
|
||||
|
||||
// XmlPut - PUT /xml
|
||||
&hyper::Method::PUT if path.matched(paths::ID_XML) => Ok("XmlPut"),
|
||||
_ => Err(()),
|
||||
|
||||
@@ -40,7 +40,7 @@ url = {version = "1.5", optional = true}
|
||||
|
||||
# Client-specific
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -56,7 +56,8 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||
env_logger = "0.6"
|
||||
uuid = {version = "0.7", features = ["serde", "v4"]}
|
||||
|
||||
[[example]]
|
||||
name = "client"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate ops_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
#[allow(unused_imports)]
|
||||
@@ -53,87 +53,52 @@ use ops_v3::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
Op9GetResponse
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
|
||||
"Op10Get",
|
||||
|
||||
"Op11Get",
|
||||
|
||||
"Op12Get",
|
||||
|
||||
"Op13Get",
|
||||
|
||||
"Op14Get",
|
||||
|
||||
"Op15Get",
|
||||
|
||||
"Op16Get",
|
||||
|
||||
"Op17Get",
|
||||
|
||||
"Op18Get",
|
||||
|
||||
"Op19Get",
|
||||
|
||||
"Op1Get",
|
||||
|
||||
"Op20Get",
|
||||
|
||||
"Op21Get",
|
||||
|
||||
"Op22Get",
|
||||
|
||||
"Op23Get",
|
||||
|
||||
"Op24Get",
|
||||
|
||||
"Op25Get",
|
||||
|
||||
"Op26Get",
|
||||
|
||||
"Op27Get",
|
||||
|
||||
"Op28Get",
|
||||
|
||||
"Op29Get",
|
||||
|
||||
"Op2Get",
|
||||
|
||||
"Op30Get",
|
||||
|
||||
"Op31Get",
|
||||
|
||||
"Op32Get",
|
||||
|
||||
"Op33Get",
|
||||
|
||||
"Op34Get",
|
||||
|
||||
"Op35Get",
|
||||
|
||||
"Op36Get",
|
||||
|
||||
"Op37Get",
|
||||
|
||||
"Op3Get",
|
||||
|
||||
"Op4Get",
|
||||
|
||||
"Op5Get",
|
||||
|
||||
"Op6Get",
|
||||
|
||||
"Op7Get",
|
||||
|
||||
"Op8Get",
|
||||
|
||||
"Op9Get",
|
||||
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -176,267 +141,194 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
match matches.value_of("operation") {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
match matches.value_of("operation") {
|
||||
Some("Op10Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op10_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op11Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op11_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op12Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op12_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op13Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op13_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op14Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op14_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op15Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op15_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op16Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op16_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op17Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op17_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op18Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op18_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op19Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op19_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op1Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op1_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op20Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op20_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op21Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op21_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op22Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op22_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op23Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op23_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op24Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op24_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op25Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op25_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op26Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op26_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op27Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op27_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op28Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op28_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op29Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op29_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op2Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op2_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op30Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op30_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op31Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op31_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op32Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op32_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op33Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op33_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op34Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op34_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op35Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op35_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op36Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op36_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op37Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op37_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op3Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op3_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op4Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op4_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op5Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op5_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op6Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op6_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op7Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op7_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op8Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op8_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("Op9Get") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.op9_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
//! Main binary entry point for ops_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate ops_v3;
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate ops_v3;
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = ops_v3::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
ops_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//! Main binary entry point for ops_v3 implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate ops_v3;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate ops_v3;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:80";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
//! Main library entry point for ops_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
|
||||
use ops_v3::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
ops_v3::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use ops_v3::{
|
||||
Api,
|
||||
ApiError,
|
||||
Op10GetResponse,
|
||||
Op11GetResponse,
|
||||
Op12GetResponse,
|
||||
Op13GetResponse,
|
||||
Op14GetResponse,
|
||||
Op15GetResponse,
|
||||
Op16GetResponse,
|
||||
Op17GetResponse,
|
||||
Op18GetResponse,
|
||||
Op19GetResponse,
|
||||
Op1GetResponse,
|
||||
Op20GetResponse,
|
||||
Op21GetResponse,
|
||||
Op22GetResponse,
|
||||
Op23GetResponse,
|
||||
Op24GetResponse,
|
||||
Op25GetResponse,
|
||||
Op26GetResponse,
|
||||
Op27GetResponse,
|
||||
Op28GetResponse,
|
||||
Op29GetResponse,
|
||||
Op2GetResponse,
|
||||
Op30GetResponse,
|
||||
Op31GetResponse,
|
||||
Op32GetResponse,
|
||||
Op33GetResponse,
|
||||
Op34GetResponse,
|
||||
Op35GetResponse,
|
||||
Op36GetResponse,
|
||||
Op37GetResponse,
|
||||
Op3GetResponse,
|
||||
Op4GetResponse,
|
||||
Op5GetResponse,
|
||||
Op6GetResponse,
|
||||
Op7GetResponse,
|
||||
Op8GetResponse,
|
||||
Op9GetResponse,
|
||||
};
|
||||
use ops_v3::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
fn op10_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op10GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op10_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op11_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op11GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op11_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op12_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op12GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op12_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op13_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op13GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op13_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op14_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op14GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op14_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op15_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op15GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op15_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op16_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op16GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op16_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op17_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op17GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op17_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op18_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op18GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op18_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op19_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op19GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op19_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op1_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op1GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op1_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op20_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op20GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op20_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op21_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op21GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op21_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op22_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op22GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op22_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op23_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op23GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op23_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op24_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op24GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op24_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op25_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op25GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op25_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op26_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op26GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op26_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op27_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op27GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op27_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op28_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op28GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op28_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op29_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op29GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op29_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op2_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op2GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op2_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op30_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op30GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op30_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op31_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op31GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op31_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op32_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op32GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op32_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op33_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op33GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op33_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op34_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op34GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op34_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op35_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op35GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op35_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op36_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op36GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op36_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op37_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op37GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op37_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op3_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op3GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op3_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op4_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op4GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op4_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op5_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op5GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op5_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op6_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op6GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op6_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op7_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op7GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op7_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op8_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op8GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op8_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn op9_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Op9GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("op9_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
//! Main library entry point for ops_v3 implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use ops_v3::{Api, ApiError,
|
||||
Op10GetResponse,
|
||||
Op11GetResponse,
|
||||
Op12GetResponse,
|
||||
Op13GetResponse,
|
||||
Op14GetResponse,
|
||||
Op15GetResponse,
|
||||
Op16GetResponse,
|
||||
Op17GetResponse,
|
||||
Op18GetResponse,
|
||||
Op19GetResponse,
|
||||
Op1GetResponse,
|
||||
Op20GetResponse,
|
||||
Op21GetResponse,
|
||||
Op22GetResponse,
|
||||
Op23GetResponse,
|
||||
Op24GetResponse,
|
||||
Op25GetResponse,
|
||||
Op26GetResponse,
|
||||
Op27GetResponse,
|
||||
Op28GetResponse,
|
||||
Op29GetResponse,
|
||||
Op2GetResponse,
|
||||
Op30GetResponse,
|
||||
Op31GetResponse,
|
||||
Op32GetResponse,
|
||||
Op33GetResponse,
|
||||
Op34GetResponse,
|
||||
Op35GetResponse,
|
||||
Op36GetResponse,
|
||||
Op37GetResponse,
|
||||
Op3GetResponse,
|
||||
Op4GetResponse,
|
||||
Op5GetResponse,
|
||||
Op6GetResponse,
|
||||
Op7GetResponse,
|
||||
Op8GetResponse,
|
||||
Op9GetResponse
|
||||
};
|
||||
use ops_v3::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
|
||||
|
||||
fn op10_get(&self, context: &C) -> Box<Future<Item=Op10GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op10_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op11_get(&self, context: &C) -> Box<Future<Item=Op11GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op11_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op12_get(&self, context: &C) -> Box<Future<Item=Op12GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op12_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op13_get(&self, context: &C) -> Box<Future<Item=Op13GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op13_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op14_get(&self, context: &C) -> Box<Future<Item=Op14GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op14_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op15_get(&self, context: &C) -> Box<Future<Item=Op15GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op15_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op16_get(&self, context: &C) -> Box<Future<Item=Op16GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op16_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op17_get(&self, context: &C) -> Box<Future<Item=Op17GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op17_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op18_get(&self, context: &C) -> Box<Future<Item=Op18GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op18_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op19_get(&self, context: &C) -> Box<Future<Item=Op19GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op19_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op1_get(&self, context: &C) -> Box<Future<Item=Op1GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op1_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op20_get(&self, context: &C) -> Box<Future<Item=Op20GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op20_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op21_get(&self, context: &C) -> Box<Future<Item=Op21GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op21_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op22_get(&self, context: &C) -> Box<Future<Item=Op22GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op22_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op23_get(&self, context: &C) -> Box<Future<Item=Op23GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op23_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op24_get(&self, context: &C) -> Box<Future<Item=Op24GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op24_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op25_get(&self, context: &C) -> Box<Future<Item=Op25GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op25_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op26_get(&self, context: &C) -> Box<Future<Item=Op26GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op26_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op27_get(&self, context: &C) -> Box<Future<Item=Op27GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op27_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op28_get(&self, context: &C) -> Box<Future<Item=Op28GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op28_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op29_get(&self, context: &C) -> Box<Future<Item=Op29GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op29_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op2_get(&self, context: &C) -> Box<Future<Item=Op2GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op2_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op30_get(&self, context: &C) -> Box<Future<Item=Op30GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op30_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op31_get(&self, context: &C) -> Box<Future<Item=Op31GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op31_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op32_get(&self, context: &C) -> Box<Future<Item=Op32GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op32_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op33_get(&self, context: &C) -> Box<Future<Item=Op33GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op33_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op34_get(&self, context: &C) -> Box<Future<Item=Op34GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op34_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op35_get(&self, context: &C) -> Box<Future<Item=Op35GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op35_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op36_get(&self, context: &C) -> Box<Future<Item=Op36GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op36_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op37_get(&self, context: &C) -> Box<Future<Item=Op37GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op37_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op3_get(&self, context: &C) -> Box<Future<Item=Op3GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op3_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op4_get(&self, context: &C) -> Box<Future<Item=Op4GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op4_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op5_get(&self, context: &C) -> Box<Future<Item=Op5GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op5_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op6_get(&self, context: &C) -> Box<Future<Item=Op6GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op6_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op7_get(&self, context: &C) -> Box<Future<Item=Op7GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op7_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op8_get(&self, context: &C) -> Box<Future<Item=Op8GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op8_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn op9_get(&self, context: &C) -> Box<Future<Item=Op9GetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("op9_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(any(feature = "server"))]
|
||||
#[cfg(feature = "server")]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
@@ -31,7 +31,7 @@ extern crate swagger;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate hyper;
|
||||
#[cfg(any(feature = "client"))]
|
||||
#[cfg(feature = "client")]
|
||||
extern crate hyper_tls;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate openssl;
|
||||
@@ -73,7 +73,6 @@ pub use futures::Future;
|
||||
pub const BASE_PATH: &'static str = "";
|
||||
pub const API_VERSION: &'static str = "0.0.1";
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Op10GetResponse {
|
||||
/// OK
|
||||
@@ -296,236 +295,307 @@ pub enum Op9GetResponse {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
/// API
|
||||
pub trait Api<C> {
|
||||
fn op10_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op11_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op10_get(&self, context: &C) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send>;
|
||||
fn op12_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op13_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op11_get(&self, context: &C) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send>;
|
||||
fn op14_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op15_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op12_get(&self, context: &C) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send>;
|
||||
fn op16_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op17_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op13_get(&self, context: &C) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send>;
|
||||
fn op18_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op19_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op14_get(&self, context: &C) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send>;
|
||||
fn op1_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op20_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op15_get(&self, context: &C) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send>;
|
||||
fn op21_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op22_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op16_get(&self, context: &C) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send>;
|
||||
fn op23_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op24_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op17_get(&self, context: &C) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send>;
|
||||
fn op25_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op26_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op18_get(&self, context: &C) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send>;
|
||||
fn op27_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op28_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op19_get(&self, context: &C) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send>;
|
||||
fn op29_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op2_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op1_get(&self, context: &C) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send>;
|
||||
fn op30_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op31_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op20_get(&self, context: &C) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send>;
|
||||
fn op32_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op33_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op21_get(&self, context: &C) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send>;
|
||||
fn op34_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op35_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op22_get(&self, context: &C) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send>;
|
||||
fn op36_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op37_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op23_get(&self, context: &C) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send>;
|
||||
fn op3_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op4_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op24_get(&self, context: &C) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send>;
|
||||
fn op5_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op6_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op25_get(&self, context: &C) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send>;
|
||||
fn op7_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op8_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op26_get(&self, context: &C) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op27_get(&self, context: &C) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op28_get(&self, context: &C) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op29_get(&self, context: &C) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op2_get(&self, context: &C) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op30_get(&self, context: &C) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op31_get(&self, context: &C) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op32_get(&self, context: &C) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op33_get(&self, context: &C) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op34_get(&self, context: &C) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op35_get(&self, context: &C) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op36_get(&self, context: &C) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op37_get(&self, context: &C) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op3_get(&self, context: &C) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op4_get(&self, context: &C) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op5_get(&self, context: &C) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op6_get(&self, context: &C) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op7_get(&self, context: &C) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op8_get(&self, context: &C) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op9_get(&self, context: &C) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send>;
|
||||
fn op9_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// API without a `Context`
|
||||
pub trait ApiNoContext {
|
||||
fn op10_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op11_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op10_get(&self) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send>;
|
||||
fn op12_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op13_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op11_get(&self) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send>;
|
||||
fn op14_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op15_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op12_get(&self) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send>;
|
||||
fn op16_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op17_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op13_get(&self) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send>;
|
||||
fn op18_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op19_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op14_get(&self) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send>;
|
||||
fn op1_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op20_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op15_get(&self) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send>;
|
||||
fn op21_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op22_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op16_get(&self) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send>;
|
||||
fn op23_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op24_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op17_get(&self) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send>;
|
||||
fn op25_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op26_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op18_get(&self) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send>;
|
||||
fn op27_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op28_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op19_get(&self) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send>;
|
||||
fn op29_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op2_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op1_get(&self) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send>;
|
||||
fn op30_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op31_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op20_get(&self) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send>;
|
||||
fn op32_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op33_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op21_get(&self) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send>;
|
||||
fn op34_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op35_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op22_get(&self) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send>;
|
||||
fn op36_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op37_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op23_get(&self) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send>;
|
||||
fn op3_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op4_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op24_get(&self) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send>;
|
||||
fn op5_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op6_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op25_get(&self) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send>;
|
||||
fn op7_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op8_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
fn op26_get(&self) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op27_get(&self) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op28_get(&self) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op29_get(&self) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op2_get(&self) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op30_get(&self) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op31_get(&self) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op32_get(&self) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op33_get(&self) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op34_get(&self) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op35_get(&self) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op36_get(&self) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op37_get(&self) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op3_get(&self) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op4_get(&self) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op5_get(&self) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op6_get(&self) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op7_get(&self) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op8_get(&self) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn op9_get(&self) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send>;
|
||||
fn op9_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
@@ -542,189 +612,262 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
|
||||
}
|
||||
|
||||
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
|
||||
|
||||
|
||||
fn op10_get(&self) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send> {
|
||||
fn op10_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op10GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op10_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op11_get(&self) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send> {
|
||||
fn op11_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op11GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op11_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op12_get(&self) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send> {
|
||||
fn op12_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op12GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op12_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op13_get(&self) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send> {
|
||||
fn op13_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op13GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op13_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op14_get(&self) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send> {
|
||||
fn op14_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op14GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op14_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op15_get(&self) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send> {
|
||||
fn op15_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op15GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op15_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op16_get(&self) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send> {
|
||||
fn op16_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op16GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op16_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op17_get(&self) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send> {
|
||||
fn op17_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op17GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op17_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op18_get(&self) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send> {
|
||||
fn op18_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op18GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op18_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op19_get(&self) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send> {
|
||||
fn op19_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op19GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op19_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op1_get(&self) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send> {
|
||||
fn op1_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op1GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op1_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op20_get(&self) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send> {
|
||||
fn op20_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op20GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op20_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op21_get(&self) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send> {
|
||||
fn op21_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op21GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op21_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op22_get(&self) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send> {
|
||||
fn op22_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op22GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op22_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op23_get(&self) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send> {
|
||||
fn op23_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op23GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op23_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op24_get(&self) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send> {
|
||||
fn op24_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op24GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op24_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op25_get(&self) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send> {
|
||||
fn op25_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op25GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op25_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op26_get(&self) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send> {
|
||||
fn op26_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op26GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op26_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op27_get(&self) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send> {
|
||||
fn op27_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op27GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op27_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op28_get(&self) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send> {
|
||||
fn op28_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op28GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op28_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op29_get(&self) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send> {
|
||||
fn op29_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op29GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op29_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op2_get(&self) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send> {
|
||||
fn op2_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op2GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op2_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op30_get(&self) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send> {
|
||||
fn op30_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op30GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op30_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op31_get(&self) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send> {
|
||||
fn op31_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op31GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op31_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op32_get(&self) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send> {
|
||||
fn op32_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op32GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op32_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op33_get(&self) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send> {
|
||||
fn op33_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op33GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op33_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op34_get(&self) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send> {
|
||||
fn op34_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op34GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op34_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op35_get(&self) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send> {
|
||||
fn op35_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op35GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op35_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op36_get(&self) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send> {
|
||||
fn op36_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op36GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op36_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op37_get(&self) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send> {
|
||||
fn op37_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op37GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op37_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op3_get(&self) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send> {
|
||||
fn op3_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op3GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op3_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op4_get(&self) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send> {
|
||||
fn op4_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op4GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op4_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op5_get(&self) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send> {
|
||||
fn op5_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op5GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op5_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op6_get(&self) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send> {
|
||||
fn op6_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op6GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op6_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op7_get(&self) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send> {
|
||||
fn op7_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op7GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op7_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op8_get(&self) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send> {
|
||||
fn op8_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op8GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op8_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn op9_get(&self) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send> {
|
||||
fn op9_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=Op9GetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().op9_get(&self.context())
|
||||
}
|
||||
|
||||
@@ -735,7 +878,7 @@ pub mod client;
|
||||
|
||||
// Re-export Client as a top-level name
|
||||
#[cfg(feature = "client")]
|
||||
pub use self::client::Client;
|
||||
pub use client::Client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
@@ -744,5 +887,8 @@ pub mod server;
|
||||
#[cfg(feature = "server")]
|
||||
pub use self::server::Service;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod context;
|
||||
|
||||
pub mod models;
|
||||
pub mod header;
|
||||
|
||||
@@ -3,8 +3,79 @@
|
||||
pub mod responses {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,18 +5,22 @@ use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use url::form_urlencoded;
|
||||
|
||||
use mimetypes;
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub use swagger::auth::Authorization;
|
||||
pub use crate::context;
|
||||
|
||||
use {Api,
|
||||
Op10GetResponse,
|
||||
@@ -56,13 +60,7 @@ use {Api,
|
||||
Op7GetResponse,
|
||||
Op8GetResponse,
|
||||
Op9GetResponse
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub mod context;
|
||||
};
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
@@ -220,8 +218,6 @@ where
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
// This match statement is duplicated below in `parse_operation_id()`.
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
|
||||
// Op10Get - GET /op10
|
||||
@@ -238,15 +234,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op10GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -278,15 +270,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op11GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -318,15 +306,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op12GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -358,15 +342,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op13GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -398,15 +378,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op14GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -438,15 +414,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op15GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -478,15 +450,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op16GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -518,15 +486,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op17GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -558,15 +522,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op18GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -598,15 +558,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op19GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -638,15 +594,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op1GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -678,15 +630,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op20GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -718,15 +666,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op21GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -758,15 +702,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op22GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -798,15 +738,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op23GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -838,15 +774,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op24GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -878,15 +810,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op25GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -918,15 +846,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op26GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -958,15 +882,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op27GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -998,15 +918,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op28GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1038,15 +954,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op29GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1078,15 +990,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op2GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1118,15 +1026,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op30GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1158,15 +1062,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op31GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1198,15 +1098,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op32GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1238,15 +1134,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op33GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1278,15 +1170,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op34GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1318,15 +1206,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op35GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1358,15 +1242,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op36GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1398,15 +1278,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op37GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1438,15 +1314,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op3GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1478,15 +1350,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op4GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1518,15 +1386,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op5GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1558,15 +1422,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op6GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1598,15 +1458,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op7GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1638,15 +1494,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op8GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1678,15 +1530,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
Op9GetResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -1729,115 +1577,78 @@ impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
|
||||
// Op10Get - GET /op10
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP10) => Ok("Op10Get"),
|
||||
|
||||
// Op11Get - GET /op11
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP11) => Ok("Op11Get"),
|
||||
|
||||
// Op12Get - GET /op12
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP12) => Ok("Op12Get"),
|
||||
|
||||
// Op13Get - GET /op13
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP13) => Ok("Op13Get"),
|
||||
|
||||
// Op14Get - GET /op14
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP14) => Ok("Op14Get"),
|
||||
|
||||
// Op15Get - GET /op15
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP15) => Ok("Op15Get"),
|
||||
|
||||
// Op16Get - GET /op16
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP16) => Ok("Op16Get"),
|
||||
|
||||
// Op17Get - GET /op17
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP17) => Ok("Op17Get"),
|
||||
|
||||
// Op18Get - GET /op18
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP18) => Ok("Op18Get"),
|
||||
|
||||
// Op19Get - GET /op19
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP19) => Ok("Op19Get"),
|
||||
|
||||
// Op1Get - GET /op1
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP1) => Ok("Op1Get"),
|
||||
|
||||
// Op20Get - GET /op20
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP20) => Ok("Op20Get"),
|
||||
|
||||
// Op21Get - GET /op21
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP21) => Ok("Op21Get"),
|
||||
|
||||
// Op22Get - GET /op22
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP22) => Ok("Op22Get"),
|
||||
|
||||
// Op23Get - GET /op23
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP23) => Ok("Op23Get"),
|
||||
|
||||
// Op24Get - GET /op24
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP24) => Ok("Op24Get"),
|
||||
|
||||
// Op25Get - GET /op25
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP25) => Ok("Op25Get"),
|
||||
|
||||
// Op26Get - GET /op26
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP26) => Ok("Op26Get"),
|
||||
|
||||
// Op27Get - GET /op27
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP27) => Ok("Op27Get"),
|
||||
|
||||
// Op28Get - GET /op28
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP28) => Ok("Op28Get"),
|
||||
|
||||
// Op29Get - GET /op29
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP29) => Ok("Op29Get"),
|
||||
|
||||
// Op2Get - GET /op2
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP2) => Ok("Op2Get"),
|
||||
|
||||
// Op30Get - GET /op30
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP30) => Ok("Op30Get"),
|
||||
|
||||
// Op31Get - GET /op31
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP31) => Ok("Op31Get"),
|
||||
|
||||
// Op32Get - GET /op32
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP32) => Ok("Op32Get"),
|
||||
|
||||
// Op33Get - GET /op33
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP33) => Ok("Op33Get"),
|
||||
|
||||
// Op34Get - GET /op34
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP34) => Ok("Op34Get"),
|
||||
|
||||
// Op35Get - GET /op35
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP35) => Ok("Op35Get"),
|
||||
|
||||
// Op36Get - GET /op36
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP36) => Ok("Op36Get"),
|
||||
|
||||
// Op37Get - GET /op37
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP37) => Ok("Op37Get"),
|
||||
|
||||
// Op3Get - GET /op3
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP3) => Ok("Op3Get"),
|
||||
|
||||
// Op4Get - GET /op4
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP4) => Ok("Op4Get"),
|
||||
|
||||
// Op5Get - GET /op5
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP5) => Ok("Op5Get"),
|
||||
|
||||
// Op6Get - GET /op6
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP6) => Ok("Op6Get"),
|
||||
|
||||
// Op7Get - GET /op7
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP7) => Ok("Op7Get"),
|
||||
|
||||
// Op8Get - GET /op8
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP8) => Ok("Op8Get"),
|
||||
|
||||
// Op9Get - GET /op9
|
||||
&hyper::Method::GET if path.matched(paths::ID_OP9) => Ok("Op9Get"),
|
||||
_ => Err(()),
|
||||
|
||||
@@ -52,7 +52,7 @@ url = {version = "1.5", optional = true}
|
||||
# Client-specific
|
||||
serde_urlencoded = {version = "0.5.1", optional = true}
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -68,6 +68,7 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
env_logger = "0.6"
|
||||
|
||||
[[example]]
|
||||
name = "client"
|
||||
|
||||
@@ -61,7 +61,6 @@ cargo run --example server
|
||||
To run a client, follow one of the following simple steps:
|
||||
|
||||
```
|
||||
cargo run --example client TestSpecialTags
|
||||
cargo run --example client Call123example
|
||||
cargo run --example client FakeOuterBooleanSerialize
|
||||
cargo run --example client FakeOuterCompositeSerialize
|
||||
@@ -69,33 +68,24 @@ cargo run --example client FakeOuterNumberSerialize
|
||||
cargo run --example client FakeOuterStringSerialize
|
||||
cargo run --example client FakeResponseWithNumericalDescription
|
||||
cargo run --example client HyphenParam
|
||||
cargo run --example client TestBodyWithQueryParams
|
||||
cargo run --example client TestClientModel
|
||||
cargo run --example client TestEndpointParameters
|
||||
cargo run --example client TestEnumParameters
|
||||
cargo run --example client TestInlineAdditionalProperties
|
||||
cargo run --example client TestJsonFormData
|
||||
cargo run --example client TestClassname
|
||||
cargo run --example client AddPet
|
||||
cargo run --example client DeletePet
|
||||
cargo run --example client FindPetsByStatus
|
||||
cargo run --example client FindPetsByTags
|
||||
cargo run --example client GetPetById
|
||||
cargo run --example client UpdatePet
|
||||
cargo run --example client UpdatePetWithForm
|
||||
cargo run --example client UploadFile
|
||||
cargo run --example client DeleteOrder
|
||||
cargo run --example client GetInventory
|
||||
cargo run --example client GetOrderById
|
||||
cargo run --example client PlaceOrder
|
||||
cargo run --example client CreateUser
|
||||
cargo run --example client CreateUsersWithArrayInput
|
||||
cargo run --example client CreateUsersWithListInput
|
||||
cargo run --example client DeleteUser
|
||||
cargo run --example client GetUserByName
|
||||
cargo run --example client LoginUser
|
||||
cargo run --example client LogoutUser
|
||||
cargo run --example client UpdateUser
|
||||
```
|
||||
|
||||
### HTTPS
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate petstore_with_fake_endpoints_models_for_testing;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
#[allow(unused_imports)]
|
||||
@@ -51,63 +51,40 @@ use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Client,
|
||||
UpdateUserResponse
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
|
||||
"Call123example",
|
||||
|
||||
"FakeOuterBooleanSerialize",
|
||||
|
||||
"FakeOuterCompositeSerialize",
|
||||
|
||||
"FakeOuterNumberSerialize",
|
||||
|
||||
"FakeOuterStringSerialize",
|
||||
|
||||
"FakeResponseWithNumericalDescription",
|
||||
|
||||
"HyphenParam",
|
||||
|
||||
"TestEndpointParameters",
|
||||
|
||||
"TestEnumParameters",
|
||||
|
||||
"TestJsonFormData",
|
||||
|
||||
"DeletePet",
|
||||
|
||||
"FindPetsByStatus",
|
||||
|
||||
"FindPetsByTags",
|
||||
|
||||
"GetPetById",
|
||||
|
||||
"UpdatePetWithForm",
|
||||
|
||||
"UploadFile",
|
||||
|
||||
"DeleteOrder",
|
||||
|
||||
"GetInventory",
|
||||
|
||||
"GetOrderById",
|
||||
|
||||
"CreateUsersWithArrayInput",
|
||||
|
||||
"CreateUsersWithListInput",
|
||||
|
||||
"DeleteUser",
|
||||
|
||||
"GetUserByName",
|
||||
|
||||
"LoginUser",
|
||||
|
||||
"LogoutUser",
|
||||
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -150,95 +127,75 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
match matches.value_of("operation") {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
match matches.value_of("operation") {
|
||||
/* Disabled because there's no example.
|
||||
Some("TestSpecialTags") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_special_tags(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("Call123example") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.call123example(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FakeOuterBooleanSerialize") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.fake_outer_boolean_serialize(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FakeOuterCompositeSerialize") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.fake_outer_composite_serialize(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FakeOuterNumberSerialize") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.fake_outer_number_serialize(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FakeOuterStringSerialize") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.fake_outer_string_serialize(
|
||||
None
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FakeResponseWithNumericalDescription") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.fake_response_with_numerical_description(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("HyphenParam") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.hyphen_param(
|
||||
"hyphen_param_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("TestBodyWithQueryParams") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_body_with_query_params(
|
||||
"query_example".to_string(),
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("TestClientModel") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_client_model(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("TestEndpointParameters") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_endpoint_parameters(
|
||||
8.14,
|
||||
1.2,
|
||||
@@ -255,11 +212,9 @@ fn main() {
|
||||
Some("password_example".to_string()),
|
||||
Some("callback_example".to_string())
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("TestEnumParameters") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_enum_parameters(
|
||||
Some(&Vec::new()),
|
||||
Some("enum_header_string_example".to_string()),
|
||||
@@ -269,213 +224,166 @@ fn main() {
|
||||
Some(1.2),
|
||||
Some("enum_form_string_example".to_string())
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("TestInlineAdditionalProperties") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_inline_additional_properties(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("TestJsonFormData") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_json_form_data(
|
||||
"param_example".to_string(),
|
||||
"param2_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("TestClassname") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.test_classname(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("AddPet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.add_pet(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("DeletePet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.delete_pet(
|
||||
789,
|
||||
Some("api_key_example".to_string())
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FindPetsByStatus") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.find_pets_by_status(
|
||||
&Vec::new()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("FindPetsByTags") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.find_pets_by_tags(
|
||||
&Vec::new()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("GetPetById") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.get_pet_by_id(
|
||||
789
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("UpdatePet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.update_pet(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("UpdatePetWithForm") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.update_pet_with_form(
|
||||
789,
|
||||
Some("name_example".to_string()),
|
||||
Some("status_example".to_string())
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("UploadFile") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.upload_file(
|
||||
789,
|
||||
Some("additional_metadata_example".to_string()),
|
||||
Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE")))
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("DeleteOrder") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.delete_order(
|
||||
"order_id_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("GetInventory") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.get_inventory(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("GetOrderById") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.get_order_by_id(
|
||||
789
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("PlaceOrder") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.place_order(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("CreateUser") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.create_user(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("CreateUsersWithArrayInput") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.create_users_with_array_input(
|
||||
&Vec::new()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("CreateUsersWithListInput") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.create_users_with_list_input(
|
||||
&Vec::new()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("DeleteUser") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.delete_user(
|
||||
"username_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("GetUserByName") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.get_user_by_name(
|
||||
"username_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("LoginUser") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.login_user(
|
||||
"username_example".to_string(),
|
||||
"password_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("LogoutUser") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.logout_user(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("UpdateUser") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.update_user(
|
||||
"username_example".to_string(),
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
//! Main binary entry point for petstore_with_fake_endpoints_models_for_testing implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate petstore_with_fake_endpoints_models_for_testing;
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate petstore_with_fake_endpoints_models_for_testing;
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate uuid;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = petstore_with_fake_endpoints_models_for_testing::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
petstore_with_fake_endpoints_models_for_testing::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//! Main binary entry point for petstore_with_fake_endpoints_models_for_testing implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate petstore_with_fake_endpoints_models_for_testing;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate petstore_with_fake_endpoints_models_for_testing;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate uuid;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:80";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
@@ -0,0 +1,530 @@
|
||||
//! Main library entry point for petstore_with_fake_endpoints_models_for_testing implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
use uuid;
|
||||
|
||||
use petstore_with_fake_endpoints_models_for_testing::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
petstore_with_fake_endpoints_models_for_testing::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use petstore_with_fake_endpoints_models_for_testing::{
|
||||
Api,
|
||||
ApiError,
|
||||
TestSpecialTagsResponse,
|
||||
Call123exampleResponse,
|
||||
FakeOuterBooleanSerializeResponse,
|
||||
FakeOuterCompositeSerializeResponse,
|
||||
FakeOuterNumberSerializeResponse,
|
||||
FakeOuterStringSerializeResponse,
|
||||
FakeResponseWithNumericalDescriptionResponse,
|
||||
HyphenParamResponse,
|
||||
TestBodyWithQueryParamsResponse,
|
||||
TestClientModelResponse,
|
||||
TestEndpointParametersResponse,
|
||||
TestEnumParametersResponse,
|
||||
TestInlineAdditionalPropertiesResponse,
|
||||
TestJsonFormDataResponse,
|
||||
TestClassnameResponse,
|
||||
AddPetResponse,
|
||||
DeletePetResponse,
|
||||
FindPetsByStatusResponse,
|
||||
FindPetsByTagsResponse,
|
||||
GetPetByIdResponse,
|
||||
UpdatePetResponse,
|
||||
UpdatePetWithFormResponse,
|
||||
UploadFileResponse,
|
||||
DeleteOrderResponse,
|
||||
GetInventoryResponse,
|
||||
GetOrderByIdResponse,
|
||||
PlaceOrderResponse,
|
||||
CreateUserResponse,
|
||||
CreateUsersWithArrayInputResponse,
|
||||
CreateUsersWithListInputResponse,
|
||||
DeleteUserResponse,
|
||||
GetUserByNameResponse,
|
||||
LoginUserResponse,
|
||||
LogoutUserResponse,
|
||||
UpdateUserResponse,
|
||||
};
|
||||
use petstore_with_fake_endpoints_models_for_testing::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
/// To test special tags
|
||||
fn test_special_tags(
|
||||
&self,
|
||||
body: models::Client,
|
||||
context: &C) -> Box<Future<Item=TestSpecialTagsResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn call123example(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=Call123exampleResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("call123example() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn fake_outer_boolean_serialize(
|
||||
&self,
|
||||
body: Option<models::OuterBoolean>,
|
||||
context: &C) -> Box<Future<Item=FakeOuterBooleanSerializeResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn fake_outer_composite_serialize(
|
||||
&self,
|
||||
body: Option<models::OuterComposite>,
|
||||
context: &C) -> Box<Future<Item=FakeOuterCompositeSerializeResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn fake_outer_number_serialize(
|
||||
&self,
|
||||
body: Option<models::OuterNumber>,
|
||||
context: &C) -> Box<Future<Item=FakeOuterNumberSerializeResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn fake_outer_string_serialize(
|
||||
&self,
|
||||
body: Option<models::OuterString>,
|
||||
context: &C) -> Box<Future<Item=FakeOuterStringSerializeResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn fake_response_with_numerical_description(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("fake_response_with_numerical_description() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn hyphen_param(
|
||||
&self,
|
||||
hyphen_param: String,
|
||||
context: &C) -> Box<Future<Item=HyphenParamResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("hyphen_param(\"{}\") - X-Span-ID: {:?}", hyphen_param, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn test_body_with_query_params(
|
||||
&self,
|
||||
query: String,
|
||||
body: models::User,
|
||||
context: &C) -> Box<Future<Item=TestBodyWithQueryParamsResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_body_with_query_params(\"{}\", {:?}) - X-Span-ID: {:?}", query, body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test \"client\" model
|
||||
fn test_client_model(
|
||||
&self,
|
||||
body: models::Client,
|
||||
context: &C) -> Box<Future<Item=TestClientModelResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
|
||||
fn test_endpoint_parameters(
|
||||
&self,
|
||||
number: f64,
|
||||
double: f64,
|
||||
pattern_without_delimiter: String,
|
||||
byte: swagger::ByteArray,
|
||||
integer: Option<i32>,
|
||||
int32: Option<i32>,
|
||||
int64: Option<i64>,
|
||||
float: Option<f32>,
|
||||
string: Option<String>,
|
||||
binary: Option<swagger::ByteArray>,
|
||||
date: Option<chrono::DateTime::<chrono::Utc>>,
|
||||
date_time: Option<chrono::DateTime::<chrono::Utc>>,
|
||||
password: Option<String>,
|
||||
callback: Option<String>,
|
||||
context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test enum parameters
|
||||
fn test_enum_parameters(
|
||||
&self,
|
||||
enum_header_string_array: Option<&Vec<String>>,
|
||||
enum_header_string: Option<String>,
|
||||
enum_query_string_array: Option<&Vec<String>>,
|
||||
enum_query_string: Option<String>,
|
||||
enum_query_integer: Option<i32>,
|
||||
enum_query_double: Option<f64>,
|
||||
enum_form_string: Option<String>,
|
||||
context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// test inline additionalProperties
|
||||
fn test_inline_additional_properties(
|
||||
&self,
|
||||
param: HashMap<String, String>,
|
||||
context: &C) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_inline_additional_properties({:?}) - X-Span-ID: {:?}", param, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// test json serialization of form data
|
||||
fn test_json_form_data(
|
||||
&self,
|
||||
param: String,
|
||||
param2: String,
|
||||
context: &C) -> Box<Future<Item=TestJsonFormDataResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test class name in snake case
|
||||
fn test_classname(
|
||||
&self,
|
||||
body: models::Client,
|
||||
context: &C) -> Box<Future<Item=TestClassnameResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("test_classname({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Add a new pet to the store
|
||||
fn add_pet(
|
||||
&self,
|
||||
body: models::Pet,
|
||||
context: &C) -> Box<Future<Item=AddPetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("add_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Deletes a pet
|
||||
fn delete_pet(
|
||||
&self,
|
||||
pet_id: i64,
|
||||
api_key: Option<String>,
|
||||
context: &C) -> Box<Future<Item=DeletePetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Finds Pets by status
|
||||
fn find_pets_by_status(
|
||||
&self,
|
||||
status: &Vec<String>,
|
||||
context: &C) -> Box<Future<Item=FindPetsByStatusResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Finds Pets by tags
|
||||
fn find_pets_by_tags(
|
||||
&self,
|
||||
tags: &Vec<String>,
|
||||
context: &C) -> Box<Future<Item=FindPetsByTagsResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Find pet by ID
|
||||
fn get_pet_by_id(
|
||||
&self,
|
||||
pet_id: i64,
|
||||
context: &C) -> Box<Future<Item=GetPetByIdResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Update an existing pet
|
||||
fn update_pet(
|
||||
&self,
|
||||
body: models::Pet,
|
||||
context: &C) -> Box<Future<Item=UpdatePetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("update_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Updates a pet in the store with form data
|
||||
fn update_pet_with_form(
|
||||
&self,
|
||||
pet_id: i64,
|
||||
name: Option<String>,
|
||||
status: Option<String>,
|
||||
context: &C) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// uploads an image
|
||||
fn upload_file(
|
||||
&self,
|
||||
pet_id: i64,
|
||||
additional_metadata: Option<String>,
|
||||
file: Option<swagger::ByteArray>,
|
||||
context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("upload_file({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, additional_metadata, file, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Delete purchase order by ID
|
||||
fn delete_order(
|
||||
&self,
|
||||
order_id: String,
|
||||
context: &C) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Returns pet inventories by status
|
||||
fn get_inventory(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=GetInventoryResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("get_inventory() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Find purchase order by ID
|
||||
fn get_order_by_id(
|
||||
&self,
|
||||
order_id: i64,
|
||||
context: &C) -> Box<Future<Item=GetOrderByIdResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Place an order for a pet
|
||||
fn place_order(
|
||||
&self,
|
||||
body: models::Order,
|
||||
context: &C) -> Box<Future<Item=PlaceOrderResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("place_order({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Create user
|
||||
fn create_user(
|
||||
&self,
|
||||
body: models::User,
|
||||
context: &C) -> Box<Future<Item=CreateUserResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("create_user({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Creates list of users with given input array
|
||||
fn create_users_with_array_input(
|
||||
&self,
|
||||
body: &Vec<models::User>,
|
||||
context: &C) -> Box<Future<Item=CreateUsersWithArrayInputResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Creates list of users with given input array
|
||||
fn create_users_with_list_input(
|
||||
&self,
|
||||
body: &Vec<models::User>,
|
||||
context: &C) -> Box<Future<Item=CreateUsersWithListInputResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Delete user
|
||||
fn delete_user(
|
||||
&self,
|
||||
username: String,
|
||||
context: &C) -> Box<Future<Item=DeleteUserResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get user by user name
|
||||
fn get_user_by_name(
|
||||
&self,
|
||||
username: String,
|
||||
context: &C) -> Box<Future<Item=GetUserByNameResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Logs user into the system
|
||||
fn login_user(
|
||||
&self,
|
||||
username: String,
|
||||
password: String,
|
||||
context: &C) -> Box<Future<Item=LoginUserResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Logs out current logged in user session
|
||||
fn logout_user(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=LogoutUserResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("logout_user() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Updated user
|
||||
fn update_user(
|
||||
&self,
|
||||
username: String,
|
||||
body: models::User,
|
||||
context: &C) -> Box<Future<Item=UpdateUserResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
//! Main library entry point for petstore_with_fake_endpoints_models_for_testing implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use uuid;
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use petstore_with_fake_endpoints_models_for_testing::{Api, ApiError,
|
||||
TestSpecialTagsResponse,
|
||||
Call123exampleResponse,
|
||||
FakeOuterBooleanSerializeResponse,
|
||||
FakeOuterCompositeSerializeResponse,
|
||||
FakeOuterNumberSerializeResponse,
|
||||
FakeOuterStringSerializeResponse,
|
||||
FakeResponseWithNumericalDescriptionResponse,
|
||||
HyphenParamResponse,
|
||||
TestBodyWithQueryParamsResponse,
|
||||
TestClientModelResponse,
|
||||
TestEndpointParametersResponse,
|
||||
TestEnumParametersResponse,
|
||||
TestInlineAdditionalPropertiesResponse,
|
||||
TestJsonFormDataResponse,
|
||||
TestClassnameResponse,
|
||||
AddPetResponse,
|
||||
DeletePetResponse,
|
||||
FindPetsByStatusResponse,
|
||||
FindPetsByTagsResponse,
|
||||
GetPetByIdResponse,
|
||||
UpdatePetResponse,
|
||||
UpdatePetWithFormResponse,
|
||||
UploadFileResponse,
|
||||
DeleteOrderResponse,
|
||||
GetInventoryResponse,
|
||||
GetOrderByIdResponse,
|
||||
PlaceOrderResponse,
|
||||
CreateUserResponse,
|
||||
CreateUsersWithArrayInputResponse,
|
||||
CreateUsersWithListInputResponse,
|
||||
DeleteUserResponse,
|
||||
GetUserByNameResponse,
|
||||
LoginUserResponse,
|
||||
LogoutUserResponse,
|
||||
UpdateUserResponse
|
||||
};
|
||||
use petstore_with_fake_endpoints_models_for_testing::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
|
||||
/// To test special tags
|
||||
fn test_special_tags(&self, body: models::Client, context: &C) -> Box<Future<Item=TestSpecialTagsResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn call123example(&self, context: &C) -> Box<Future<Item=Call123exampleResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("call123example() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn fake_outer_boolean_serialize(&self, body: Option<models::OuterBoolean>, context: &C) -> Box<Future<Item=FakeOuterBooleanSerializeResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn fake_outer_composite_serialize(&self, body: Option<models::OuterComposite>, context: &C) -> Box<Future<Item=FakeOuterCompositeSerializeResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn fake_outer_number_serialize(&self, body: Option<models::OuterNumber>, context: &C) -> Box<Future<Item=FakeOuterNumberSerializeResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn fake_outer_string_serialize(&self, body: Option<models::OuterString>, context: &C) -> Box<Future<Item=FakeOuterStringSerializeResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn fake_response_with_numerical_description(&self, context: &C) -> Box<Future<Item=FakeResponseWithNumericalDescriptionResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("fake_response_with_numerical_description() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn hyphen_param(&self, hyphen_param: String, context: &C) -> Box<Future<Item=HyphenParamResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("hyphen_param(\"{}\") - X-Span-ID: {:?}", hyphen_param, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn test_body_with_query_params(&self, query: String, body: models::User, context: &C) -> Box<Future<Item=TestBodyWithQueryParamsResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_body_with_query_params(\"{}\", {:?}) - X-Span-ID: {:?}", query, body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test \"client\" model
|
||||
fn test_client_model(&self, body: models::Client, context: &C) -> Box<Future<Item=TestClientModelResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
|
||||
fn test_endpoint_parameters(&self, number: f64, double: f64, pattern_without_delimiter: String, byte: swagger::ByteArray, integer: Option<i32>, int32: Option<i32>, int64: Option<i64>, float: Option<f32>, string: Option<String>, binary: Option<swagger::ByteArray>, date: Option<chrono::DateTime::<chrono::Utc>>, date_time: Option<chrono::DateTime::<chrono::Utc>>, password: Option<String>, callback: Option<String>, context: &C) -> Box<Future<Item=TestEndpointParametersResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test enum parameters
|
||||
fn test_enum_parameters(&self, enum_header_string_array: Option<&Vec<String>>, enum_header_string: Option<String>, enum_query_string_array: Option<&Vec<String>>, enum_query_string: Option<String>, enum_query_integer: Option<i32>, enum_query_double: Option<f64>, enum_form_string: Option<String>, context: &C) -> Box<Future<Item=TestEnumParametersResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// test inline additionalProperties
|
||||
fn test_inline_additional_properties(&self, param: HashMap<String, String>, context: &C) -> Box<Future<Item=TestInlineAdditionalPropertiesResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_inline_additional_properties({:?}) - X-Span-ID: {:?}", param, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// test json serialization of form data
|
||||
fn test_json_form_data(&self, param: String, param2: String, context: &C) -> Box<Future<Item=TestJsonFormDataResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// To test class name in snake case
|
||||
fn test_classname(&self, body: models::Client, context: &C) -> Box<Future<Item=TestClassnameResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("test_classname({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Add a new pet to the store
|
||||
fn add_pet(&self, body: models::Pet, context: &C) -> Box<Future<Item=AddPetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("add_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Deletes a pet
|
||||
fn delete_pet(&self, pet_id: i64, api_key: Option<String>, context: &C) -> Box<Future<Item=DeletePetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Finds Pets by status
|
||||
fn find_pets_by_status(&self, status: &Vec<String>, context: &C) -> Box<Future<Item=FindPetsByStatusResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Finds Pets by tags
|
||||
fn find_pets_by_tags(&self, tags: &Vec<String>, context: &C) -> Box<Future<Item=FindPetsByTagsResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Find pet by ID
|
||||
fn get_pet_by_id(&self, pet_id: i64, context: &C) -> Box<Future<Item=GetPetByIdResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Update an existing pet
|
||||
fn update_pet(&self, body: models::Pet, context: &C) -> Box<Future<Item=UpdatePetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("update_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Updates a pet in the store with form data
|
||||
fn update_pet_with_form(&self, pet_id: i64, name: Option<String>, status: Option<String>, context: &C) -> Box<Future<Item=UpdatePetWithFormResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// uploads an image
|
||||
fn upload_file(&self, pet_id: i64, additional_metadata: Option<String>, file: Option<swagger::ByteArray>, context: &C) -> Box<Future<Item=UploadFileResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("upload_file({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, additional_metadata, file, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Delete purchase order by ID
|
||||
fn delete_order(&self, order_id: String, context: &C) -> Box<Future<Item=DeleteOrderResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Returns pet inventories by status
|
||||
fn get_inventory(&self, context: &C) -> Box<Future<Item=GetInventoryResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("get_inventory() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Find purchase order by ID
|
||||
fn get_order_by_id(&self, order_id: i64, context: &C) -> Box<Future<Item=GetOrderByIdResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Place an order for a pet
|
||||
fn place_order(&self, body: models::Order, context: &C) -> Box<Future<Item=PlaceOrderResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("place_order({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Create user
|
||||
fn create_user(&self, body: models::User, context: &C) -> Box<Future<Item=CreateUserResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("create_user({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Creates list of users with given input array
|
||||
fn create_users_with_array_input(&self, body: &Vec<models::User>, context: &C) -> Box<Future<Item=CreateUsersWithArrayInputResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Creates list of users with given input array
|
||||
fn create_users_with_list_input(&self, body: &Vec<models::User>, context: &C) -> Box<Future<Item=CreateUsersWithListInputResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Delete user
|
||||
fn delete_user(&self, username: String, context: &C) -> Box<Future<Item=DeleteUserResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get user by user name
|
||||
fn get_user_by_name(&self, username: String, context: &C) -> Box<Future<Item=GetUserByNameResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Logs user into the system
|
||||
fn login_user(&self, username: String, password: String, context: &C) -> Box<Future<Item=LoginUserResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Logs out current logged in user session
|
||||
fn logout_user(&self, context: &C) -> Box<Future<Item=LogoutUserResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("logout_user() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Updated user
|
||||
fn update_user(&self, username: String, body: models::User, context: &C) -> Box<Future<Item=UpdateUserResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,10 @@
|
||||
/// mime types for requests and responses
|
||||
|
||||
pub mod responses {
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for TestSpecialTags
|
||||
pub static TEST_SPECIAL_TAGS_SUCCESSFUL_OPERATION: &str = "application/json";
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for FakeOuterBooleanSerialize
|
||||
pub static FAKE_OUTER_BOOLEAN_SERIALIZE_OUTPUT_BOOLEAN: &str = "*/*";
|
||||
|
||||
@@ -18,12 +17,21 @@ pub mod responses {
|
||||
/// Create &str objects for the response content types for FakeOuterStringSerialize
|
||||
pub static FAKE_OUTER_STRING_SERIALIZE_OUTPUT_STRING: &str = "*/*";
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for TestClientModel
|
||||
pub static TEST_CLIENT_MODEL_SUCCESSFUL_OPERATION: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for TestClassname
|
||||
pub static TEST_CLASSNAME_SUCCESSFUL_OPERATION: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for FindPetsByStatus
|
||||
pub static FIND_PETS_BY_STATUS_SUCCESSFUL_OPERATION: &str = "application/xml";
|
||||
|
||||
@@ -33,9 +41,12 @@ pub mod responses {
|
||||
/// Create &str objects for the response content types for GetPetById
|
||||
pub static GET_PET_BY_ID_SUCCESSFUL_OPERATION: &str = "application/xml";
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for UploadFile
|
||||
pub static UPLOAD_FILE_SUCCESSFUL_OPERATION: &str = "application/json";
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for GetInventory
|
||||
pub static GET_INVENTORY_SUCCESSFUL_OPERATION: &str = "application/json";
|
||||
|
||||
@@ -45,19 +56,25 @@ pub mod responses {
|
||||
/// Create &str objects for the response content types for PlaceOrder
|
||||
pub static PLACE_ORDER_SUCCESSFUL_OPERATION: &str = "application/xml";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for GetUserByName
|
||||
pub static GET_USER_BY_NAME_SUCCESSFUL_OPERATION: &str = "application/xml";
|
||||
|
||||
/// Create &str objects for the response content types for LoginUser
|
||||
pub static LOGIN_USER_SUCCESSFUL_OPERATION: &str = "application/xml";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
|
||||
/// Create &str objects for the request content types for TestSpecialTags
|
||||
pub static TEST_SPECIAL_TAGS: &str = "application/json";
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for FakeOuterBooleanSerialize
|
||||
pub static FAKE_OUTER_BOOLEAN_SERIALIZE: &str = "application/json";
|
||||
|
||||
@@ -70,6 +87,8 @@ pub mod requests {
|
||||
/// Create &str objects for the request content types for FakeOuterStringSerialize
|
||||
pub static FAKE_OUTER_STRING_SERIALIZE: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for TestBodyWithQueryParams
|
||||
pub static TEST_BODY_WITH_QUERY_PARAMS: &str = "application/json";
|
||||
|
||||
@@ -94,12 +113,20 @@ pub mod requests {
|
||||
/// Create &str objects for the request content types for AddPet
|
||||
pub static ADD_PET: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for UpdatePet
|
||||
pub static UPDATE_PET: &str = "application/json";
|
||||
|
||||
/// Create &str objects for the request content types for UpdatePetWithForm
|
||||
pub static UPDATE_PET_WITH_FORM: &str = "application/x-www-form-urlencoded";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for PlaceOrder
|
||||
pub static PLACE_ORDER: &str = "application/json";
|
||||
|
||||
@@ -112,6 +139,10 @@ pub mod requests {
|
||||
/// Create &str objects for the request content types for CreateUsersWithListInput
|
||||
pub static CREATE_USERS_WITH_LIST_INPUT: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for UpdateUser
|
||||
pub static UPDATE_USER: &str = "application/json";
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@ url = {version = "1.5", optional = true}
|
||||
|
||||
# Client-specific
|
||||
|
||||
# Server-specific
|
||||
# Server, and client callback-specific
|
||||
lazy_static = { version = "1.4", optional = true }
|
||||
percent-encoding = {version = "1.0.0", optional = true}
|
||||
regex = {version = "0.2", optional = true}
|
||||
@@ -56,7 +56,8 @@ frunk-enum-core = { version = "0.2.0", optional = true }
|
||||
[dev-dependencies]
|
||||
clap = "2.25"
|
||||
error-chain = "0.12"
|
||||
uuid = {version = "0.5", features = ["serde", "v4"]}
|
||||
env_logger = "0.6"
|
||||
uuid = {version = "0.7", features = ["serde", "v4"]}
|
||||
|
||||
[[example]]
|
||||
name = "client"
|
||||
|
||||
@@ -62,13 +62,11 @@ To run a client, follow one of the following simple steps:
|
||||
|
||||
```
|
||||
cargo run --example client DummyGet
|
||||
cargo run --example client DummyPut
|
||||
cargo run --example client FileResponseGet
|
||||
cargo run --example client GetStructuredYaml
|
||||
cargo run --example client HtmlPost
|
||||
cargo run --example client PostYaml
|
||||
cargo run --example client RawJsonGet
|
||||
cargo run --example client SoloObjectPost
|
||||
```
|
||||
|
||||
### HTTPS
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate rust_server_test;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate futures;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate swagger;
|
||||
extern crate clap;
|
||||
extern crate tokio;
|
||||
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use futures::{Future, future, Stream, stream};
|
||||
#[allow(unused_imports)]
|
||||
@@ -24,25 +24,21 @@ use rust_server_test::{Api, ApiNoContext, Client, ContextWrapperExt,
|
||||
SoloObjectPostResponse
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("client")
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
|
||||
"DummyGet",
|
||||
|
||||
"FileResponseGet",
|
||||
|
||||
"GetStructuredYaml",
|
||||
|
||||
"HtmlPost",
|
||||
|
||||
"PostYaml",
|
||||
|
||||
"RawJsonGet",
|
||||
|
||||
])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -85,72 +81,57 @@ fn main() {
|
||||
|
||||
let client = client.with_context(context);
|
||||
|
||||
match matches.value_of("operation") {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
match matches.value_of("operation") {
|
||||
Some("DummyGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.dummy_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("DummyPut") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.dummy_put(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
Some("FileResponseGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.file_response_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("GetStructuredYaml") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.get_structured_yaml(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("HtmlPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.html_post(
|
||||
"body_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("PostYaml") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.post_yaml(
|
||||
"value_example".to_string()
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
Some("RawJsonGet") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.raw_json_get(
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
|
||||
/* Disabled because there's no example.
|
||||
Some("SoloObjectPost") => {
|
||||
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let result = rt.block_on(client.solo_object_post(
|
||||
???
|
||||
));
|
||||
println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has<XSpanIdString>).get().clone());
|
||||
info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
},
|
||||
*/
|
||||
|
||||
_ => {
|
||||
panic!("Invalid operation provided")
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
//! Main binary entry point for rust_server_test implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate rust_server_test;
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
extern crate native_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate rust_server_test;
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
use futures::{Future, Stream};
|
||||
use hyper::service::MakeService;
|
||||
use hyper::server::conn::Http;
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
use tokio::net::TcpListener;
|
||||
use clap::{App, Arg};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
mod server_lib;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let server = server_lib::Server::new();
|
||||
|
||||
let service_fn = rust_server_test::server::MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
rust_server_test::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:80".parse().expect("Failed to parse bind address");
|
||||
if matches.is_present("https") {
|
||||
let ssl = ssl().expect("Failed to load SSL keys");
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
hyper::rt::run(tls_listener);
|
||||
} else {
|
||||
// Using HTTP
|
||||
hyper::rt::run(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//! Main binary entry point for rust_server_test implementation.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// Imports required by this file.
|
||||
// extern crate <name of this crate>;
|
||||
extern crate rust_server_test;
|
||||
extern crate clap;
|
||||
extern crate env_logger;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate openssl;
|
||||
extern crate swagger;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate rust_server_test;
|
||||
extern crate chrono;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
extern crate futures;
|
||||
extern crate native_tls;
|
||||
// extern crate swagger;
|
||||
extern crate tokio;
|
||||
extern crate tokio_tls;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use openssl::x509::X509_FILETYPE_PEM;
|
||||
use openssl::ssl::{SslAcceptorBuilder, SslMethod};
|
||||
use openssl::error::ErrorStack;
|
||||
|
||||
mod server;
|
||||
|
||||
// Builds an SSL implementation for Simple HTTPS from some hard-coded file names
|
||||
fn ssl() -> Result<SslAcceptorBuilder, ErrorStack> {
|
||||
let mut ssl = SslAcceptorBuilder::mozilla_intermediate_raw(SslMethod::tls())?;
|
||||
|
||||
// Server authentication
|
||||
ssl.set_private_key_file("examples/server-key.pem", X509_FILETYPE_PEM)?;
|
||||
ssl.set_certificate_chain_file("examples/server-chain.pem")?;
|
||||
ssl.check_private_key()?;
|
||||
|
||||
Ok(ssl)
|
||||
}
|
||||
|
||||
/// Create custom server, wire it to the autogenerated router,
|
||||
/// and pass it to the web server.
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
let matches = App::new("server")
|
||||
.arg(Arg::with_name("https")
|
||||
.long("https")
|
||||
.help("Whether to use HTTPS or not"))
|
||||
.get_matches();
|
||||
|
||||
let addr = "127.0.0.1:80";
|
||||
|
||||
let https = if matches.is_present("https") {
|
||||
Some(ssl().expect("Failed to load SSL keys"))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
hyper::rt::run(server::create(addr, https));
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
//! Main library entry point for rust_server_test implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use chrono;
|
||||
use futures::{future, Future, Stream};
|
||||
use hyper::server::conn::Http;
|
||||
use hyper::service::MakeService as _;
|
||||
use native_tls;
|
||||
use openssl::ssl::SslAcceptorBuilder;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::MakeAllowAllAuthenticator;
|
||||
use swagger::EmptyContext;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_tls::TlsAcceptorExt;
|
||||
|
||||
|
||||
use rust_server_test::models;
|
||||
|
||||
pub fn create(addr: &str, https: Option<SslAcceptorBuilder>) -> Box<Future<Item = (), Error = ()> + Send> {
|
||||
let addr = addr.parse().expect("Failed to parse bind address");
|
||||
|
||||
let server = Server::new();
|
||||
|
||||
let service_fn = MakeService::new(server);
|
||||
|
||||
let service_fn = MakeAllowAllAuthenticator::new(service_fn, "cosmo");
|
||||
|
||||
let service_fn =
|
||||
rust_server_test::server::context::MakeAddContext::<_, EmptyContext>::new(
|
||||
service_fn
|
||||
);
|
||||
|
||||
if let Some(ssl) = https {
|
||||
let builder: native_tls::TlsAcceptorBuilder = native_tls::backend::openssl::TlsAcceptorBuilderExt::from_openssl(ssl);
|
||||
let tls_acceptor = builder.build().expect("Failed to build TLS acceptor");
|
||||
let service_fn = Arc::new(Mutex::new(service_fn));
|
||||
let tls_listener = TcpListener::bind(&addr).unwrap().incoming().for_each(move |tcp| {
|
||||
let addr = tcp.peer_addr().expect("Unable to get remote address");
|
||||
|
||||
let service_fn = service_fn.clone();
|
||||
|
||||
hyper::rt::spawn(tls_acceptor.accept_async(tcp).map_err(|_| ()).and_then(move |tls| {
|
||||
let ms = {
|
||||
let mut service_fn = service_fn.lock().unwrap();
|
||||
service_fn.make_service(&addr)
|
||||
};
|
||||
|
||||
ms.and_then(move |service| {
|
||||
Http::new().serve_connection(tls, service)
|
||||
}).map_err(|_| ())
|
||||
}));
|
||||
|
||||
Ok(())
|
||||
}).map_err(|_| ());
|
||||
|
||||
Box::new(tls_listener)
|
||||
} else {
|
||||
// Using HTTP
|
||||
Box::new(hyper::server::Server::bind(&addr).serve(service_fn).map_err(|e| panic!("{:?}", e)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
use rust_server_test::{
|
||||
Api,
|
||||
ApiError,
|
||||
DummyGetResponse,
|
||||
DummyPutResponse,
|
||||
FileResponseGetResponse,
|
||||
GetStructuredYamlResponse,
|
||||
HtmlPostResponse,
|
||||
PostYamlResponse,
|
||||
RawJsonGetResponse,
|
||||
SoloObjectPostResponse,
|
||||
};
|
||||
use rust_server_test::server::MakeService;
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
/// A dummy endpoint to make the spec valid.
|
||||
fn dummy_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=DummyGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("dummy_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn dummy_put(
|
||||
&self,
|
||||
nested_response: models::InlineObject,
|
||||
context: &C) -> Box<Future<Item=DummyPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("dummy_put({:?}) - X-Span-ID: {:?}", nested_response, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get a file
|
||||
fn file_response_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=FileResponseGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("file_response_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn get_structured_yaml(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("get_structured_yaml() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Test HTML handling
|
||||
fn html_post(
|
||||
&self,
|
||||
body: String,
|
||||
context: &C) -> Box<Future<Item=HtmlPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("html_post(\"{}\") - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
fn post_yaml(
|
||||
&self,
|
||||
value: String,
|
||||
context: &C) -> Box<Future<Item=PostYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("post_yaml(\"{}\") - X-Span-ID: {:?}", value, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get an arbitrary JSON blob.
|
||||
fn raw_json_get(
|
||||
&self,
|
||||
context: &C) -> Box<Future<Item=RawJsonGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("raw_json_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Send an arbitrary JSON blob
|
||||
fn solo_object_post(
|
||||
&self,
|
||||
value: serde_json::Value,
|
||||
context: &C) -> Box<Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let context = context.clone();
|
||||
info!("solo_object_post({:?}) - X-Span-ID: {:?}", value, context.get().0.clone());
|
||||
Box::new(future::err("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
//! Main library entry point for rust_server_test implementation.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
mod errors {
|
||||
error_chain!{}
|
||||
}
|
||||
|
||||
pub use self::errors::*;
|
||||
|
||||
use futures::{self, Future};
|
||||
use chrono;
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use rust_server_test::{Api, ApiError,
|
||||
DummyGetResponse,
|
||||
DummyPutResponse,
|
||||
FileResponseGetResponse,
|
||||
GetStructuredYamlResponse,
|
||||
HtmlPostResponse,
|
||||
PostYamlResponse,
|
||||
RawJsonGetResponse,
|
||||
SoloObjectPostResponse
|
||||
};
|
||||
use rust_server_test::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
marker: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C> Server<C> {
|
||||
pub fn new() -> Self {
|
||||
Server{marker: PhantomData}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Api<C> for Server<C> where C: Has<XSpanIdString>{
|
||||
|
||||
/// A dummy endpoint to make the spec valid.
|
||||
fn dummy_get(&self, context: &C) -> Box<Future<Item=DummyGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("dummy_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn dummy_put(&self, nested_response: models::InlineObject, context: &C) -> Box<Future<Item=DummyPutResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("dummy_put({:?}) - X-Span-ID: {:?}", nested_response, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get a file
|
||||
fn file_response_get(&self, context: &C) -> Box<Future<Item=FileResponseGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("file_response_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn get_structured_yaml(&self, context: &C) -> Box<Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("get_structured_yaml() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Test HTML handling
|
||||
fn html_post(&self, body: String, context: &C) -> Box<Future<Item=HtmlPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("html_post(\"{}\") - X-Span-ID: {:?}", body, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
|
||||
fn post_yaml(&self, value: String, context: &C) -> Box<Future<Item=PostYamlResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("post_yaml(\"{}\") - X-Span-ID: {:?}", value, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Get an arbitrary JSON blob.
|
||||
fn raw_json_get(&self, context: &C) -> Box<Future<Item=RawJsonGetResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("raw_json_get() - X-Span-ID: {:?}", context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
/// Send an arbitrary JSON blob
|
||||
fn solo_object_post(&self, value: serde_json::Value, context: &C) -> Box<Future<Item=SoloObjectPostResponse, Error=ApiError> + Send> {
|
||||
let context = context.clone();
|
||||
println!("solo_object_post({:?}) - X-Span-ID: {:?}", value, context.get().0.clone());
|
||||
Box::new(futures::failed("Generic failure".into()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
use futures;
|
||||
use futures::{Future, Stream, future, stream};
|
||||
use hyper;
|
||||
use hyper::client::HttpConnector;
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use hyper::{Body, Uri, Response};
|
||||
use hyper_tls::HttpsConnector;
|
||||
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
use futures;
|
||||
use futures::{Future, Stream};
|
||||
use futures::{future, stream};
|
||||
use serde_json;
|
||||
use std::borrow::Cow;
|
||||
#[allow(unused_imports)]
|
||||
@@ -22,20 +18,11 @@ use std::str;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use swagger::client::Service;
|
||||
|
||||
|
||||
use {Api,
|
||||
DummyGetResponse,
|
||||
DummyPutResponse,
|
||||
FileResponseGetResponse,
|
||||
GetStructuredYamlResponse,
|
||||
HtmlPostResponse,
|
||||
PostYamlResponse,
|
||||
RawJsonGetResponse,
|
||||
SoloObjectPostResponse
|
||||
};
|
||||
use swagger::connector;
|
||||
use swagger::{ApiError, XSpanIdString, Has, AuthData};
|
||||
use url::form_urlencoded;
|
||||
use url::percent_encoding::{utf8_percent_encode, PATH_SEGMENT_ENCODE_SET, QUERY_ENCODE_SET};
|
||||
|
||||
use mimetypes;
|
||||
use models;
|
||||
@@ -49,6 +36,17 @@ define_encode_set! {
|
||||
pub ID_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'|'}
|
||||
}
|
||||
|
||||
use {Api,
|
||||
DummyGetResponse,
|
||||
DummyPutResponse,
|
||||
FileResponseGetResponse,
|
||||
GetStructuredYamlResponse,
|
||||
HtmlPostResponse,
|
||||
PostYamlResponse,
|
||||
RawJsonGetResponse,
|
||||
SoloObjectPostResponse
|
||||
};
|
||||
|
||||
/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes.
|
||||
fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<String, ClientInitError> {
|
||||
// First convert to Uri, since a base path is a subset of Uri.
|
||||
@@ -71,7 +69,10 @@ fn into_base_path(input: &str, correct_scheme: Option<&'static str>) -> Result<S
|
||||
/// A client that implements the API by making HTTP calls out to a server.
|
||||
pub struct Client<F>
|
||||
{
|
||||
/// Inner service
|
||||
client_service: Arc<Box<dyn Service<ReqBody=Body, Future=F> + Send + Sync>>,
|
||||
|
||||
/// Base path of the API
|
||||
base_path: String,
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
pub fn try_new_http(
|
||||
base_path: &str,
|
||||
) -> Result<Self, ClientInitError> {
|
||||
let http_connector = swagger::http_connector();
|
||||
let http_connector = connector::http_connector();
|
||||
|
||||
Self::try_new_with_connector(base_path, Some("http"), http_connector)
|
||||
}
|
||||
@@ -152,7 +153,7 @@ impl Client<hyper::client::ResponseFuture>
|
||||
where
|
||||
CA: AsRef<Path>,
|
||||
{
|
||||
let https_connector = swagger::https_connector(ca_certificate);
|
||||
let https_connector = connector::https_connector(ca_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
|
||||
@@ -175,14 +176,14 @@ impl Client<hyper::client::ResponseFuture>
|
||||
D: AsRef<Path>,
|
||||
{
|
||||
let https_connector =
|
||||
swagger::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
connector::https_mutual_connector(ca_certificate, client_key, client_certificate);
|
||||
Self::try_new_with_connector(base_path, Some("https"), https_connector)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Client<F>
|
||||
{
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::client::Service`
|
||||
/// Constructor for creating a `Client` by passing in a pre-made `swagger::Service`
|
||||
///
|
||||
/// This allows adding custom wrappers around the underlying transport, for example for logging.
|
||||
pub fn try_new_with_client_service(
|
||||
@@ -196,12 +197,55 @@ impl<F> Client<F>
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type failing to create a Client
|
||||
#[derive(Debug)]
|
||||
pub enum ClientInitError {
|
||||
/// Invalid URL Scheme
|
||||
InvalidScheme,
|
||||
|
||||
/// Invalid URI
|
||||
InvalidUri(hyper::http::uri::InvalidUri),
|
||||
|
||||
/// Missing Hostname
|
||||
MissingHost,
|
||||
|
||||
/// SSL Connection Error
|
||||
SslError(openssl::error::ErrorStack)
|
||||
}
|
||||
|
||||
impl From<hyper::http::uri::InvalidUri> for ClientInitError {
|
||||
fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
|
||||
ClientInitError::InvalidUri(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<openssl::error::ErrorStack> for ClientInitError {
|
||||
fn from(err: openssl::error::ErrorStack) -> ClientInitError {
|
||||
ClientInitError::SslError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ClientInitError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s: &dyn fmt::Debug = self;
|
||||
s.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for ClientInitError {
|
||||
fn description(&self) -> &str {
|
||||
"Failed to produce a hyper client."
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, F> Api<C> for Client<F> where
|
||||
C: Has<XSpanIdString> ,
|
||||
F: Future<Item=Response<Body>, Error=hyper::Error> + Send + 'static
|
||||
{
|
||||
|
||||
fn dummy_get(&self, context: &C) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send> {
|
||||
fn dummy_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/dummy",
|
||||
self.base_path
|
||||
@@ -228,14 +272,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -269,10 +311,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn dummy_put(&self, param_nested_response: models::InlineObject, context: &C) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send> {
|
||||
fn dummy_put(
|
||||
&self,
|
||||
param_nested_response: models::InlineObject,
|
||||
context: &C) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/dummy",
|
||||
self.base_path
|
||||
@@ -307,14 +352,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -348,10 +391,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn file_response_get(&self, context: &C) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send> {
|
||||
fn file_response_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/file_response",
|
||||
self.base_path
|
||||
@@ -378,14 +423,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -397,13 +440,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
serde_json::from_str::<swagger::ByteArray>(body)
|
||||
.map_err(|e| e.into())
|
||||
)
|
||||
)
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
serde_json::from_str::<swagger::ByteArray>(body)
|
||||
.map_err(|e| e.into())
|
||||
)
|
||||
)
|
||||
.map(move |body| {
|
||||
FileResponseGetResponse::Success
|
||||
(body)
|
||||
@@ -431,10 +474,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn get_structured_yaml(&self, context: &C) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send> {
|
||||
fn get_structured_yaml(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/get-structured-yaml",
|
||||
self.base_path
|
||||
@@ -461,14 +506,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -480,12 +523,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
Ok(body.to_string())
|
||||
)
|
||||
)
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
Ok(body.to_string())
|
||||
)
|
||||
)
|
||||
.map(move |body| {
|
||||
GetStructuredYamlResponse::OK
|
||||
(body)
|
||||
@@ -513,10 +556,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn html_post(&self, param_body: String, context: &C) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send> {
|
||||
fn html_post(
|
||||
&self,
|
||||
param_body: String,
|
||||
context: &C) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/html",
|
||||
self.base_path
|
||||
@@ -551,14 +597,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -570,12 +614,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
Ok(body.to_string())
|
||||
)
|
||||
)
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
Ok(body.to_string())
|
||||
)
|
||||
)
|
||||
.map(move |body| {
|
||||
HtmlPostResponse::Success
|
||||
(body)
|
||||
@@ -603,10 +647,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn post_yaml(&self, param_value: String, context: &C) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send> {
|
||||
fn post_yaml(
|
||||
&self,
|
||||
param_value: String,
|
||||
context: &C) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/post-yaml",
|
||||
self.base_path
|
||||
@@ -641,14 +688,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create header: {} - {}", header, e))))
|
||||
});
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -682,10 +727,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn raw_json_get(&self, context: &C) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send> {
|
||||
fn raw_json_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/raw_json",
|
||||
self.base_path
|
||||
@@ -712,14 +759,12 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create request: {}", e))))
|
||||
};
|
||||
|
||||
|
||||
let header = HeaderValue::from_str((context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str());
|
||||
request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header {
|
||||
Ok(h) => h,
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -731,13 +776,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
.concat2()
|
||||
.map_err(|e| ApiError(format!("Failed to read response: {}", e)))
|
||||
.and_then(|body|
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
serde_json::from_str::<serde_json::Value>(body)
|
||||
.map_err(|e| e.into())
|
||||
)
|
||||
)
|
||||
str::from_utf8(&body)
|
||||
.map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))
|
||||
.and_then(|body|
|
||||
serde_json::from_str::<serde_json::Value>(body)
|
||||
.map_err(|e| e.into())
|
||||
)
|
||||
)
|
||||
.map(move |body| {
|
||||
RawJsonGetResponse::Success
|
||||
(body)
|
||||
@@ -765,10 +810,13 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn solo_object_post(&self, param_value: serde_json::Value, context: &C) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send> {
|
||||
fn solo_object_post(
|
||||
&self,
|
||||
param_value: serde_json::Value,
|
||||
context: &C) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
let mut uri = format!(
|
||||
"{}/solo-object",
|
||||
self.base_path
|
||||
@@ -796,6 +844,7 @@ impl<C, F> Api<C> for Client<F> where
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(¶m_value).expect("impossible to fail to serialize");
|
||||
|
||||
*request.body_mut() = Body::from(body);
|
||||
|
||||
let header = &mimetypes::requests::SOLO_OBJECT_POST;
|
||||
@@ -810,7 +859,6 @@ impl<C, F> Api<C> for Client<F> where
|
||||
Err(e) => return Box::new(future::err(ApiError(format!("Unable to create X-Span ID header value: {}", e))))
|
||||
});
|
||||
|
||||
|
||||
Box::new(self.client_service.request(request)
|
||||
.map_err(|e| ApiError(format!("No response received: {}", e)))
|
||||
.and_then(|mut response| {
|
||||
@@ -844,39 +892,6 @@ impl<C, F> Api<C> for Client<F> where
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClientInitError {
|
||||
InvalidScheme,
|
||||
InvalidUri(hyper::http::uri::InvalidUri),
|
||||
MissingHost,
|
||||
SslError(openssl::error::ErrorStack)
|
||||
}
|
||||
|
||||
impl From<hyper::http::uri::InvalidUri> for ClientInitError {
|
||||
fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError {
|
||||
ClientInitError::InvalidUri(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<openssl::error::ErrorStack> for ClientInitError {
|
||||
fn from(err: openssl::error::ErrorStack) -> ClientInitError {
|
||||
ClientInitError::SslError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ClientInitError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
(self as &dyn fmt::Debug).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for ClientInitError {
|
||||
fn description(&self) -> &str {
|
||||
"Failed to produce a hyper client."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(any(feature = "server"))]
|
||||
#[cfg(feature = "server")]
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
@@ -31,7 +31,7 @@ extern crate swagger;
|
||||
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate hyper;
|
||||
#[cfg(any(feature = "client"))]
|
||||
#[cfg(feature = "client")]
|
||||
extern crate hyper_tls;
|
||||
#[cfg(any(feature = "client", feature = "server"))]
|
||||
extern crate openssl;
|
||||
@@ -73,7 +73,6 @@ pub use futures::Future;
|
||||
pub const BASE_PATH: &'static str = "";
|
||||
pub const API_VERSION: &'static str = "2.3.4";
|
||||
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DummyGetResponse {
|
||||
/// Success
|
||||
@@ -90,21 +89,21 @@ pub enum DummyPutResponse {
|
||||
pub enum FileResponseGetResponse {
|
||||
/// Success
|
||||
Success
|
||||
( swagger::ByteArray )
|
||||
(swagger::ByteArray)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum GetStructuredYamlResponse {
|
||||
/// OK
|
||||
OK
|
||||
(String)
|
||||
(String)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum HtmlPostResponse {
|
||||
/// Success
|
||||
Success
|
||||
(String)
|
||||
(String)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -117,7 +116,7 @@ pub enum PostYamlResponse {
|
||||
pub enum RawJsonGetResponse {
|
||||
/// Success
|
||||
Success
|
||||
( serde_json::Value )
|
||||
(serde_json::Value)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -126,62 +125,93 @@ pub enum SoloObjectPostResponse {
|
||||
OK
|
||||
}
|
||||
|
||||
|
||||
/// API
|
||||
pub trait Api<C> {
|
||||
|
||||
/// A dummy endpoint to make the spec valid.
|
||||
fn dummy_get(&self, context: &C) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>;
|
||||
fn dummy_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn dummy_put(&self, nested_response: models::InlineObject, context: &C) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>;
|
||||
fn dummy_put(
|
||||
&self,
|
||||
nested_response: models::InlineObject,
|
||||
context: &C) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get a file
|
||||
fn file_response_get(&self, context: &C) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>;
|
||||
fn file_response_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn get_structured_yaml(&self, context: &C) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>;
|
||||
fn get_structured_yaml(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Test HTML handling
|
||||
fn html_post(&self, body: String, context: &C) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>;
|
||||
fn html_post(
|
||||
&self,
|
||||
body: String,
|
||||
context: &C) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn post_yaml(&self, value: String, context: &C) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>;
|
||||
fn post_yaml(
|
||||
&self,
|
||||
value: String,
|
||||
context: &C) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get an arbitrary JSON blob.
|
||||
fn raw_json_get(&self, context: &C) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>;
|
||||
fn raw_json_get(
|
||||
&self,
|
||||
context: &C) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Send an arbitrary JSON blob
|
||||
fn solo_object_post(&self, value: serde_json::Value, context: &C) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>;
|
||||
fn solo_object_post(
|
||||
&self,
|
||||
value: serde_json::Value,
|
||||
context: &C) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
/// API without a `Context`
|
||||
pub trait ApiNoContext {
|
||||
|
||||
/// A dummy endpoint to make the spec valid.
|
||||
fn dummy_get(&self) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>;
|
||||
fn dummy_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn dummy_put(&self, nested_response: models::InlineObject) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>;
|
||||
fn dummy_put(
|
||||
&self,
|
||||
nested_response: models::InlineObject,
|
||||
) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get a file
|
||||
fn file_response_get(&self) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>;
|
||||
fn file_response_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn get_structured_yaml(&self) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>;
|
||||
fn get_structured_yaml(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Test HTML handling
|
||||
fn html_post(&self, body: String) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>;
|
||||
fn html_post(
|
||||
&self,
|
||||
body: String,
|
||||
) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
|
||||
fn post_yaml(&self, value: String) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>;
|
||||
fn post_yaml(
|
||||
&self,
|
||||
value: String,
|
||||
) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Get an arbitrary JSON blob.
|
||||
fn raw_json_get(&self) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>;
|
||||
fn raw_json_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>;
|
||||
|
||||
/// Send an arbitrary JSON blob
|
||||
fn solo_object_post(&self, value: serde_json::Value) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>;
|
||||
fn solo_object_post(
|
||||
&self,
|
||||
value: serde_json::Value,
|
||||
) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>;
|
||||
|
||||
}
|
||||
|
||||
@@ -198,44 +228,68 @@ impl<'a, T: Api<C> + Sized, C> ContextWrapperExt<'a, C> for T {
|
||||
}
|
||||
|
||||
impl<'a, T: Api<C>, C> ApiNoContext for ContextWrapper<'a, T, C> {
|
||||
|
||||
/// A dummy endpoint to make the spec valid.
|
||||
fn dummy_get(&self) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send> {
|
||||
fn dummy_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=DummyGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().dummy_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn dummy_put(&self, nested_response: models::InlineObject) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send> {
|
||||
fn dummy_put(
|
||||
&self,
|
||||
nested_response: models::InlineObject,
|
||||
) -> Box<dyn Future<Item=DummyPutResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().dummy_put(nested_response, &self.context())
|
||||
}
|
||||
|
||||
/// Get a file
|
||||
fn file_response_get(&self) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send> {
|
||||
fn file_response_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=FileResponseGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().file_response_get(&self.context())
|
||||
}
|
||||
|
||||
|
||||
fn get_structured_yaml(&self) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send> {
|
||||
fn get_structured_yaml(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=GetStructuredYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().get_structured_yaml(&self.context())
|
||||
}
|
||||
|
||||
/// Test HTML handling
|
||||
fn html_post(&self, body: String) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send> {
|
||||
fn html_post(
|
||||
&self,
|
||||
body: String,
|
||||
) -> Box<dyn Future<Item=HtmlPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().html_post(body, &self.context())
|
||||
}
|
||||
|
||||
|
||||
fn post_yaml(&self, value: String) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send> {
|
||||
fn post_yaml(
|
||||
&self,
|
||||
value: String,
|
||||
) -> Box<dyn Future<Item=PostYamlResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().post_yaml(value, &self.context())
|
||||
}
|
||||
|
||||
/// Get an arbitrary JSON blob.
|
||||
fn raw_json_get(&self) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send> {
|
||||
fn raw_json_get(
|
||||
&self,
|
||||
) -> Box<dyn Future<Item=RawJsonGetResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().raw_json_get(&self.context())
|
||||
}
|
||||
|
||||
/// Send an arbitrary JSON blob
|
||||
fn solo_object_post(&self, value: serde_json::Value) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send> {
|
||||
fn solo_object_post(
|
||||
&self,
|
||||
value: serde_json::Value,
|
||||
) -> Box<dyn Future<Item=SoloObjectPostResponse, Error=ApiError> + Send>
|
||||
{
|
||||
self.api().solo_object_post(value, &self.context())
|
||||
}
|
||||
|
||||
@@ -246,7 +300,7 @@ pub mod client;
|
||||
|
||||
// Re-export Client as a top-level name
|
||||
#[cfg(feature = "client")]
|
||||
pub use self::client::Client;
|
||||
pub use client::Client;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod server;
|
||||
@@ -255,5 +309,8 @@ pub mod server;
|
||||
#[cfg(feature = "server")]
|
||||
pub use self::server::Service;
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
pub mod context;
|
||||
|
||||
pub mod models;
|
||||
pub mod header;
|
||||
|
||||
@@ -12,9 +12,11 @@ pub mod responses {
|
||||
/// Create &str objects for the response content types for HtmlPost
|
||||
pub static HTML_POST_SUCCESS: &str = "text/html";
|
||||
|
||||
|
||||
/// Create &str objects for the response content types for RawJsonGet
|
||||
pub static RAW_JSON_GET_SUCCESS: &str = "*/*";
|
||||
|
||||
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
@@ -22,12 +24,15 @@ pub mod requests {
|
||||
/// Create &str objects for the request content types for DummyPut
|
||||
pub static DUMMY_PUT: &str = "application/json";
|
||||
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for HtmlPost
|
||||
pub static HTML_POST: &str = "text/html";
|
||||
|
||||
/// Create &str objects for the request content types for PostYaml
|
||||
pub static POST_YAML: &str = "application/yaml";
|
||||
|
||||
|
||||
/// Create &str objects for the request content types for SoloObjectPost
|
||||
pub static SOLO_OBJECT_POST: &str = "application/json";
|
||||
|
||||
|
||||
@@ -5,18 +5,22 @@ use futures::{Future, future, Stream, stream};
|
||||
use hyper;
|
||||
use hyper::{Request, Response, Error, StatusCode, Body, HeaderMap};
|
||||
use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE};
|
||||
use url::form_urlencoded;
|
||||
use mimetypes;
|
||||
use serde_json;
|
||||
use std::io;
|
||||
#[allow(unused_imports)]
|
||||
use swagger;
|
||||
use swagger::{ApiError, XSpanIdString, Has, RequestParser};
|
||||
pub use swagger::auth::Authorization;
|
||||
use swagger::auth::Scopes;
|
||||
use swagger::context::ContextualPayload;
|
||||
use url::form_urlencoded;
|
||||
|
||||
use mimetypes;
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub use swagger::auth::Authorization;
|
||||
pub use crate::context;
|
||||
|
||||
use {Api,
|
||||
DummyGetResponse,
|
||||
@@ -27,13 +31,7 @@ use {Api,
|
||||
PostYamlResponse,
|
||||
RawJsonGetResponse,
|
||||
SoloObjectPostResponse
|
||||
};
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
use header;
|
||||
|
||||
pub mod context;
|
||||
};
|
||||
|
||||
mod paths {
|
||||
extern crate regex;
|
||||
@@ -131,8 +129,6 @@ where
|
||||
let mut context = body.context;
|
||||
let body = body.inner;
|
||||
|
||||
// This match statement is duplicated below in `parse_operation_id()`.
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
|
||||
// DummyGet - GET /dummy
|
||||
@@ -149,15 +145,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
DummyGetResponse::Success
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -207,6 +199,7 @@ where
|
||||
.body(Body::from("Missing required body parameter nested_response"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter nested_response"))),
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.dummy_put(
|
||||
param_nested_response,
|
||||
@@ -218,7 +211,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -229,11 +221,8 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
DummyPutResponse::Success
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -271,22 +260,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
FileResponseGetResponse::Success
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::FILE_RESPONSE_GET_SUCCESS)
|
||||
.expect("Unable to create Content-Type header for FILE_RESPONSE_GET_SUCCESS"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -320,22 +303,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
GetStructuredYamlResponse::OK
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::GET_STRUCTURED_YAML_OK)
|
||||
.expect("Unable to create Content-Type header for GET_STRUCTURED_YAML_OK"));
|
||||
|
||||
let body = body;
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -382,6 +359,7 @@ where
|
||||
.body(Body::from("Missing required body parameter body"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter body"))),
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.html_post(
|
||||
param_body,
|
||||
@@ -393,22 +371,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
HtmlPostResponse::Success
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::HTML_POST_SUCCESS)
|
||||
.expect("Unable to create Content-Type header for HTML_POST_SUCCESS"));
|
||||
|
||||
let body = body;
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -461,6 +433,7 @@ where
|
||||
.body(Body::from("Missing required body parameter value"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter value"))),
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.post_yaml(
|
||||
param_value,
|
||||
@@ -472,15 +445,11 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
PostYamlResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -518,22 +487,16 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
RawJsonGetResponse::Success
|
||||
|
||||
(body)
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode");
|
||||
|
||||
response.headers_mut().insert(
|
||||
CONTENT_TYPE,
|
||||
HeaderValue::from_str(mimetypes::responses::RAW_JSON_GET_SUCCESS)
|
||||
.expect("Unable to create Content-Type header for RAW_JSON_GET_SUCCESS"));
|
||||
|
||||
let body = serde_json::to_string(&body).expect("impossible to fail to serialize");
|
||||
*response.body_mut() = Body::from(body);
|
||||
},
|
||||
@@ -585,6 +548,7 @@ where
|
||||
.body(Body::from("Missing required body parameter value"))
|
||||
.expect("Unable to create Bad Request response for missing body parameter value"))),
|
||||
};
|
||||
|
||||
Box::new(
|
||||
api_impl.solo_object_post(
|
||||
param_value,
|
||||
@@ -596,7 +560,6 @@ where
|
||||
HeaderValue::from_str((&context as &dyn Has<XSpanIdString>).get().0.clone().to_string().as_str())
|
||||
.expect("Unable to create X-Span-ID header value"));
|
||||
|
||||
|
||||
if !unused_elements.is_empty() {
|
||||
response.headers_mut().insert(
|
||||
HeaderName::from_static("warning"),
|
||||
@@ -607,11 +570,8 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
SoloObjectPostResponse::OK
|
||||
|
||||
|
||||
=> {
|
||||
*response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode");
|
||||
|
||||
},
|
||||
},
|
||||
Err(_) => {
|
||||
@@ -660,28 +620,20 @@ impl<T> RequestParser<T> for ApiRequestParser {
|
||||
fn parse_operation_id(request: &Request<T>) -> Result<&'static str, ()> {
|
||||
let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path());
|
||||
match request.method() {
|
||||
|
||||
// DummyGet - GET /dummy
|
||||
&hyper::Method::GET if path.matched(paths::ID_DUMMY) => Ok("DummyGet"),
|
||||
|
||||
// DummyPut - PUT /dummy
|
||||
&hyper::Method::PUT if path.matched(paths::ID_DUMMY) => Ok("DummyPut"),
|
||||
|
||||
// FileResponseGet - GET /file_response
|
||||
&hyper::Method::GET if path.matched(paths::ID_FILE_RESPONSE) => Ok("FileResponseGet"),
|
||||
|
||||
// GetStructuredYaml - GET /get-structured-yaml
|
||||
&hyper::Method::GET if path.matched(paths::ID_GET_STRUCTURED_YAML) => Ok("GetStructuredYaml"),
|
||||
|
||||
// HtmlPost - POST /html
|
||||
&hyper::Method::POST if path.matched(paths::ID_HTML) => Ok("HtmlPost"),
|
||||
|
||||
// PostYaml - POST /post-yaml
|
||||
&hyper::Method::POST if path.matched(paths::ID_POST_YAML) => Ok("PostYaml"),
|
||||
|
||||
// RawJsonGet - GET /raw_json
|
||||
&hyper::Method::GET if path.matched(paths::ID_RAW_JSON) => Ok("RawJsonGet"),
|
||||
|
||||
// SoloObjectPost - POST /solo-object
|
||||
&hyper::Method::POST if path.matched(paths::ID_SOLO_OBJECT) => Ok("SoloObjectPost"),
|
||||
_ => Err(()),
|
||||
|
||||
Reference in New Issue
Block a user