forked from loafle/openapi-generator-original
Merge remote-tracking branch 'origin/master' into 4.0.x
This commit is contained in:
32
bin/cpp-qt5-server-petstore.sh
Executable file
32
bin/cpp-qt5-server-petstore.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPT="$0"
|
||||
echo "# START SCRIPT: $SCRIPT"
|
||||
|
||||
while [ -h "$SCRIPT" ] ; do
|
||||
ls=`ls -ld "$SCRIPT"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
SCRIPT="$link"
|
||||
else
|
||||
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -d "${APP_DIR}" ]; then
|
||||
APP_DIR=`dirname "$SCRIPT"`/..
|
||||
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||
fi
|
||||
|
||||
executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
|
||||
|
||||
if [ ! -f "$executable" ]
|
||||
then
|
||||
mvn -B clean package
|
||||
fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate -t modules/openapi-generator/src/main/resources/cpp-qt5-server -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g cpp-qt5-server -o samples/server/petstore/cpp-qt5-server $@"
|
||||
|
||||
java $JAVA_OPTS -jar $executable $ags
|
||||
@@ -27,7 +27,7 @@ fi
|
||||
|
||||
# if you've executed sbt assembly previously it will use that instead.
|
||||
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||
ags="generate --artifact-id petstore-java-client-jersey1 -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -o samples/client/petstore/java/jersey1 -DhideGenerationTimestamp=true --library=jersey1 $@"
|
||||
ags="generate --artifact-id petstore-java-client-jersey1 -t modules/openapi-generator/src/main/resources/Java -i modules/openapi-generator/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -g java -o samples/client/petstore/java/jersey1 -DhideGenerationTimestamp=true --library=jersey1 --additional-properties useNullForUnknownEnumValue=true $@"
|
||||
|
||||
echo "Removing files and folders under samples/client/petstore/java/jersey1/src/main"
|
||||
rm -rf samples/client/petstore/java/jersey1/src/main
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": "jersey2",
|
||||
"artifactId": "petstore-jersey2"
|
||||
"artifactId": "petstore-jersey2",
|
||||
"additionalProperties" : {
|
||||
"useNullForUnknownEnumValue" : true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,17 @@ For the templates, this is not an API change, because the same values are availa
|
||||
|
||||
If you have your own `Codegen` class (to support your own generator for example) then you might get some compile error due to the change.
|
||||
|
||||
==== Java
|
||||
|
||||
Schema with enum values are mapped to java enum in the generated code.
|
||||
In previous version, when an unknown value was deserialized, the value was set to `null`.
|
||||
|
||||
With `3.2.0` a new option is introduced: `useNullForUnknownEnumValue`.
|
||||
|
||||
* When set to `false` (default value), an Exception (`IllegalArgumentException`) is thrown when the value not available in the enum.
|
||||
* When set to `true`, unknown values are mapped to `null` as it was the case in previous versions.
|
||||
|
||||
|
||||
=== From 3.0.x to 3.1.0
|
||||
|
||||
Version `3.1.0` is the first minor version of OpenAPI-Generator, in comparison to `3.0.3` it contains some breaking changes, but with the possibility to fallback to the old behavior.
|
||||
|
||||
@@ -72,4 +72,4 @@ public class ConfigHelp implements Runnable {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,6 +194,11 @@ public class Generate implements Runnable {
|
||||
description = CodegenConstants.REMOVE_OPERATION_ID_PREFIX_DESC)
|
||||
private Boolean removeOperationIdPrefix;
|
||||
|
||||
@Option(name = {"--skip-validate-spec"},
|
||||
title = "skip spec validation",
|
||||
description = "Skips the default behavior of validating an input specification.")
|
||||
private Boolean skipValidateSpec;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -207,6 +212,10 @@ public class Generate implements Runnable {
|
||||
}
|
||||
|
||||
// now override with any specified parameters
|
||||
if (skipValidateSpec != null) {
|
||||
configurator.setValidateSpec(false);
|
||||
}
|
||||
|
||||
if (verbose != null) {
|
||||
configurator.setVerbose(verbose);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,11 @@ The gradle plugin is not currently published to https://plugins.gradle.org/m2/.
|
||||
|false
|
||||
|The verbosity of generation
|
||||
|
||||
|validateSpec
|
||||
|Boolean
|
||||
|true
|
||||
|Whether or not we should validate the input spec before generation. Invalid specs result in an error.
|
||||
|
||||
|generatorName
|
||||
|String
|
||||
|None
|
||||
|
||||
@@ -11,6 +11,7 @@ gradle openApiGenerate
|
||||
gradle openApiMeta
|
||||
gradle openApiValidate
|
||||
gradle buildGoSdk
|
||||
gradle generateGoWithInvalidSpec
|
||||
```
|
||||
|
||||
The samples can be tested against other versions of the plugin using the `openApiGeneratorVersion` property. For example:
|
||||
|
||||
@@ -54,3 +54,16 @@ task buildGoSdk(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTas
|
||||
dateLibrary: "threetenp"
|
||||
]
|
||||
}
|
||||
|
||||
task generateGoWithInvalidSpec(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask){
|
||||
validateSpec = true
|
||||
generatorName = "go"
|
||||
inputSpec = "$rootDir/petstore-v3.0-invalid.yaml".toString()
|
||||
additionalProperties = [
|
||||
packageName: "petstore"
|
||||
]
|
||||
outputDir = "$buildDir/go".toString()
|
||||
configOptions = [
|
||||
dateLibrary: "threetenp"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ class OpenApiGeneratorPlugin : Plugin<Project> {
|
||||
description = "Generate code via Open API Tools Generator for Open API 2.0 or 3.x specification documents."
|
||||
|
||||
verbose.set(generate.verbose)
|
||||
validateSpec.set(generate.validateSpec)
|
||||
generatorName.set(generate.generatorName)
|
||||
outputDir.set(generate.outputDir)
|
||||
inputSpec.set(generate.inputSpec)
|
||||
|
||||
@@ -32,6 +32,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
|
||||
*/
|
||||
val verbose = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Whether or not an input specification should be validated upon generation.
|
||||
*/
|
||||
val validateSpec = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
|
||||
*/
|
||||
@@ -262,6 +267,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
|
||||
val configOptions = project.objects.property<Map<String, String>>()
|
||||
|
||||
init {
|
||||
applyDefaults()
|
||||
}
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
fun applyDefaults(){
|
||||
releaseNote.set("Minor update")
|
||||
modelNamePrefix.set("")
|
||||
modelNameSuffix.set("")
|
||||
@@ -271,5 +281,6 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
|
||||
generateApiDocumentation.set(true)
|
||||
withXml.set(false)
|
||||
configOptions.set(mapOf())
|
||||
validateSpec.set(true)
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ import org.gradle.kotlin.dsl.property
|
||||
import org.openapitools.codegen.CodegenConstants
|
||||
import org.openapitools.codegen.DefaultGenerator
|
||||
import org.openapitools.codegen.config.CodegenConfigurator
|
||||
import org.openapitools.codegen.config.CodegenConfiguratorUtils.*
|
||||
|
||||
|
||||
/**
|
||||
@@ -48,6 +47,12 @@ open class GenerateTask : DefaultTask() {
|
||||
@get:Internal
|
||||
val verbose = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* Whether or not an input specification should be validated upon generation.
|
||||
*/
|
||||
@get:Internal
|
||||
val validateSpec = project.objects.property<Boolean>()
|
||||
|
||||
/**
|
||||
* The name of the generator which will handle codegen. (see "openApiGenerators" task)
|
||||
*/
|
||||
@@ -382,6 +387,10 @@ open class GenerateTask : DefaultTask() {
|
||||
configurator.isVerbose = value
|
||||
}
|
||||
|
||||
validateSpec.ifNotEmpty { value ->
|
||||
configurator.isValidateSpec = value
|
||||
}
|
||||
|
||||
skipOverwrite.ifNotEmpty { value ->
|
||||
configurator.isSkipOverwrite = value ?: false
|
||||
}
|
||||
@@ -528,8 +537,7 @@ open class GenerateTask : DefaultTask() {
|
||||
|
||||
out.println("Successfully generated code to ${configurator.outputDir}")
|
||||
} catch (e: RuntimeException) {
|
||||
logger.error(e.message)
|
||||
throw GradleException("Code generation failed.")
|
||||
throw GradleException("Code generation failed.", e)
|
||||
}
|
||||
} finally {
|
||||
originalEnvironmentVariables.forEach { entry ->
|
||||
|
||||
@@ -31,7 +31,7 @@ class GenerateTaskDslTest : TestBase() {
|
||||
fun `openApiGenerate should create an expected file structure from DSL config`() {
|
||||
// Arrange
|
||||
val projectFiles = mapOf(
|
||||
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0-invalid.yaml")
|
||||
"spec.yaml" to javaClass.classLoader.getResourceAsStream("specs/petstore-v3.0.yaml")
|
||||
)
|
||||
withProject(defaultBuildGradle, projectFiles)
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ mvn clean compile
|
||||
### General Configuration parameters
|
||||
|
||||
- `inputSpec` - OpenAPI Spec file path
|
||||
- `validateSpec` - Whether or not to validate the input spec prior to generation. Invalid specifications will result in an error.
|
||||
- `language` - target generation language (deprecated, replaced by `generatorName` as values here don't represent only 'language' any longer)
|
||||
- `generatorName` - target generator name
|
||||
- `output` - target output path (default is `${project.build.directory}/generated-sources/swagger`)
|
||||
@@ -102,4 +103,8 @@ Specifying a custom generator is a bit different. It doesn't support the classpa
|
||||
|
||||
### Sample configuration
|
||||
|
||||
- Please see [an example configuration](examples) for using the plugin
|
||||
Please see [an example configuration](examples) for using the plugin. To run these examples, explicitly pass the file to maven. Example:
|
||||
|
||||
```bash
|
||||
mvn -f non-java.xml compile
|
||||
```
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.0.1-SNAPSHOT</version>
|
||||
<version>3.1.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>sample-project</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>sample-project</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- activate the plugin -->
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.1.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<validateSpec>false</validateSpec>
|
||||
<inputSpec>petstore-v3.0-invalid.yaml</inputSpec>
|
||||
<generatorName>aspnetcore</generatorName>
|
||||
<configOptions>
|
||||
<additional-properties>optionalProjectFile=true</additional-properties>
|
||||
</configOptions>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -12,7 +12,7 @@
|
||||
<plugin>
|
||||
<groupId>org.openapitools</groupId>
|
||||
<artifactId>openapi-generator-maven-plugin</artifactId>
|
||||
<version>3.0.1-SNAPSHOT</version>
|
||||
<version>3.1.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
openapi: "3.0.0"
|
||||
servers:
|
||||
- url: http://petstore.swagger.io/v1
|
||||
paths:
|
||||
/pets:
|
||||
get:
|
||||
summary: List all pets
|
||||
operationId: listPets
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: limit
|
||||
in: query
|
||||
description: How many items to return at one time (max 100)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int32
|
||||
responses:
|
||||
'200':
|
||||
description: A paged array of pets
|
||||
headers:
|
||||
x-next:
|
||||
description: A link to the next page of responses
|
||||
schema:
|
||||
type: string
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
post:
|
||||
summary: Create a pet
|
||||
tags:
|
||||
- pets
|
||||
responses:
|
||||
'201':
|
||||
description: Null response
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
/pets/{petId}:
|
||||
get:
|
||||
summary: Info for a specific pet
|
||||
operationId: showPetById
|
||||
tags:
|
||||
- pets
|
||||
parameters:
|
||||
- name: petId
|
||||
in: path
|
||||
required: true
|
||||
description: The id of the pet to retrieve
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Expected response to a valid request
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Pets"
|
||||
default:
|
||||
description: unexpected error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Error"
|
||||
components:
|
||||
schemas:
|
||||
Pet:
|
||||
required:
|
||||
- id
|
||||
- name
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
name:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
Pets:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Pet"
|
||||
Error:
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int32
|
||||
message:
|
||||
type: string
|
||||
@@ -60,6 +60,9 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenMojo.class);
|
||||
|
||||
@Parameter(name="validateSpec", required = false, defaultValue = "true")
|
||||
private Boolean validateSpec;
|
||||
|
||||
@Parameter(name = "verbose", required = false, defaultValue = "false")
|
||||
private boolean verbose;
|
||||
|
||||
@@ -348,6 +351,11 @@ public class CodeGenMojo extends AbstractMojo {
|
||||
|
||||
configurator.setVerbose(verbose);
|
||||
|
||||
// now override with any specified parameters
|
||||
if (validateSpec != null) {
|
||||
configurator.setValidateSpec(validateSpec);
|
||||
}
|
||||
|
||||
if (skipOverwrite != null) {
|
||||
configurator.setSkipOverwrite(skipOverwrite);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
package org.openapitools.codegen;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class SpecValidationException extends RuntimeException {
|
||||
|
||||
private Set<String> errors;
|
||||
private Set<String> warnings;
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with {@code null} as its
|
||||
* detail message. The cause is not initialized, and may subsequently be
|
||||
* initialized by a call to {@link #initCause}.
|
||||
*/
|
||||
public SpecValidationException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail message.
|
||||
* The cause is not initialized, and may subsequently be initialized by a
|
||||
* call to {@link #initCause}.
|
||||
*
|
||||
* @param message the detail message. The detail message is saved for
|
||||
* later retrieval by the {@link #getMessage()} method.
|
||||
*/
|
||||
public SpecValidationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail message and
|
||||
* cause. <p>Note that the detail message associated with
|
||||
* {@code cause} is <i>not</i> automatically incorporated in
|
||||
* this runtime exception's detail message.
|
||||
*
|
||||
* @param message the detail message (which is saved for later retrieval
|
||||
* by the {@link #getMessage()} method).
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public SpecValidationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified cause and a
|
||||
* detail message of <tt>(cause==null ? null : cause.toString())</tt>
|
||||
* (which typically contains the class and detail message of
|
||||
* <tt>cause</tt>). This constructor is useful for runtime exceptions
|
||||
* that are little more than wrappers for other throwables.
|
||||
*
|
||||
* @param cause the cause (which is saved for later retrieval by the
|
||||
* {@link #getCause()} method). (A <tt>null</tt> value is
|
||||
* permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
* @since 1.4
|
||||
*/
|
||||
public SpecValidationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new runtime exception with the specified detail
|
||||
* message, cause, suppression enabled or disabled, and writable
|
||||
* stack trace enabled or disabled.
|
||||
*
|
||||
* @param message the detail message.
|
||||
* @param cause the cause. (A {@code null} value is permitted,
|
||||
* and indicates that the cause is nonexistent or unknown.)
|
||||
* @param enableSuppression whether or not suppression is enabled
|
||||
* or disabled
|
||||
* @param writableStackTrace whether or not the stack trace should
|
||||
* be writable
|
||||
* @since 1.7
|
||||
*/
|
||||
public SpecValidationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public Set<String> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public Set<String> getWarnings() {
|
||||
return warnings;
|
||||
}
|
||||
|
||||
public void setErrors(Set<String> errors) {
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public void setWarnings(Set<String> warnings) {
|
||||
this.warnings = warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the detail message string of this throwable.
|
||||
*
|
||||
* @return the detail message string of this {@code Throwable} instance
|
||||
* (which may be {@code null}).
|
||||
*/
|
||||
@Override
|
||||
public String getMessage() {
|
||||
int errorCount = 0;
|
||||
if (errors != null) {
|
||||
errorCount = errors.size();
|
||||
}
|
||||
int warningCount = 0;
|
||||
if (warnings != null) {
|
||||
warningCount = warnings.size();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(System.lineSeparator())
|
||||
.append("Errors: ")
|
||||
.append(System.lineSeparator());
|
||||
errors.forEach(msg ->
|
||||
sb.append("\t-").append(msg).append(System.lineSeparator())
|
||||
);
|
||||
|
||||
if (!warnings.isEmpty()) {
|
||||
sb.append("Warnings: ").append(System.lineSeparator());
|
||||
warnings.forEach(msg ->
|
||||
sb.append("\t-").append(msg).append(System.lineSeparator())
|
||||
);
|
||||
}
|
||||
return super.getMessage() + " | " +
|
||||
"Error count: " + errorCount + ", Warning count: " + warningCount + sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,8 @@ package org.openapitools.codegen.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.ClientOptInput;
|
||||
import org.openapitools.codegen.ClientOpts;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
import org.openapitools.codegen.CodegenConfigLoader;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.auth.AuthParser;
|
||||
import io.swagger.parser.OpenAPIParser;
|
||||
import io.swagger.v3.core.util.Json;
|
||||
@@ -33,6 +29,7 @@ import io.swagger.v3.parser.core.models.ParseOptions;
|
||||
import io.swagger.v3.parser.core.models.SwaggerParseResult;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.openapitools.codegen.languages.*;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -80,6 +77,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
private boolean verbose;
|
||||
private boolean skipOverwrite;
|
||||
private boolean removeOperationIdPrefix;
|
||||
private boolean validateSpec;
|
||||
private String templateDir;
|
||||
private String auth;
|
||||
private String apiPackage;
|
||||
@@ -108,6 +106,7 @@ public class CodegenConfigurator implements Serializable {
|
||||
private final Map<String, Object> dynamicProperties = new HashMap<String, Object>(); //the map that holds the JsonAnySetter/JsonAnyGetter values
|
||||
|
||||
public CodegenConfigurator() {
|
||||
this.validateSpec = true;
|
||||
this.setOutputDir(".");
|
||||
}
|
||||
|
||||
@@ -211,6 +210,15 @@ public class CodegenConfigurator implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isValidateSpec() {
|
||||
return validateSpec;
|
||||
}
|
||||
|
||||
public CodegenConfigurator setValidateSpec(final boolean validateSpec) {
|
||||
this.validateSpec = validateSpec;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isSkipOverwrite() {
|
||||
return skipOverwrite;
|
||||
}
|
||||
@@ -514,8 +522,45 @@ public class CodegenConfigurator implements Serializable {
|
||||
options.setResolve(true);
|
||||
options.setFlatten(true);
|
||||
SwaggerParseResult result = new OpenAPIParser().readLocation(inputSpec, authorizationValues, options);
|
||||
|
||||
Set<String> validationMessages = new HashSet<>(result.getMessages());
|
||||
OpenAPI specification = result.getOpenAPI();
|
||||
|
||||
// NOTE: We will only expose errors+warnings if there are already errors in the spec.
|
||||
if (validationMessages.size() > 0) {
|
||||
Set<String> warnings = new HashSet<>();
|
||||
if (specification != null) {
|
||||
List<String> unusedModels = ModelUtils.getUnusedSchemas(specification);
|
||||
if (unusedModels != null) unusedModels.forEach(name -> warnings.add("Unused model: " + name));
|
||||
}
|
||||
|
||||
if (this.isValidateSpec()) {
|
||||
SpecValidationException ex = new SpecValidationException("Specification has failed validation.");
|
||||
ex.setErrors(validationMessages);
|
||||
ex.setWarnings(warnings);
|
||||
throw ex;
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("There were issues with the specification, but validation has been explicitly disabled.");
|
||||
sb.append(System.lineSeparator());
|
||||
|
||||
sb.append("Errors: ").append(System.lineSeparator());
|
||||
validationMessages.forEach(msg ->
|
||||
sb.append("\t-").append(msg).append(System.lineSeparator())
|
||||
);
|
||||
|
||||
if (!warnings.isEmpty()) {
|
||||
sb.append("Warnings: ").append(System.lineSeparator());
|
||||
warnings.forEach(msg ->
|
||||
sb.append("\t-").append(msg).append(System.lineSeparator())
|
||||
);
|
||||
}
|
||||
LOGGER.warn(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
input.opts(new ClientOpts())
|
||||
.openAPI(result.getOpenAPI());
|
||||
.openAPI(specification);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
public static final String DISABLE_HTML_ESCAPING = "disableHtmlEscaping";
|
||||
public static final String BOOLEAN_GETTER_PREFIX = "booleanGetterPrefix";
|
||||
public static final String BOOLEAN_GETTER_PREFIX_DEFAULT = "get";
|
||||
public static final String USE_NULL_FOR_UNKNOWN_ENUM_VALUE = "useNullForUnknownEnumValue";
|
||||
|
||||
protected String dateLibrary = "threetenbp";
|
||||
protected boolean supportAsync = false;
|
||||
@@ -99,6 +100,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
protected boolean supportJava6= false;
|
||||
protected boolean disableHtmlEscaping = false;
|
||||
protected String booleanGetterPrefix = BOOLEAN_GETTER_PREFIX_DEFAULT;
|
||||
protected boolean useNullForUnknownEnumValue = false;
|
||||
|
||||
public AbstractJavaCodegen() {
|
||||
super();
|
||||
@@ -213,6 +215,11 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
}
|
||||
additionalProperties.put(BOOLEAN_GETTER_PREFIX, booleanGetterPrefix);
|
||||
|
||||
if (additionalProperties.containsKey(USE_NULL_FOR_UNKNOWN_ENUM_VALUE)) {
|
||||
this.setUseNullForUnknownEnumValue(Boolean.valueOf(additionalProperties.get(USE_NULL_FOR_UNKNOWN_ENUM_VALUE).toString()));
|
||||
}
|
||||
additionalProperties.put(USE_NULL_FOR_UNKNOWN_ENUM_VALUE, useNullForUnknownEnumValue);
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
|
||||
this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
|
||||
} else if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
|
||||
@@ -1254,6 +1261,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code
|
||||
this.booleanGetterPrefix = booleanGetterPrefix;
|
||||
}
|
||||
|
||||
public void setUseNullForUnknownEnumValue(boolean useNullForUnknownEnumValue) {
|
||||
this.useNullForUnknownEnumValue = useNullForUnknownEnumValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
// remove " to avoid code injection
|
||||
|
||||
@@ -23,13 +23,9 @@ import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenOperation;
|
||||
import org.openapitools.codegen.CodegenParameter;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.DefaultCodegen;
|
||||
import org.openapitools.codegen.SupportingFile;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.media.*;
|
||||
|
||||
import java.io.File;
|
||||
@@ -702,6 +698,22 @@ public abstract class AbstractPhpCodegen extends DefaultCodegen implements Codeg
|
||||
return super.escapeText(input).trim();
|
||||
}
|
||||
|
||||
public void escapeMediaType(List<CodegenOperation> operationList) {
|
||||
for (CodegenOperation op : operationList) {
|
||||
if (!op.hasProduces) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Map<String, String>> c = op.produces;
|
||||
for (Map<String, String> mediaType : c) {
|
||||
// "*/*" causes a syntax error
|
||||
if ("*/*".equals(mediaType.get("mediaType"))) {
|
||||
mediaType.put("mediaType", "*_/_*");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String extractSimpleName(String phpClassName) {
|
||||
if (phpClassName == null) {
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
|
||||
* Copyright 2018 SmartBear Software
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.*;
|
||||
import org.openapitools.codegen.utils.ModelUtils;
|
||||
|
||||
import io.swagger.v3.oas.models.media.*;
|
||||
import io.swagger.v3.parser.util.SchemaTypeUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class CppQt5ServerCodegen extends AbstractCppCodegen implements CodegenConfig {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CppQt5ServerCodegen.class);
|
||||
|
||||
public static final String CPP_NAMESPACE = "cppNamespace";
|
||||
public static final String CPP_NAMESPACE_DESC = "C++ namespace (convention: name::space::for::api).";
|
||||
|
||||
protected final String PREFIX = "OAI";
|
||||
protected final String SRC_DIR = "/src";
|
||||
protected final String MODEL_DIR = "/src/models";
|
||||
protected final String APIHANDLER_DIR = "/src/handlers";
|
||||
protected final String APIREQUEST_DIR = "/src/requests";
|
||||
protected Set<String> foundationClasses = new HashSet<String>();
|
||||
// source folder where to write the files
|
||||
protected String sourceFolder = "server";
|
||||
protected String apiVersion = "1.0.0";
|
||||
protected Map<String, String> namespaces = new HashMap<String, String>();
|
||||
protected Set<String> systemIncludes = new HashSet<String>();
|
||||
protected String cppNamespace = "OpenAPI";
|
||||
|
||||
public CppQt5ServerCodegen() {
|
||||
super();
|
||||
|
||||
// set the output folder here
|
||||
outputFolder = "generated-code/cpp-qt5-server";
|
||||
|
||||
// set modelNamePrefix as default for QT5CPP
|
||||
if (StringUtils.isEmpty(modelNamePrefix)) {
|
||||
modelNamePrefix = PREFIX;
|
||||
}
|
||||
|
||||
/*
|
||||
* Models. You can write model files using the modelTemplateFiles map.
|
||||
* if you want to create one template for file, you can do so here.
|
||||
* for multiple files for model, just put another entry in the `modelTemplateFiles` with
|
||||
* a different extension
|
||||
*/
|
||||
modelTemplateFiles.put(
|
||||
"model-header.mustache",
|
||||
".h");
|
||||
|
||||
modelTemplateFiles.put(
|
||||
"model-body.mustache",
|
||||
".cpp");
|
||||
|
||||
/*
|
||||
* Api classes. You can write classes for each Api file with the apiTemplateFiles map.
|
||||
* as with models, add multiple entries with different extensions for multiple files per
|
||||
* class
|
||||
*/
|
||||
apiTemplateFiles.put(
|
||||
"apihandler.h.mustache", // the template to use
|
||||
".h"); // the extension for each file to write
|
||||
|
||||
apiTemplateFiles.put(
|
||||
"apihandler.cpp.mustache", // the template to use
|
||||
".cpp"); // the extension for each file to write
|
||||
|
||||
apiTemplateFiles.put(
|
||||
"apirequest.h.mustache", // the template to use
|
||||
".h"); // the extension for each file to write
|
||||
|
||||
apiTemplateFiles.put(
|
||||
"apirequest.cpp.mustache", // the template to use
|
||||
".cpp"); // the extension for each file to write
|
||||
|
||||
/*
|
||||
* Template Location. This is the location which templates will be read from. The generator
|
||||
* will use the resource stream to attempt to read the templates.
|
||||
*/
|
||||
embeddedTemplateDir = templateDir = "cpp-qt5-server";
|
||||
|
||||
// CLI options
|
||||
addOption(CPP_NAMESPACE, CPP_NAMESPACE_DESC, this.cppNamespace);
|
||||
|
||||
/*
|
||||
* Additional Properties. These values can be passed to the templates and
|
||||
* are available in models, apis, and supporting files
|
||||
*/
|
||||
additionalProperties.put("apiVersion", apiVersion);
|
||||
additionalProperties().put("prefix", PREFIX);
|
||||
|
||||
// Write defaults namespace in properties so that it can be accessible in templates.
|
||||
// At this point command line has not been parsed so if value is given
|
||||
// in command line it will superseed this content
|
||||
additionalProperties.put("cppNamespace", cppNamespace);
|
||||
|
||||
/*
|
||||
* Language Specific Primitives. These types will not trigger imports by
|
||||
* the client generator
|
||||
*/
|
||||
languageSpecificPrimitives = new HashSet<String>(
|
||||
Arrays.asList(
|
||||
"bool",
|
||||
"qint32",
|
||||
"qint64",
|
||||
"float",
|
||||
"double")
|
||||
);
|
||||
|
||||
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder + MODEL_DIR, PREFIX + "Helpers.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder + MODEL_DIR, PREFIX + "Helpers.cpp"));
|
||||
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder + MODEL_DIR, PREFIX + "Object.h"));
|
||||
supportingFiles.add(new SupportingFile("apirouter.h.mustache", sourceFolder + APIHANDLER_DIR, PREFIX + "ApiRouter.h"));
|
||||
supportingFiles.add(new SupportingFile("apirouter.cpp.mustache", sourceFolder + APIHANDLER_DIR, PREFIX + "ApiRouter.cpp"));
|
||||
|
||||
|
||||
supportingFiles.add(new SupportingFile("main.cpp.mustache", sourceFolder + SRC_DIR, "main.cpp"));
|
||||
supportingFiles.add(new SupportingFile("src-CMakeLists.txt.mustache", sourceFolder + SRC_DIR, "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("README.md.mustache", sourceFolder, "README.MD"));
|
||||
supportingFiles.add(new SupportingFile("Makefile.mustache", sourceFolder, "Makefile"));
|
||||
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("Dockerfile.mustache", sourceFolder, "Dockerfile"));
|
||||
supportingFiles.add(new SupportingFile("LICENSE.txt.mustache", sourceFolder, "LICENSE.txt"));
|
||||
|
||||
super.typeMapping = new HashMap<String, String>();
|
||||
|
||||
typeMapping.put("date", "QDate");
|
||||
typeMapping.put("DateTime", "QDateTime");
|
||||
typeMapping.put("string", "QString");
|
||||
typeMapping.put("integer", "qint32");
|
||||
typeMapping.put("long", "qint64");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("array", "QList");
|
||||
typeMapping.put("map", "QMap");
|
||||
typeMapping.put("object", PREFIX + "Object");
|
||||
// mapped as "file" type for OAS 3.0
|
||||
typeMapping.put("ByteArray", "QByteArray");
|
||||
// UUID support - possible enhancement : use QUuid instead of QString.
|
||||
// beware though that Serialisation/deserialisation of QUuid does not
|
||||
// come out of the box and will need to be sorted out (at least imply
|
||||
// modifications on multiple templates)
|
||||
typeMapping.put("UUID", "QString");
|
||||
typeMapping.put("file", "QIODevice");
|
||||
typeMapping.put("binary", "QIODevice");
|
||||
importMapping = new HashMap<String, String>();
|
||||
namespaces = new HashMap<String, String>();
|
||||
|
||||
foundationClasses.add("QString");
|
||||
|
||||
systemIncludes.add("QString");
|
||||
systemIncludes.add("QList");
|
||||
systemIncludes.add("QMap");
|
||||
systemIncludes.add("QDate");
|
||||
systemIncludes.add("QDateTime");
|
||||
systemIncludes.add("QByteArray");
|
||||
systemIncludes.add("QIODevice");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (additionalProperties.containsKey("cppNamespace")) {
|
||||
cppNamespace = (String) additionalProperties.get("cppNamespace");
|
||||
}
|
||||
|
||||
additionalProperties.put("cppNamespaceDeclarations", cppNamespace.split("\\::"));
|
||||
if (additionalProperties.containsKey("modelNamePrefix")) {
|
||||
supportingFiles.clear();
|
||||
supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Helpers.h"));
|
||||
supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Helpers.cpp"));
|
||||
supportingFiles.add(new SupportingFile("object.mustache", sourceFolder + MODEL_DIR, modelNamePrefix + "Object.h"));
|
||||
supportingFiles.add(new SupportingFile("apirouter.h.mustache", sourceFolder + APIHANDLER_DIR, modelNamePrefix + "ApiRouter.h"));
|
||||
supportingFiles.add(new SupportingFile("apirouter.cpp.mustache", sourceFolder + APIHANDLER_DIR, modelNamePrefix + "ApiRouter.cpp"));
|
||||
|
||||
supportingFiles.add(new SupportingFile("main.cpp.mustache", sourceFolder + SRC_DIR, "main.cpp"));
|
||||
supportingFiles.add(new SupportingFile("src-CMakeLists.txt.mustache", sourceFolder + SRC_DIR, "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("README.md.mustache", sourceFolder, "README.MD"));
|
||||
supportingFiles.add(new SupportingFile("Makefile.mustache", sourceFolder, "Makefile"));
|
||||
supportingFiles.add(new SupportingFile("CMakeLists.txt.mustache", sourceFolder, "CMakeLists.txt"));
|
||||
supportingFiles.add(new SupportingFile("Dockerfile.mustache", sourceFolder, "Dockerfile"));
|
||||
supportingFiles.add(new SupportingFile("LICENSE.txt.mustache", sourceFolder, "LICENSE.txt"));
|
||||
|
||||
typeMapping.put("object", modelNamePrefix + "Object");
|
||||
additionalProperties().put("prefix", modelNamePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the type of generator.
|
||||
*
|
||||
* @return the CodegenType for this generator
|
||||
* @see org.openapitools.codegen.CodegenType
|
||||
*/
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
return CodegenType.SERVER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a friendly name for the generator. This will be used by the generator
|
||||
* to select the library with the -g flag.
|
||||
*
|
||||
* @return the friendly name for the generator
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return "cpp-qt5-server";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns human-friendly help for the generator. Provide the consumer with help
|
||||
* tips, parameters here
|
||||
*
|
||||
* @return A string value for the help message
|
||||
*/
|
||||
@Override
|
||||
public String getHelp() {
|
||||
return "Generates a Qt5 C++ Server using the QHTTPEngine HTTP Library.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelImport(String name) {
|
||||
if( name.isEmpty() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (namespaces.containsKey(name)) {
|
||||
return "using " + namespaces.get(name) + ";";
|
||||
} else if (systemIncludes.contains(name)) {
|
||||
return "#include <" + name + ">";
|
||||
}
|
||||
|
||||
String folder = modelPackage().replace("::", File.separator);
|
||||
if (!folder.isEmpty())
|
||||
folder += File.separator;
|
||||
|
||||
return "#include \"" + folder + name + ".h\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
|
||||
* those terms here. This logic is only called if a variable matches the reserved words
|
||||
*
|
||||
* @return the escaped term
|
||||
*/
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
if (this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
return "_" + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write model files. You can use the modelPackage() as defined when the class is
|
||||
* instantiated
|
||||
*/
|
||||
@Override
|
||||
public String modelFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + MODEL_DIR + "/" + modelPackage().replace("::", File.separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Location to write api files. You can use the apiPackage() as defined when the class is
|
||||
* instantiated
|
||||
*/
|
||||
@Override
|
||||
public String apiFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + APIHANDLER_DIR + "/" + apiPackage().replace("::", File.separator);
|
||||
}
|
||||
|
||||
private String requestFileFolder() {
|
||||
return outputFolder + "/" + sourceFolder + APIREQUEST_DIR + "/" + apiPackage().replace("::", File.separator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelFilename(String name) {
|
||||
return modelNamePrefix + initialCaps(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apiFilename(String templateName, String tag) {
|
||||
String result = super.apiFilename(templateName, tag);
|
||||
|
||||
if (templateName.contains("apirequest")) {
|
||||
result = result.replace("ApiHandler", "ApiRequest");
|
||||
result = result.replace(apiFileFolder(), requestFileFolder());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiFilename(String name) {
|
||||
return modelNamePrefix + initialCaps(name) + "ApiHandler";
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - type declaration. This is a String which is used by the templates to instantiate your
|
||||
* types. There is typically special handling for different property types
|
||||
*
|
||||
* @return a string value used as the `dataType` field for model templates, `returnType` for api templates
|
||||
*/
|
||||
@Override
|
||||
public String getTypeDeclaration(Schema p) {
|
||||
String openAPIType = getSchemaType(p);
|
||||
|
||||
if (ModelUtils.isArraySchema(p)) {
|
||||
ArraySchema ap = (ArraySchema) p;
|
||||
Schema inner = ap.getItems();
|
||||
return getSchemaType(p) + "<" + getTypeDeclaration(inner) + ">";
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
Schema inner = (Schema) p.getAdditionalProperties();
|
||||
return getSchemaType(p) + "<QString, " + getTypeDeclaration(inner) + ">";
|
||||
} else if (ModelUtils.isBinarySchema(p)) {
|
||||
return getSchemaType(p) + "*";
|
||||
} else if (ModelUtils.isFileSchema(p)) {
|
||||
return getSchemaType(p) + "*";
|
||||
}
|
||||
if (foundationClasses.contains(openAPIType)) {
|
||||
return openAPIType;
|
||||
} else if (languageSpecificPrimitives.contains(openAPIType)) {
|
||||
return toModelName(openAPIType);
|
||||
} else {
|
||||
return openAPIType;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toDefaultValue(Schema p) {
|
||||
if (ModelUtils.isBooleanSchema(p)) {
|
||||
return "false";
|
||||
} else if (ModelUtils.isDateSchema(p)) {
|
||||
return "NULL";
|
||||
} else if (ModelUtils.isDateTimeSchema(p)) {
|
||||
return "NULL";
|
||||
} else if (ModelUtils.isNumberSchema(p)) {
|
||||
if (SchemaTypeUtil.FLOAT_FORMAT.equals(p.getFormat())) {
|
||||
return "0.0f";
|
||||
}
|
||||
return "0.0";
|
||||
} else if (ModelUtils.isIntegerSchema(p)) {
|
||||
if (SchemaTypeUtil.INTEGER64_FORMAT.equals(p.getFormat())) {
|
||||
return "0L";
|
||||
}
|
||||
return "0";
|
||||
} else if (ModelUtils.isMapSchema(p)) {
|
||||
Schema inner = (Schema) p.getAdditionalProperties();
|
||||
return "QMap<QString, " + getTypeDeclaration(inner) + ">()";
|
||||
} else if (ModelUtils.isArraySchema(p)) {
|
||||
ArraySchema ap = (ArraySchema) p;
|
||||
Schema inner = ap.getItems();
|
||||
return "QList<" + getTypeDeclaration(inner) + ">()";
|
||||
} else if (ModelUtils.isStringSchema(p)) {
|
||||
return "QString(\"\")";
|
||||
} else if (!StringUtils.isEmpty(p.get$ref())) {
|
||||
return toModelName(ModelUtils.getSimpleRef(p.get$ref())) + "()";
|
||||
}
|
||||
return "NULL";
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional - OpenAPI type conversion. This is used to map OpenAPI types in a `Schema` into
|
||||
* either language specific types via `typeMapping` or into complex models if there is not a mapping.
|
||||
*
|
||||
* @return a string value of the type or complex model for this property
|
||||
*/
|
||||
@Override
|
||||
public String getSchemaType(Schema p) {
|
||||
String openAPIType = super.getSchemaType(p);
|
||||
|
||||
String type = null;
|
||||
if (typeMapping.containsKey(openAPIType)) {
|
||||
type = typeMapping.get(openAPIType);
|
||||
if (languageSpecificPrimitives.contains(type)) {
|
||||
return toModelName(type);
|
||||
}
|
||||
if (foundationClasses.contains(type)) {
|
||||
return type;
|
||||
}
|
||||
} else {
|
||||
type = openAPIType;
|
||||
}
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toModelName(String type) {
|
||||
if (type == null) {
|
||||
LOGGER.warn("Model name can't be null. Defaul to 'UnknownModel'.");
|
||||
type = "UnknownModel";
|
||||
}
|
||||
|
||||
if (typeMapping.keySet().contains(type) ||
|
||||
typeMapping.values().contains(type) ||
|
||||
importMapping.values().contains(type) ||
|
||||
defaultIncludes.contains(type) ||
|
||||
languageSpecificPrimitives.contains(type)) {
|
||||
return type;
|
||||
} else {
|
||||
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toVarName(String name) {
|
||||
// sanitize name
|
||||
String varName = name;
|
||||
varName = sanitizeName(name);
|
||||
|
||||
// if it's all uppper case, convert to lower case
|
||||
if (varName.matches("^[A-Z_]*$")) {
|
||||
varName = varName.toLowerCase();
|
||||
}
|
||||
|
||||
// camelize (lower first character) the variable name
|
||||
// petId => pet_id
|
||||
varName = underscore(varName);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(varName) || varName.matches("^\\d.*")) {
|
||||
varName = escapeReservedWord(varName);
|
||||
}
|
||||
|
||||
return varName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toParamName(String name) {
|
||||
return toVarName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toApiName(String type) {
|
||||
return modelNamePrefix + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeQuotationMark(String input) {
|
||||
// remove " to avoid code injection
|
||||
return input.replace("\"", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String escapeUnsafeCharacters(String input) {
|
||||
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeDeclaration(String str) {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import org.openapitools.codegen.*;
|
||||
import io.swagger.models.properties.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
@@ -152,6 +151,8 @@ public class PhpLumenServerCodegen extends AbstractPhpCodegen {
|
||||
}
|
||||
});
|
||||
|
||||
escapeMediaType(operations);
|
||||
|
||||
return objs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,17 +124,7 @@ public class PhpSlimServerCodegen extends AbstractPhpCodegen {
|
||||
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation op : operationList) {
|
||||
if (op.hasProduces) {
|
||||
// need to escape */* values because they breakes current mustaches
|
||||
List<Map<String, String>> c = op.produces;
|
||||
for (Map<String, String> mediaType : c) {
|
||||
if ("*/*".equals(mediaType.get("mediaType"))) {
|
||||
mediaType.put("mediaType", "*_/_*");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
escapeMediaType(operationList);
|
||||
return objs;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
|
||||
package org.openapitools.codegen.languages;
|
||||
|
||||
import io.swagger.v3.core.util.Json;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.Operation;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConfig;
|
||||
@@ -175,6 +177,22 @@ public class StaticHtml2Generator extends DefaultCodegen implements CodegenConfi
|
||||
additionalProperties.put("jsModuleName", jsModuleName);
|
||||
|
||||
preparHtmlForGlobalDescription(openAPI);
|
||||
|
||||
Map<String, Object> vendorExtensions = openAPI.getExtensions();
|
||||
if (vendorExtensions != null) {
|
||||
for(Map.Entry<String, Object> vendorExtension: vendorExtensions.entrySet()) {
|
||||
// Vendor extensions could be Maps (objects). If we wanted to iterate through them in our template files
|
||||
// without knowing the keys beforehand, the default `toString` method renders them unusable. Instead, we
|
||||
// convert them to JSON strings now, which means we can easily use them later.
|
||||
if (vendorExtension.getValue() instanceof Map) {
|
||||
this.vendorExtensions().put(vendorExtension.getKey(), Json.mapper().convertValue(vendorExtension.getValue(), JsonNode.class));
|
||||
} else {
|
||||
this.vendorExtensions().put(vendorExtension.getKey(), vendorExtension.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
openAPI.setExtensions(this.vendorExtensions);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,7 +48,7 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
{{#gson}}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
{{#gson}}
|
||||
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + v + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@ public enum {{datatypeWithEnum}} {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + v + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
{{/jackson}}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@ public enum {{datatypeWithEnum}} {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + v + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ org.openapitools.codegen.languages.BashClientCodegen
|
||||
org.openapitools.codegen.languages.ClojureClientCodegen
|
||||
org.openapitools.codegen.languages.ConfluenceWikiCodegen
|
||||
org.openapitools.codegen.languages.CppQt5ClientCodegen
|
||||
org.openapitools.codegen.languages.CppQt5ServerCodegen
|
||||
org.openapitools.codegen.languages.CppPistacheServerCodegen
|
||||
org.openapitools.codegen.languages.CppRestbedServerCodegen
|
||||
org.openapitools.codegen.languages.CppRestSdkClientCodegen
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
|
||||
project(cpp-qt5-server)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/external)
|
||||
|
||||
ExternalProject_Add(QHTTPENGINE
|
||||
GIT_REPOSITORY https://github.com/etherealjoy/qhttpengine.git
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_LOCATION}
|
||||
)
|
||||
|
||||
include_directories(${EXTERNAL_INSTALL_LOCATION}/include)
|
||||
link_directories(${EXTERNAL_INSTALL_LOCATION}/lib)
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,29 @@
|
||||
FROM alpine:latest AS build
|
||||
|
||||
RUN apk add --update \
|
||||
cmake \
|
||||
alpine-sdk \
|
||||
openssl \
|
||||
qt5-qtbase-dev \
|
||||
qt5-qttools-dev
|
||||
|
||||
WORKDIR /usr/server
|
||||
ADD ./src ./src
|
||||
ADD ./CMakeLists.txt ./
|
||||
RUN mkdir -p ./build
|
||||
WORKDIR /usr/server/build
|
||||
RUN cmake -DNODEBUG:STRING="ON" ..
|
||||
RUN make
|
||||
|
||||
FROM alpine:latest AS runtime
|
||||
RUN apk add --update \
|
||||
libgcc \
|
||||
libstdc++ \
|
||||
qt5-qtbase \
|
||||
openssl
|
||||
|
||||
WORKDIR /usr/server
|
||||
COPY --from=build /usr/server/build/src/cpp-qt5-server ./build/src/
|
||||
COPY --from=build /usr/server/external/ ./external
|
||||
EXPOSE 8080/tcp
|
||||
ENTRYPOINT ["/usr/server/build/src/cpp-qt5-server"]
|
||||
@@ -0,0 +1,11 @@
|
||||
QHttpEngine
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Nathan Osman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,29 @@
|
||||
BUILD_DIR=build
|
||||
DIST_DIR=.
|
||||
ECHO=echo
|
||||
CMAKE=cmake
|
||||
RM=rm
|
||||
MKDIR_P = mkdir -p
|
||||
CD=cd
|
||||
|
||||
default: all
|
||||
|
||||
checkdir:
|
||||
ifeq "$(wildcard $(BUILD_DIR) )" ""
|
||||
@$(ECHO) "Build Directory not existing, creating..."
|
||||
@${MKDIR_P} ${BUILD_DIR}
|
||||
endif
|
||||
|
||||
cmakestep: checkdir
|
||||
$(CD) $(BUILD_DIR) && $(CMAKE) ../${DIST_DIR}
|
||||
|
||||
all: cmakestep
|
||||
$(MAKE) -j8 -C $(BUILD_DIR) all
|
||||
|
||||
install: all
|
||||
$(MAKE) -C $(BUILD_DIR) install
|
||||
|
||||
clean:
|
||||
$(RM) -rf $(BUILD_DIR)/*
|
||||
|
||||
.PHONY: clean install
|
||||
@@ -0,0 +1,93 @@
|
||||
## Qt5 HTTP Server based on the Qhttpengine
|
||||
This server was generated by the [openapi-generator]
|
||||
(https://openapi-generator.tech) project.
|
||||
By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate a server stub.
|
||||
-
|
||||
|
||||
To see how to make this your own, look here:
|
||||
|
||||
[README]((https://openapi-generator.tech))
|
||||
|
||||
- API version: {{appVersion}}{{^hideGenerationTimestamp}}
|
||||
- Build date: {{generatedDate}}{{/hideGenerationTimestamp}}
|
||||
{{#infoUrl}}
|
||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||
{{/infoUrl}}
|
||||
|
||||
## QHTTPEngine
|
||||
|
||||
[](https://travis-ci.org/nitroshare/qhttpengine)
|
||||
[](http://opensource.org/licenses/MIT)
|
||||
|
||||
Simple set of classes for developing HTTP server applications in Qt.
|
||||
|
||||
### Documentation
|
||||
|
||||
To learn more about building and using the library, please visit this page:
|
||||
|
||||
https://ci.quickmediasolutions.com/job/qhttpengine-documentation/doxygen/
|
||||
|
||||
|
||||
### Viewing the code
|
||||
You can view the code using an editor like Microsoft Visual Studio Code or you can
|
||||
Use QtCreator and browse for the root CMakeLists.txt and load it as a project
|
||||
|
||||
### Build with make
|
||||
Install the tools [Linux/Debian]
|
||||
```
|
||||
sudo apt install cmake build-essential libssl-dev qtbase5-dev qtbase5-dev-tools git curl
|
||||
```
|
||||
|
||||
To build, go to the `server` folder
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
To run the server
|
||||
```
|
||||
./build/src/cpp-qt5-server &
|
||||
```
|
||||
#### Invoke an API
|
||||
```
|
||||
curl -X GET http://localhost:8080/v2/store/inventory
|
||||
curl -X POST http://localhost:8080/v2/store/order -H "Content-Type: application/json" -d "{ \"id\": 22, \"petId\": 1541, \"quantity\": 5, \"shipDate\": \"2018-06-16T18:31:43.870Z\", \"status\": \"placed\", \"complete\": \"true\" }"
|
||||
curl -X GET http://localhost:8080/v2/pet/findByStatus
|
||||
curl -X GET http://localhost:8080/v2/store/inventory
|
||||
```
|
||||
|
||||
### Run and build with docker
|
||||
Building with docker multistage
|
||||
If you dont have docker install [here](https://docs.docker.com/install)
|
||||
Add yourself to the docker group
|
||||
|
||||
```
|
||||
docker build --network=host -t cpp-qt5-server .
|
||||
```
|
||||
Running with docker
|
||||
```
|
||||
docker run --rm -it --name=server-container cpp-qt5-server
|
||||
```
|
||||
|
||||
#### Invoking an API
|
||||
Mind the IP here
|
||||
```
|
||||
curl -X GET http://172.17.0.2:8080/v2/store/inventory
|
||||
curl -X POST http://172.17.0.2:8080/v2/store/order -H "Content-Type: application/json" -d "{ \"id\": 22, \"petId\": 1541, \"quantity\": 5, \"shipDate\": \"2018-06-16T18:31:43.870Z\", \"status\": \"placed\", \"complete\": \"true\" }"
|
||||
```
|
||||
|
||||
use this command to get the container IP
|
||||
```
|
||||
docker inspect server-container | grep "IPAddress"
|
||||
```
|
||||
To exit from the command line
|
||||
```
|
||||
Ctrl + p + q
|
||||
```
|
||||
To stop container
|
||||
```
|
||||
docker stop <containername>
|
||||
```
|
||||
or to terminate and quit
|
||||
```
|
||||
Ctrl+C
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
{{>licenseInfo}}
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
#include <QDebug>
|
||||
|
||||
#include "{{classname}}Handler.h"
|
||||
#include "{{classname}}Request.h"
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
{{classname}}Handler::{{classname}}Handler(){
|
||||
|
||||
}
|
||||
|
||||
{{classname}}Handler::~{{classname}}Handler(){
|
||||
|
||||
}
|
||||
|
||||
{{#operations}}{{#operation}}void {{classname}}Handler::{{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
|
||||
{{#allParams}}
|
||||
Q_UNUSED({{paramName}});
|
||||
{{/allParams}}
|
||||
auto reqObj = qobject_cast<{{classname}}Request*>(sender());
|
||||
if( reqObj != nullptr )
|
||||
{
|
||||
{{#returnType}}{{{returnType}}} res;{{/returnType}}
|
||||
reqObj->{{nickname}}Response({{#returnType}}res{{/returnType}});
|
||||
}
|
||||
}
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
@@ -0,0 +1,33 @@
|
||||
{{>licenseInfo}}
|
||||
#ifndef _{{prefix}}_{{classname}}Handler_H_
|
||||
#define _{{prefix}}_{{classname}}Handler_H_
|
||||
|
||||
#include <QObject>
|
||||
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
class {{classname}}Handler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
{{classname}}Handler();
|
||||
virtual ~{{classname}}Handler();
|
||||
|
||||
|
||||
public slots:
|
||||
{{#operations}}{{#operation}}virtual void {{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif // _{{prefix}}_{{classname}}Handler_H_
|
||||
@@ -0,0 +1,124 @@
|
||||
{{>licenseInfo}}
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
#include <QDebug>
|
||||
|
||||
#include "{{prefix}}Helpers.h"
|
||||
#include "{{classname}}Request.h"
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
{{classname}}Request::{{classname}}Request(QHttpEngine::Socket *s, {{classname}}Handler* hdl) : QObject(s), socket(s), handler(hdl) {
|
||||
}
|
||||
|
||||
{{classname}}Request::~{{classname}}Request(){
|
||||
disconnect(this, nullptr, nullptr, nullptr);
|
||||
qDebug() << "{{classname}}Request::~{{classname}}Request()";
|
||||
}
|
||||
|
||||
QMap<QString, QString>
|
||||
{{classname}}Request::getDefaultHeaders(){
|
||||
return defaultHeaders;
|
||||
}
|
||||
|
||||
QHttpEngine::Socket* {{classname}}Request::getRawSocket(){
|
||||
return socket;
|
||||
}
|
||||
|
||||
{{#operations}}{{#operation}}
|
||||
void {{classname}}Request::{{nickname}}Request({{#hasPathParams}}{{#pathParams}}QString {{{paramName}}}str{{/pathParams}}{{/hasPathParams}}){
|
||||
qDebug() << "{{{basePathWithoutHost}}}{{{path}}}";
|
||||
connect(this, &{{classname}}Request::{{nickname}}, handler, &{{classname}}Handler::{{nickname}});
|
||||
|
||||
{{#queryParams}}{{queryParam}}
|
||||
{{{dataType}}} {{paramName}};
|
||||
if(socket->queryString().keys().contains("{{paramName}}")){
|
||||
fromStringValue(socket->queryString().value{{#isListContainer}}s{{/isListContainer}}("{{paramName}}"), {{paramName}});
|
||||
}
|
||||
{{queryParam}}{{/queryParams}}
|
||||
{{#pathParams}}
|
||||
{{{dataType}}} {{paramName}};
|
||||
fromStringValue({{paramName}}str, {{paramName}});
|
||||
{{/pathParams}}{{#headerParams}}
|
||||
{{{dataType}}} {{paramName}};
|
||||
if(socket->headers().keys().contains("{{paramName}}")){
|
||||
fromStringValue(socket->queryString().value("{{paramName}}"), {{paramName}});
|
||||
}
|
||||
{{/headerParams}}{{#formParams}}
|
||||
{{{dataType}}} {{paramName}};{{/formParams}}{{#bodyParams}} {{#bodyParam}}
|
||||
{{#isListContainer}}
|
||||
QJsonDocument doc;
|
||||
{{{dataType}}} {{paramName}};
|
||||
if(socket->readJson(doc)){
|
||||
QJsonArray jsonArray = doc.array();
|
||||
foreach(QJsonValue obj, jsonArray) {
|
||||
{{items.baseType}} o;
|
||||
::{{cppNamespace}}::fromJsonValue(o, obj);
|
||||
{{paramName}}.append(o);
|
||||
}
|
||||
}
|
||||
{{/isListContainer}}
|
||||
{{^isListContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{#isPrimitive}}
|
||||
{{{dataType}}} {{paramName}};
|
||||
::{{cppNamespace}}::fromStringValue((QString(socket->readAll()), {{paramName}});
|
||||
{{/isPrimitive}}
|
||||
{{/isMapContainer}}
|
||||
{{#isMapContainer}}
|
||||
QJsonDocument doc;
|
||||
socket->readJson(doc);
|
||||
QJsonObject obj = doc.object();
|
||||
{{{dataType}}} {{paramName}};
|
||||
foreach(QString key, obj.keys()) {
|
||||
{{baseType}} val;
|
||||
::{{cppNamespace}}::fromJsonValue(val, obj[key]);
|
||||
{{paramName}}.insert(key, val);
|
||||
}
|
||||
{{/isMapContainer}}
|
||||
{{^isMapContainer}}
|
||||
{{^isPrimitive}}
|
||||
QJsonDocument doc;
|
||||
socket->readJson(doc);
|
||||
QJsonObject obj = doc.object();
|
||||
{{{dataType}}} {{paramName}};
|
||||
::{{cppNamespace}}::fromJsonValue({{paramName}}, obj);
|
||||
{{/isPrimitive}}
|
||||
{{/isMapContainer}}
|
||||
{{/isListContainer}}
|
||||
{{/bodyParam}}{{/bodyParams}}
|
||||
|
||||
emit {{nickname}}({{#allParams}}{{#isBodyParam}}{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
}
|
||||
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Response({{#returnType}}{{{returnType}}} res{{/returnType}}){
|
||||
socket->setStatusCode(QHttpEngine::Socket::OK);
|
||||
if(socket->isOpen()){
|
||||
socket->writeHeaders();
|
||||
socket->close();
|
||||
}
|
||||
}
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#operations}}{{#operation}}void {{classname}}Request::{{nickname}}Error({{#returnType}}{{{returnType}}} res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str){
|
||||
Q_UNUSED(error_type);
|
||||
Q_UNUSED(error_str);
|
||||
socket->setStatusCode(QHttpEngine::Socket::NotFound);
|
||||
if(socket->isOpen()){
|
||||
socket->writeHeaders();
|
||||
socket->close();
|
||||
}
|
||||
}
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
@@ -0,0 +1,53 @@
|
||||
{{>licenseInfo}}
|
||||
#ifndef _{{prefix}}_{{classname}}Request_H_
|
||||
#define _{{prefix}}_{{classname}}Request_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QNetworkReply>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <qhttpengine/socket.h>
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
#include "{{classname}}Handler.h"
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
class {{classname}}Request : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
{{classname}}Request(QHttpEngine::Socket *s, {{classname}}Handler* handler);
|
||||
virtual ~{{classname}}Request();
|
||||
|
||||
{{#operations}}{{#operation}}void {{nickname}}Request({{#hasPathParams}}{{#pathParams}}QString {{{paramName}}}{{/pathParams}}{{/hasPathParams}});
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#operations}}{{#operation}}void {{nickname}}Response({{#returnType}}{{{returnType}}} res{{/returnType}});
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
{{#operations}}{{#operation}}void {{nickname}}Error({{#returnType}}{{{returnType}}} res, {{/returnType}}QNetworkReply::NetworkError error_type, QString& error_str);
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
QMap<QString, QString> getDefaultHeaders();
|
||||
QHttpEngine::Socket* getRawSocket();
|
||||
|
||||
signals:
|
||||
{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
|
||||
{{/operation}}{{/operations}}
|
||||
|
||||
private:
|
||||
QMap<QString, QString> defaultHeaders;
|
||||
QHttpEngine::Socket *socket;
|
||||
{{classname}}Handler *handler;
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif // _{{prefix}}_{{classname}}Request_H_
|
||||
@@ -0,0 +1,94 @@
|
||||
{{>licenseInfo}}
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QVariantMap>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include "{{prefix}}ApiRouter.h"
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}#include "{{classname}}Request.h"
|
||||
{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
inline QHttpEngine::Socket::Method toQHttpEngineMethod(QString method){
|
||||
|
||||
if( method == QString("OPTIONS"))
|
||||
return QHttpEngine::Socket::Method::OPTIONS;
|
||||
if( method == QString("GET"))
|
||||
return QHttpEngine::Socket::Method::GET;
|
||||
if( method == QString("HEAD"))
|
||||
return QHttpEngine::Socket::Method::HEAD;
|
||||
if( method == QString("POST"))
|
||||
return QHttpEngine::Socket::Method::POST;
|
||||
if( method == QString("PUT"))
|
||||
return QHttpEngine::Socket::Method::PUT;
|
||||
if( method == QString("DELETE"))
|
||||
return QHttpEngine::Socket::Method::DELETE;
|
||||
if( method == QString("TRACE"))
|
||||
return QHttpEngine::Socket::Method::TRACE;
|
||||
if( method == QString("CONNECT"))
|
||||
return QHttpEngine::Socket::Method::CONNECT;
|
||||
|
||||
return static_cast<QHttpEngine::Socket::Method>(-1);
|
||||
}
|
||||
|
||||
ApiRouter::ApiRouter() {
|
||||
{{#apiInfo}}{{#apis}}{{classname}}ApiHandler = new {{classname}}Handler();
|
||||
{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
ApiRouter::~ApiRouter(){
|
||||
qDebug() << "~ApiRouter()";
|
||||
{{#apiInfo}}{{#apis}}delete {{classname}}ApiHandler;
|
||||
{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
void ApiRouter::setUpRoutes() {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{^pathParams}}
|
||||
Routes.insert("{{{basePathWithoutHost}}}{{{path}}}",[this](QHttpEngine::Socket *socket) {
|
||||
if(toQHttpEngineMethod("{{httpMethod}}") == socket->method()){
|
||||
auto reqObj = new {{classname}}Request(socket, {{classname}}ApiHandler);
|
||||
reqObj->{{nickname}}Request();
|
||||
}
|
||||
});{{/pathParams}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
void ApiRouter::processRequest(QHttpEngine::Socket *socket){
|
||||
if (Routes.contains(socket->path())) {
|
||||
auto itr = Routes.find(socket->path());
|
||||
while (itr != Routes.end() && itr.key() == socket->path()) {
|
||||
itr.value().operator()(socket);
|
||||
++itr;
|
||||
}
|
||||
} else
|
||||
{ {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#pathParams}}
|
||||
{
|
||||
QString completePath("{{{basePathWithoutHost}}}{{{path}}}");
|
||||
QString {{paramName}}PathParam("{");
|
||||
{{paramName}}PathParam.append("{{baseName}}").append("}");
|
||||
completePath.replace("/", "\\/"); // replace '/' with '\/' for regex
|
||||
completePath.replace({{paramName}}PathParam, "([^\\/]*?)"); // match anything but '/''
|
||||
completePath.append("$"); // End of string
|
||||
QRegularExpression re(completePath, QRegularExpression::CaseInsensitiveOption);
|
||||
QRegularExpressionMatch match = re.match(socket->path());
|
||||
if ((toQHttpEngineMethod("{{httpMethod}}") == socket->method()) && match.hasMatch() ) {
|
||||
QString pathparam = match.captured(1);
|
||||
auto reqObj = new {{classname}}Request(socket, {{classname}}ApiHandler);
|
||||
reqObj->{{nickname}}Request({{#hasPathParams}}{{#pathParams}}pathparam{{/pathParams}}{{/hasPathParams}});;
|
||||
return;
|
||||
}
|
||||
}{{/pathParams}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
socket->setStatusCode(QHttpEngine::Socket::NotFound);
|
||||
if(socket->isOpen()){
|
||||
socket->writeHeaders();
|
||||
socket->close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
@@ -0,0 +1,55 @@
|
||||
{{>licenseInfo}}
|
||||
#ifndef {{prefix}}_APIROUTER_H
|
||||
#define {{prefix}}_APIROUTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QSharedPointer>
|
||||
#include <QList>
|
||||
#include <QMultiMap>
|
||||
|
||||
#include <qhttpengine/socket.h>
|
||||
#include <qhttpengine/handler.h>
|
||||
#include <qhttpengine/qobjecthandler.h>
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}#include "{{classname}}Handler.h"
|
||||
{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
class RequestHandler : public QHttpEngine::QObjectHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void requestReceived(QHttpEngine::Socket *socket);
|
||||
|
||||
protected:
|
||||
virtual void process(QHttpEngine::Socket *socket, const QString &path){
|
||||
Q_UNUSED(path);
|
||||
emit requestReceived(socket);
|
||||
}
|
||||
};
|
||||
|
||||
class ApiRouter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ApiRouter();
|
||||
virtual ~ApiRouter();
|
||||
|
||||
void setUpRoutes();
|
||||
void processRequest(QHttpEngine::Socket *socket);
|
||||
private:
|
||||
QMultiMap<QString, std::function<void(QHttpEngine::Socket *)>> Routes;
|
||||
{{#apiInfo}}{{#apis}}
|
||||
{{classname}}Handler *{{classname}}ApiHandler;{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif // {{prefix}}_APIROUTER_H
|
||||
@@ -0,0 +1,282 @@
|
||||
{{>licenseInfo}}
|
||||
#include <QDebug>
|
||||
#include "{{prefix}}Helpers.h"
|
||||
#include "{{prefix}}Object.h"
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
|
||||
QString
|
||||
toStringValue(const QString &value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const QDateTime &value){
|
||||
// ISO 8601
|
||||
return value.toString("yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm]");
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const QByteArray &value){
|
||||
return QString(value);
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const QDate &value){
|
||||
// ISO 8601
|
||||
return value.toString(Qt::DateFormat::ISODate);
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const qint32 &value) {
|
||||
return QString::number(value);
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const qint64 &value) {
|
||||
return QString::number(value);
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const bool &value) {
|
||||
return QString(value ? "true" : "false");
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const float &value){
|
||||
return QString::number(value);
|
||||
}
|
||||
|
||||
QString
|
||||
toStringValue(const double &value){
|
||||
return QString::number(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const QString &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const QDateTime &value){
|
||||
return QJsonValue(value.toString(Qt::ISODate));
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const QByteArray &value){
|
||||
return QJsonValue(QString(value.toBase64()));
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const QDate &value){
|
||||
return QJsonValue(value.toString(Qt::ISODate));
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const qint32 &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const qint64 &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const bool &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const float &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const double &value){
|
||||
return QJsonValue(value);
|
||||
}
|
||||
|
||||
QJsonValue
|
||||
toJsonValue(const {{prefix}}Object &value){
|
||||
return value.asJsonObject();
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, QString &value){
|
||||
value.clear();
|
||||
value.append(inStr);
|
||||
return !inStr.isEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, QDateTime &value){
|
||||
if(inStr.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
auto dateTime = QDateTime::fromString(inStr, "yyyy-MM-ddTHH:mm:ss[Z|[+|-]HH:mm]");
|
||||
if(dateTime.isValid()){
|
||||
value.setDate(dateTime.date());
|
||||
value.setTime(dateTime.time());
|
||||
}
|
||||
else{
|
||||
qDebug() << "DateTime is invalid";
|
||||
}
|
||||
return dateTime.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, QByteArray &value){
|
||||
if(inStr.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
value.clear();
|
||||
value.append(inStr.toUtf8());
|
||||
return value.count() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, QDate &value){
|
||||
if(inStr.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
auto date = QDate::fromString(inStr, Qt::DateFormat::ISODate);
|
||||
if(date.isValid()){
|
||||
value.setDate(date.year(), date.month(), date.day());
|
||||
}
|
||||
else{
|
||||
qDebug() << "Date is invalid";
|
||||
}
|
||||
return date.isValid();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, qint32 &value){
|
||||
bool ok = false;
|
||||
value = QVariant(inStr).toInt(&ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, qint64 &value){
|
||||
bool ok = false;
|
||||
value = QVariant(inStr).toLongLong(&ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, bool &value){
|
||||
value = QVariant(inStr).toBool();
|
||||
return ((inStr == "true") || (inStr == "false"));
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, float &value){
|
||||
bool ok = false;
|
||||
value = QVariant(inStr).toFloat(&ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
fromStringValue(const QString &inStr, double &value){
|
||||
bool ok = false;
|
||||
value = QVariant(inStr).toDouble(&ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(QString &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
if(jval.isString()){
|
||||
value = jval.toString();
|
||||
} else if(jval.isBool()) {
|
||||
value = jval.toBool() ? "true" : "false";
|
||||
} else if(jval.isDouble()){
|
||||
value = QString::number(jval.toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(QDateTime &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = QDateTime::fromString(jval.toString(), Qt::ISODate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(QByteArray &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = QByteArray::fromBase64(QByteArray::fromStdString(jval.toString().toStdString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(QDate &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = QDate::fromString(jval.toString(), Qt::ISODate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(qint32 &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = jval.toInt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(qint64 &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = jval.toVariant().toLongLong();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(bool &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = jval.toBool();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(float &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = static_cast<float>(jval.toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue(double &value, const QJsonValue &jval){
|
||||
if(!(jval.isUndefined() || jval.isNull())){
|
||||
value = jval.toDouble();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
fromJsonValue({{prefix}}Object &value, const QJsonValue &jval){
|
||||
if(jval.isObject()){
|
||||
value.fromJsonObject(jval.toObject());
|
||||
}
|
||||
}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
@@ -0,0 +1,144 @@
|
||||
{{>licenseInfo}}
|
||||
#ifndef {{prefix}}_HELPERS_H
|
||||
#define {{prefix}}_HELPERS_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QJsonArray>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QDateTime>
|
||||
#include <QByteArray>
|
||||
#include <QDate>
|
||||
#include <QVariant>
|
||||
#include "{{prefix}}Object.h"
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
QString toStringValue(const QString &value);
|
||||
QString toStringValue(const QDateTime &value);
|
||||
QString toStringValue(const QByteArray &value);
|
||||
QString toStringValue(const QDate &value);
|
||||
QString toStringValue(const qint32 &value);
|
||||
QString toStringValue(const qint64 &value);
|
||||
QString toStringValue(const bool &value);
|
||||
QString toStringValue(const float &value);
|
||||
QString toStringValue(const double &value);
|
||||
|
||||
template <typename T>
|
||||
QList<QString> toStringValue(const QList<T> &val) {
|
||||
QList<QString> strArray;
|
||||
for(auto item : val) {
|
||||
strArray.append(toStringValue(item));
|
||||
}
|
||||
return strArray;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QMap<QString, QString> toStringValue(const QMap<QString, T> &val) {
|
||||
QMap<QString, QString> strMap;
|
||||
for(auto itemkey : val.keys()) {
|
||||
strMap.insert(itemkey, toStringValue(val.value(itemkey)));
|
||||
}
|
||||
return strMap;
|
||||
}
|
||||
|
||||
QJsonValue toJsonValue(const QString &value);
|
||||
QJsonValue toJsonValue(const QDateTime &value);
|
||||
QJsonValue toJsonValue(const QByteArray &value);
|
||||
QJsonValue toJsonValue(const QDate &value);
|
||||
QJsonValue toJsonValue(const qint32 &value);
|
||||
QJsonValue toJsonValue(const qint64 &value);
|
||||
QJsonValue toJsonValue(const bool &value);
|
||||
QJsonValue toJsonValue(const float &value);
|
||||
QJsonValue toJsonValue(const double &value);
|
||||
QJsonValue toJsonValue(const {{prefix}}Object &value);
|
||||
|
||||
template <typename T>
|
||||
QJsonValue toJsonValue(const QList<T> &val) {
|
||||
QJsonArray jArray;
|
||||
for(auto item : val) {
|
||||
jArray.append(toJsonValue(item));
|
||||
}
|
||||
return jArray;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
QJsonValue toJsonValue(const QMap<QString, T> &val) {
|
||||
QJsonObject jObject;
|
||||
for(auto itemkey : val.keys()) {
|
||||
jObject.insert(itemkey, toJsonValue(val.value(itemkey)));
|
||||
}
|
||||
return jObject;
|
||||
}
|
||||
|
||||
bool fromStringValue(const QString &inStr, QString &value);
|
||||
bool fromStringValue(const QString &inStr, QDateTime &value);
|
||||
bool fromStringValue(const QString &inStr, QByteArray &value);
|
||||
bool fromStringValue(const QString &inStr, QDate &value);
|
||||
bool fromStringValue(const QString &inStr, qint32 &value);
|
||||
bool fromStringValue(const QString &inStr, qint64 &value);
|
||||
bool fromStringValue(const QString &inStr, bool &value);
|
||||
bool fromStringValue(const QString &inStr, float &value);
|
||||
bool fromStringValue(const QString &inStr, double &value);
|
||||
|
||||
template <typename T>
|
||||
void fromStringValue(const QList<QString> &inStr, QList<T> &val) {
|
||||
for(auto item: inStr){
|
||||
T itemVal;
|
||||
fromStringValue(item, itemVal);
|
||||
val.push_back(itemVal);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fromStringValue(const QMap<QString, QString> &inStr, QMap<QString, T> &val) {
|
||||
for(auto itemkey : inStr.keys()){
|
||||
T itemVal;
|
||||
fromStringValue(inStr.value(itemkey), itemVal);
|
||||
val.insert(itemkey, itemVal);
|
||||
}
|
||||
}
|
||||
|
||||
void fromJsonValue(QString &value, const QJsonValue &jval);
|
||||
void fromJsonValue(QDateTime &value, const QJsonValue &jval);
|
||||
void fromJsonValue(QByteArray &value, const QJsonValue &jval);
|
||||
void fromJsonValue(QDate &value, const QJsonValue &jval);
|
||||
void fromJsonValue(qint32 &value, const QJsonValue &jval);
|
||||
void fromJsonValue(qint64 &value, const QJsonValue &jval);
|
||||
void fromJsonValue(bool &value, const QJsonValue &jval);
|
||||
void fromJsonValue(float &value, const QJsonValue &jval);
|
||||
void fromJsonValue(double &value, const QJsonValue &jval);
|
||||
void fromJsonValue({{prefix}}Object &value, const QJsonValue &jval);
|
||||
|
||||
template <typename T>
|
||||
void fromJsonValue(QList<T> &val, const QJsonValue &jval) {
|
||||
if(jval.isArray()){
|
||||
for(const QJsonValue &jitem : jval.toArray()){
|
||||
T item;
|
||||
fromJsonValue(item, jitem);
|
||||
val.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fromJsonValue(QMap<QString, T> &val, const QJsonValue &jval) {
|
||||
auto varmap = jval.toObject().toVariantMap();
|
||||
if(varmap.count() > 0){
|
||||
for(auto itemkey : varmap.keys() ){
|
||||
T itemVal;
|
||||
fromJsonValue(itemVal, QJsonValue::fromVariant(varmap.value(itemkey)));
|
||||
val.insert(itemkey, val);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif // {{prefix}}_HELPERS_H
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* {{{appName}}}
|
||||
* {{{appDescription}}}
|
||||
*
|
||||
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
|
||||
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
|
||||
*
|
||||
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||
* https://openapi-generator.tech
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
@@ -0,0 +1,88 @@
|
||||
{{>licenseInfo}}
|
||||
|
||||
#include <QCommandLineOption>
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QHostAddress>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
#include <QSharedPointer>
|
||||
#include <QObject>
|
||||
#ifdef __linux__
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <qhttpengine/server.h>
|
||||
#include "{{prefix}}ApiRouter.h"
|
||||
|
||||
#ifdef __linux__
|
||||
void catchUnixSignals(QList<int> quitSignals) {
|
||||
auto handler = [](int sig) -> void {
|
||||
// blocking and not aysnc-signal-safe func are valid
|
||||
qDebug() << "\nquit the application by signal " << sig;
|
||||
QCoreApplication::quit();
|
||||
};
|
||||
|
||||
sigset_t blocking_mask;
|
||||
sigemptyset(&blocking_mask);
|
||||
for (auto sig : quitSignals)
|
||||
sigaddset(&blocking_mask, sig);
|
||||
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = handler;
|
||||
sa.sa_mask = blocking_mask;
|
||||
sa.sa_flags = 0;
|
||||
|
||||
for (auto sig : quitSignals)
|
||||
sigaction(sig, &sa, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
#ifdef __linux__
|
||||
QList<int> sigs({SIGQUIT, SIGINT, SIGTERM, SIGHUP});
|
||||
catchUnixSignals(sigs);
|
||||
#endif
|
||||
// Build the command-line options
|
||||
QCommandLineParser parser;
|
||||
QCommandLineOption addressOption(
|
||||
QStringList() << "a" << "address",
|
||||
"address to bind to",
|
||||
"address",
|
||||
"0.0.0.0"
|
||||
);
|
||||
parser.addOption(addressOption);
|
||||
QCommandLineOption portOption(
|
||||
QStringList() << "p" << "port",
|
||||
"port to listen on",
|
||||
"port",
|
||||
"8080"
|
||||
);
|
||||
parser.addOption(portOption);
|
||||
parser.addHelpOption();
|
||||
|
||||
// Parse the options that were provided
|
||||
parser.process(a);
|
||||
|
||||
// Obtain the values
|
||||
QHostAddress address = QHostAddress(parser.value(addressOption));
|
||||
quint16 port = static_cast<quint16>(parser.value(portOption).toInt());
|
||||
|
||||
QSharedPointer<{{cppNamespace}}::RequestHandler> handler(new {{cppNamespace}}::RequestHandler());
|
||||
{{cppNamespace}}::ApiRouter router;
|
||||
QObject::connect(handler.data(), &{{cppNamespace}}::RequestHandler::requestReceived, [&](QHttpEngine::Socket *socket) {
|
||||
router.processRequest(socket);
|
||||
});
|
||||
|
||||
QHttpEngine::Server server(handler.data());
|
||||
qDebug() << "Serving on " << address.toString() << ":" << port;
|
||||
// Attempt to listen on the specified port
|
||||
if (!server.listen(address, port)) {
|
||||
qCritical("Unable to listen on the specified port.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{{>licenseInfo}}
|
||||
{{#models}}{{#model}}
|
||||
#include "{{classname}}.h"
|
||||
|
||||
#include "{{prefix}}Helpers.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
{{classname}}::{{classname}}(QString json) {
|
||||
this->fromJson(json);
|
||||
}
|
||||
|
||||
{{classname}}::{{classname}}() {
|
||||
this->init();
|
||||
}
|
||||
|
||||
{{classname}}::~{{classname}}() {
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
{{classname}}::init() {
|
||||
{{#vars}}
|
||||
m_{{name}}_isSet = false;
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
void
|
||||
{{classname}}::fromJson(QString jsonString) {
|
||||
QByteArray array (jsonString.toStdString().c_str());
|
||||
QJsonDocument doc = QJsonDocument::fromJson(array);
|
||||
QJsonObject jsonObject = doc.object();
|
||||
this->fromJsonObject(jsonObject);
|
||||
}
|
||||
|
||||
void
|
||||
{{classname}}::fromJsonObject(QJsonObject json) {
|
||||
{{#vars}}
|
||||
{{^isContainer}}::{{cppNamespace}}::fromJsonValue({{name}}, json[QString("{{baseName}}")]);{{/isContainer}}
|
||||
{{#isContainer}}{{^items.isContainer}}::{{cppNamespace}}::fromJsonValue({{name}}, json[QString("{{baseName}}")]);{{/items.isContainer}}{{#items.isContainer}}{{#isListContainer}}
|
||||
if(json["{{baseName}}"].isArray()){
|
||||
auto arr = json["{{baseName}}"].toArray();
|
||||
for (const QJsonValue & jval : arr) {
|
||||
{{items.baseType}} item;
|
||||
{{name}}.push_back(::{{cppNamespace}}::fromJsonValue(item, jval));
|
||||
}
|
||||
}{{/isListContainer}}{{#isMapContainer}}
|
||||
if(json["{{baseName}}"].isObject()){
|
||||
auto varmap = json["{{baseName}}"].toObject().toVariantMap();
|
||||
if(varmap.count() > 0){
|
||||
for(auto val : varmap.keys()){
|
||||
{{items.baseType}} item;
|
||||
auto jval = QJsonValue::fromVariant(varmap.value(val));
|
||||
{{name}}.insert({{name}}.end(), val, ::{{cppNamespace}}::fromJsonValue(item, jval));
|
||||
}
|
||||
}
|
||||
}{{/isMapContainer}}{{/items.isContainer}}{{/isContainer}}
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
QString
|
||||
{{classname}}::asJson () const {
|
||||
QJsonObject obj = this->asJsonObject();
|
||||
QJsonDocument doc(obj);
|
||||
QByteArray bytes = doc.toJson();
|
||||
return QString(bytes);
|
||||
}
|
||||
|
||||
QJsonObject
|
||||
{{classname}}::asJsonObject() const {
|
||||
QJsonObject obj;
|
||||
{{#vars}}
|
||||
{{^isContainer}}{{#complexType}}{{^isString}}{{^isDateTime}}{{^isByteArray}}{{^isDate}}if({{name}}.isSet()){{/isDate}}{{/isByteArray}}{{/isDateTime}}{{/isString}}{{/complexType}}{{^complexType}}if(m_{{name}}_isSet){{/complexType}}{{#isString}}if(m_{{name}}_isSet){{/isString}}{{#isDateTime}}if(m_{{name}}_isSet){{/isDateTime}}{{#isByteArray}}if(m_{{name}}_isSet){{/isByteArray}}{{#isDate}}if(m_{{name}}_isSet){{/isDate}}{
|
||||
obj.insert(QString("{{baseName}}"), ::{{cppNamespace}}::toJsonValue({{name}}));
|
||||
}{{/isContainer}}{{#isContainer}}
|
||||
if({{name}}.size() > 0){
|
||||
{{^items.isContainer}}obj.insert(QString("{{baseName}}"), ::{{cppNamespace}}::toJsonValue({{name}}));{{/items.isContainer}}{{#items.isContainer}}
|
||||
obj.insert(QString("{{baseName}}"), toJsonValue({{name}}));{{/items.isContainer}}
|
||||
} {{/isContainer}}
|
||||
{{/vars}}
|
||||
return obj;
|
||||
}
|
||||
|
||||
{{#vars}}
|
||||
{{{dataType}}}
|
||||
{{classname}}::{{getter}}() {
|
||||
return {{name}};
|
||||
}
|
||||
void
|
||||
{{classname}}::{{setter}}(const {{{dataType}}} &{{name}}) {
|
||||
this->{{name}} = {{name}};
|
||||
this->m_{{name}}_isSet = true;
|
||||
}
|
||||
|
||||
{{/vars}}
|
||||
|
||||
bool
|
||||
{{classname}}::isSet() const {
|
||||
bool isObjectUpdated = false;
|
||||
do{ {{#vars}}
|
||||
{{#isContainer}}if({{name}}.size() > 0){{/isContainer}}{{^isContainer}}{{#complexType}}{{^isString}}{{^isDateTime}}{{^isByteArray}}{{^isDate}}if({{name}}.isSet()){{/isDate}}{{/isByteArray}}{{/isDateTime}}{{/isString}}{{/complexType}}{{^complexType}}if(m_{{name}}_isSet){{/complexType}}{{#isString}}if(m_{{name}}_isSet){{/isString}}{{#isDateTime}}if(m_{{name}}_isSet){{/isDateTime}}{{#isByteArray}}if(m_{{name}}_isSet){{/isByteArray}}{{#isDate}}if(m_{{name}}_isSet){{/isDate}}{{/isContainer}}{ isObjectUpdated = true; break;}
|
||||
{{/vars}}}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1,58 @@
|
||||
{{>licenseInfo}}
|
||||
{{#models}}{{#model}}/*
|
||||
* {{classname}}.h
|
||||
*
|
||||
* {{description}}
|
||||
*/
|
||||
|
||||
#ifndef {{classname}}_H_
|
||||
#define {{classname}}_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
|
||||
{{/model}}{{/models}}
|
||||
{{#imports}}{{{import}}}
|
||||
{{/imports}}
|
||||
|
||||
#include "{{prefix}}Object.h"
|
||||
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
class {{classname}}: public {{prefix}}Object {
|
||||
public:
|
||||
{{classname}}();
|
||||
{{classname}}(QString json);
|
||||
~{{classname}}() override;
|
||||
void init();
|
||||
|
||||
QString asJson () const override;
|
||||
QJsonObject asJsonObject() const override;
|
||||
void fromJsonObject(QJsonObject json) override;
|
||||
void fromJson(QString jsonString) override;
|
||||
|
||||
{{#vars}}
|
||||
{{{dataType}}} {{getter}}();
|
||||
void {{setter}}(const {{{dataType}}} &{{name}});
|
||||
|
||||
{{/vars}}
|
||||
virtual bool isSet() const override;
|
||||
|
||||
private:
|
||||
{{#vars}}
|
||||
{{{dataType}}} {{name}};
|
||||
bool m_{{name}}_isSet;
|
||||
|
||||
{{/vars}}
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif /* {{classname}}_H_ */
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
@@ -0,0 +1,47 @@
|
||||
{{>licenseInfo}}
|
||||
#ifndef _{{prefix}}_OBJECT_H_
|
||||
#define _{{prefix}}_OBJECT_H_
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
namespace {{this}} {
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
class {{prefix}}Object {
|
||||
public:
|
||||
virtual ~{{prefix}}Object(){
|
||||
|
||||
}
|
||||
|
||||
virtual QJsonObject asJsonObject() const {
|
||||
return jObj;
|
||||
}
|
||||
|
||||
virtual QString asJson() const {
|
||||
QJsonDocument doc(jObj);
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
virtual void fromJson(QString jsonString) {
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
|
||||
jObj = doc.object();
|
||||
}
|
||||
|
||||
virtual void fromJsonObject(QJsonObject json) {
|
||||
jObj = json;
|
||||
}
|
||||
|
||||
virtual bool isSet() const {
|
||||
return false;
|
||||
}
|
||||
private :
|
||||
QJsonObject jObj;
|
||||
};
|
||||
|
||||
{{#cppNamespaceDeclarations}}
|
||||
}
|
||||
{{/cppNamespaceDeclarations}}
|
||||
|
||||
#endif /* _{{prefix}}_OBJECT_H_ */
|
||||
@@ -0,0 +1,48 @@
|
||||
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
OPTION(NODEBUG "Deactivate No debugging option" "OFF")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -Wno-unused-variable")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++14 -Wall -Wno-unused-variable")
|
||||
|
||||
if(${NODEBUG} STREQUAL "OFF")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg -g3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -g3")
|
||||
else (${NODEBUG} STREQUAL "OFF")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s -O3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s -O3")
|
||||
endif(${NODEBUG} STREQUAL "OFF")
|
||||
|
||||
find_package(Qt5Core REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
|
||||
file(GLOB SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/models/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/handlers/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/requests/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${Qt5Core_INCLUDE_DIRS}
|
||||
${Qt5Network_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/models
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/handlers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/requests
|
||||
)
|
||||
|
||||
link_directories(
|
||||
${CMAKE_PREFIX_PATH}/lib
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SRCS})
|
||||
add_dependencies(${PROJECT_NAME} QHTTPENGINE)
|
||||
target_link_libraries(${PROJECT_NAME} Qt5Core Qt5Network ssl crypto qhttpengine)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
|
||||
@@ -0,0 +1 @@
|
||||
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
|
||||
@@ -103,20 +103,31 @@
|
||||
});
|
||||
</script>
|
||||
<style type="text/css">
|
||||
{{>css_bootstrap}}
|
||||
{{>css_prettify}}
|
||||
{{>styles}}
|
||||
{{>fonts}}
|
||||
|
||||
{{>css_bootstrap}}
|
||||
{{>css_prettify}}
|
||||
|
||||
{{>styles}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// Script section to load models into a JS Var
|
||||
var defs = {}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
defs.{{name}} = {{{modelJson}}};
|
||||
{{/model}}
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
defs["{{name}}"] = {{{modelJson}}};
|
||||
{{/model}}
|
||||
{{/models}}
|
||||
|
||||
var errs = {};
|
||||
{{#swagger.vendorExtensions.x-shared-errors}}
|
||||
{
|
||||
let err = {{{.}}};
|
||||
errs[err.errorID] = err;
|
||||
}
|
||||
{{/swagger.vendorExtensions.x-shared-errors}}
|
||||
</script>
|
||||
|
||||
<div class="container-fluid">
|
||||
@@ -162,7 +173,9 @@
|
||||
<div class="app-desc">Version: {{{version}}}</div>
|
||||
{{/version}}
|
||||
<hr>
|
||||
<div>{{{appDescription}}}</div>
|
||||
<div id="app-description" class="app-desc">
|
||||
{{{appDescription}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="sections">
|
||||
@@ -200,6 +213,7 @@
|
||||
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-php">PHP</a></li>
|
||||
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-perl">Perl</a></li>
|
||||
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-python">Python</a></li>
|
||||
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-rust">Rust</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
@@ -243,8 +257,22 @@
|
||||
<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-0-python">
|
||||
<pre class="prettyprint"><code class="language-python">{{>sample_python}}</code></pre>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-0-rust">
|
||||
<pre class="prettyprint"><code class="language-rust">{{>sample_rust}}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Scopes</h2>
|
||||
<table>
|
||||
{{#authMethods}}{{#scopes}}
|
||||
<tr>
|
||||
<td>{{scope}}</td>
|
||||
<td>{{description}}</td>
|
||||
</tr>
|
||||
{{/scopes}}{{/authMethods}}
|
||||
</table>
|
||||
|
||||
<h2>Parameters</h2>
|
||||
|
||||
{{#hasPathParams}}
|
||||
@@ -314,31 +342,77 @@
|
||||
|
||||
<h2>Responses</h2>
|
||||
{{#responses}}
|
||||
<h3> Status: {{code}} - {{message}} </h3>
|
||||
<h3 id="examples-{{baseName}}-{{nickname}}-title-{{code}}"></h3>
|
||||
<p id="examples-{{baseName}}-{{nickname}}-description-{{code}}" class="marked"></p>
|
||||
<script>
|
||||
var response{{baseName}}{{code}}_description = `{{{message}}}`;
|
||||
var response{{baseName}}{{code}}_description_break = response{{baseName}}{{code}}_description.indexOf('\n');
|
||||
if (response{{baseName}}{{code}}_description_break == -1) {
|
||||
$("#examples-{{baseName}}-{{nickname}}-title-{{code}}").text("Status: {{code}} - " + response{{baseName}}{{code}}_description);
|
||||
} else {
|
||||
$("#examples-{{baseName}}-{{nickname}}-title-{{code}}").text("Status: {{code}} - " + response{{baseName}}{{code}}_description.substring(0, response{{baseName}}{{code}}_description_break));
|
||||
$("#examples-{{baseName}}-{{nickname}}-description-{{code}}").html(response{{baseName}}{{code}}_description.substring(response{{baseName}}{{code}}_description_break));
|
||||
}
|
||||
</script>
|
||||
|
||||
<ul class="nav nav-tabs nav-tabs-examples" >
|
||||
|
||||
<ul id="responses-detail-{{baseName}}-{{nickname}}-{{code}}" class="nav nav-tabs nav-tabs-examples" >
|
||||
{{#schema}}
|
||||
<li class="active">
|
||||
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-schema">Schema</a>
|
||||
<a data-toggle="tab" href="#responses-{{baseName}}-{{nickname}}-{{code}}-schema">Schema</a>
|
||||
</li>
|
||||
|
||||
{{#examples}}
|
||||
<li class="">
|
||||
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-example">Response Example</a>
|
||||
<a data-toggle="tab" href="#responses-{{baseName}}-{{nickname}}-{{code}}-example">Response Example</a>
|
||||
</li>
|
||||
{{/examples}}
|
||||
|
||||
{{/schema}}
|
||||
|
||||
{{#hasHeaders}}
|
||||
<li class="">
|
||||
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-headers">Headers</a>
|
||||
</li>
|
||||
{{/hasHeaders}}
|
||||
|
||||
{{#vendorExtensions}}
|
||||
{{#x-shared-errors}}
|
||||
<script>
|
||||
$(document).ready(function()
|
||||
{
|
||||
var errRef = "{{{$ref}}}";
|
||||
var errorID = errRef.substring(errRef.lastIndexOf("/") + 1);
|
||||
var errorDef = errs[errorID];
|
||||
var tabID = 'responses-detail-{{baseName}}-{{nickname}}-{{code}}-' + errorID;
|
||||
var contentID = tabID + "-content";
|
||||
|
||||
$('#responses-detail-{{baseName}}-{{nickname}}-{{code}}').append("<li><a href='#" + tabID + "' data-toggle='tab'>" + errorID + "</a></li>");
|
||||
var contentWrapper = $('#responses-{{baseName}}-{{nickname}}-{{code}}-wrapper');
|
||||
contentWrapper.append('<div class="tab-pane" id="' + tabID + '"><div id="' + contentID + '" class="exampleStyle"></div></div>');
|
||||
var contentPane = $('#' + contentID);
|
||||
|
||||
contentPane.append('<p>' + errorDef.message + '</p>');
|
||||
if (errorDef.variables)
|
||||
{
|
||||
contentPane.append('<h4>Variables</h4>');
|
||||
var lVars = $('<ol></ol>').appendTo(contentPane);
|
||||
for (lii = 0; lii < errorDef.variables.length; lii++)
|
||||
{
|
||||
$("<li></li>").appendTo(lVars).text(errorDef.variables[lii]);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{{/x-shared-errors}}
|
||||
{{/vendorExtensions}}
|
||||
</ul>
|
||||
|
||||
<div class="tab-content" style='margin-bottom: 10px;'>
|
||||
|
||||
<div class="tab-content" id="responses-{{baseName}}-{{nickname}}-{{code}}-wrapper" style='margin-bottom: 10px;'>
|
||||
{{#schema}}
|
||||
<div class="tab-pane active" id="responses-{{nickname}}-{{code}}-schema">
|
||||
<div id='responses-{{nickname}}-{{code}}-schema-{{code}}' style="padding: 30px; border-left: 1px solid #eee; border-right: 1px solid #eee; border-bottom: 1px solid #eee;">
|
||||
<div class="tab-pane active" id="responses-{{baseName}}-{{nickname}}-{{code}}-schema">
|
||||
<div id="responses-{{baseName}}-{{nickname}}-schema-{{code}}" class="exampleStyle">
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var schemaWrapper = {{{jsonSchema}}};
|
||||
@@ -352,45 +426,43 @@
|
||||
});
|
||||
}
|
||||
|
||||
//console.log(JSON.stringify(schema));
|
||||
var view = new JSONSchemaView(schema, 3);
|
||||
$('#responses-{{nickname}}-{{code}}-schema-data').val(stringify(schema));
|
||||
var result = $('#responses-{{nickname}}-{{code}}-schema-{{code}}');
|
||||
$('#responses-{{baseName}}-{{nickname}}-{{code}}-schema-data').val(JSON.stringify(schema));
|
||||
var result = $('#responses-{{baseName}}-{{nickname}}-schema-{{code}}');
|
||||
result.empty();
|
||||
result.append(view.render());
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<input id='responses-{{nickname}}-{{code}}-schema-data' type='hidden' value=''></input>
|
||||
<input id='responses-{{baseName}}-{{nickname}}-{{code}}-schema-data' type='hidden' value=''></input>
|
||||
</div>
|
||||
{{#examples}}
|
||||
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-example">
|
||||
<pre class="prettyprint"><code class="json">{{example}}</code></pre>
|
||||
</div>
|
||||
<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-{{code}}-example">
|
||||
<pre class="prettyprint"><code class="json">{{example}}</code></pre>
|
||||
</div>
|
||||
{{/examples}}
|
||||
{{/schema}}
|
||||
{{#hasHeaders}}
|
||||
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-headers">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="150px">Name</th>
|
||||
<th width="100px">Type</th>
|
||||
<th width="100px">Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
{{#headers}}
|
||||
<tr>
|
||||
<td>{{#name}}{{name}}{{/name}}</td>
|
||||
<td>{{#datatype}}{{dataType}}{{/datatype}}</td>
|
||||
<td>{{#dataFormat}}{{dataFormat}}{{/dataFormat}}</td>
|
||||
<td>{{#description}}{{description}}{{/description}}</td>
|
||||
</tr>
|
||||
{{/headers}}
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-headers">
|
||||
<table>
|
||||
<tr>
|
||||
<th width="150px">Name</th>
|
||||
<th width="100px">Type</th>
|
||||
<th width="100px">Format</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
{{#headers}}
|
||||
<tr>
|
||||
<td>{{#name}}{{name}}{{/name}}</td>
|
||||
<td>{{#datatype}}{{dataType}}{{/datatype}}</td>
|
||||
<td>{{#dataFormat}}{{dataFormat}}{{/dataFormat}}</td>
|
||||
<td>{{#description}}{{description}}{{/description}}</td>
|
||||
</tr>
|
||||
{{/headers}}
|
||||
</table>
|
||||
</div>
|
||||
{{/hasHeaders}}
|
||||
</div>
|
||||
|
||||
{{/responses}}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,8 +15,8 @@
|
||||
{{/dataFormat}}
|
||||
|
||||
{{#description}}
|
||||
<div class="inner description">
|
||||
{{description}}
|
||||
<div class="inner description marked">
|
||||
{{description}}
|
||||
</div>
|
||||
{{/description}}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<tr><td style="width:150px;">{{paramName}} {{^required}}{{/required}}{{#required}}<span style="color:red;">*</span>{{/required}}</td>
|
||||
<td>
|
||||
|
||||
|
||||
<p class="marked">{{description}}</p>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var schemaWrapper = {{{jsonSchema}}};
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
extern crate {{classname}};
|
||||
|
||||
pub fn main() {
|
||||
{{#allParams}} let {{paramName}} = {{{example}}}; // {{{dataType}}}
|
||||
{{/allParams}}
|
||||
|
||||
let mut context = {{classname}}::Context::default();
|
||||
let result = client.{{operationId}}({{#allParams}}{{paramName}}, {{/allParams}}&context).wait();
|
||||
println!("{:?}", result);
|
||||
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* Content
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
|
||||
|
||||
* {
|
||||
font-family: 'Source Code Pro', sans-serif;
|
||||
}
|
||||
@@ -10,7 +10,11 @@ body {
|
||||
min-width: 980px;
|
||||
}
|
||||
|
||||
body, p, a, div, th, td {
|
||||
.app-desc {
|
||||
color: #808080
|
||||
}
|
||||
|
||||
body, p, a, div, th, td, li {
|
||||
font-family: "Source Sans Pro", sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
@@ -310,8 +314,6 @@ pre code.sample-request-response-json {
|
||||
border-left: #e5e5e5 4px solid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------
|
||||
* Tabs
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
@@ -362,59 +364,175 @@ ul.nav-tabs {
|
||||
|
||||
} /* /@media print */
|
||||
|
||||
|
||||
.doc-chapter
|
||||
{
|
||||
display:none;
|
||||
background-color: #eee;
|
||||
border-radius: 1px;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
.doc-chapter {
|
||||
display: none;
|
||||
background-color: #eee;
|
||||
border-radius: 1px;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* json-schema-view-js
|
||||
* https://github.com/mohsen1/json-schema-view-js#readme
|
||||
* Version: 0.4.1 - 2015-11-12T17:19:27.615Z
|
||||
* License: MIT
|
||||
*/.json-schema-view .toggle-handle:after,.json-schema-view.json-schema-view-dark .toggle-handle:after,json-schema-view .toggle-handle:after,json-schema-view[json-schema-view-dark] .toggle-handle:after{content:"\25BC"}.json-schema-view .title,.json-schema-view.json-schema-view-dark .title,json-schema-view .title,json-schema-view[json-schema-view-dark] .title{font-weight:700;cursor:pointer}.json-schema-view,json-schema-view{font-family:monospace;font-size:0;display:table-cell}.json-schema-view>*,json-schema-view>*{font-size:14px}.json-schema-view .toggle-handle,json-schema-view .toggle-handle{cursor:pointer;margin:auto .3em;font-size:10px;display:inline-block;transform-origin:50% 40%;transition:transform 150ms ease-in}.json-schema-view .toggle-handle,.json-schema-view .toggle-handle:hover,json-schema-view .toggle-handle,json-schema-view .toggle-handle:hover{text-decoration:none;color:#333}.json-schema-view .description,json-schema-view .description{color:gray;font-style:italic}
|
||||
.pattern {
|
||||
color: blue;
|
||||
}
|
||||
.default {
|
||||
color: black;
|
||||
}
|
||||
.required {
|
||||
color:black;
|
||||
}
|
||||
.json-schema-view .title,.json-schema-view .title:hover,json-schema-view .title,json-schema-view .title:hover{text-decoration:none;color:#333}.json-schema-view .brace,.json-schema-view .bracket,.json-schema-view .title,json-schema-view .brace,json-schema-view .bracket,json-schema-view .title{color:#333}.json-schema-view .property,json-schema-view .property{font-size:0;display:table-row}.json-schema-view .property>*,json-schema-view .property>*{font-size:14px;padding:.2em}.json-schema-view .name,json-schema-view .name{color:#00f;display:table-cell;vertical-align:top}.json-schema-view .type,json-schema-view .type{color:green}.json-schema-view .type-any,json-schema-view .type-any{color:#33f}.json-schema-view .required,json-schema-view .required{color:red}.json-schema-view .inner,json-schema-view .inner{padding-left:18px}.json-schema-view.collapsed .description,.json-schema-view.collapsed .property,json-schema-view.collapsed .description,json-schema-view.collapsed .property{display:none}.json-schema-view.collapsed .closeing.brace,json-schema-view.collapsed .closeing.brace{display:inline-block}.json-schema-view.collapsed .toggle-handle,json-schema-view.collapsed .toggle-handle{transform:rotate(-90deg)}.json-schema-view.json-schema-view-dark,json-schema-view[json-schema-view-dark]{font-family:monospace;font-size:0;display:table-cell}.json-schema-view.json-schema-view-dark>*,json-schema-view[json-schema-view-dark]>*{font-size:14px}.json-schema-view.json-schema-view-dark .toggle-handle,json-schema-view[json-schema-view-dark] .toggle-handle{cursor:pointer;margin:auto .3em;font-size:10px;display:inline-block;transform-origin:50% 40%;transition:transform 150ms ease-in}.json-schema-view.json-schema-view-dark .toggle-handle,.json-schema-view.json-schema-view-dark .toggle-handle:hover,json-schema-view[json-schema-view-dark] .toggle-handle,json-schema-view[json-schema-view-dark] .toggle-handle:hover{text-decoration:none;color:#eee}.json-schema-view.json-schema-view-dark .description,json-schema-view[json-schema-view-dark] .description{color:gray;font-style:italic}.json-schema-view.json-schema-view-dark .title,.json-schema-view.json-schema-view-dark .title:hover,json-schema-view[json-schema-view-dark] .title,json-schema-view[json-schema-view-dark] .title:hover{text-decoration:none;color:#eee}.json-schema-view.json-schema-view-dark .brace,.json-schema-view.json-schema-view-dark .bracket,.json-schema-view.json-schema-view-dark .title,json-schema-view[json-schema-view-dark] .brace,json-schema-view[json-schema-view-dark] .bracket,json-schema-view[json-schema-view-dark] .title{color:#eee}.json-schema-view.json-schema-view-dark .property,json-schema-view[json-schema-view-dark] .property{font-size:0;display:table-row}.json-schema-view.json-schema-view-dark .property>*,json-schema-view[json-schema-view-dark] .property>*{font-size:14px;padding:.2em}.json-schema-view.json-schema-view-dark .name,json-schema-view[json-schema-view-dark] .name{color:#add8e6;display:table-cell;vertical-align:top}.json-schema-view.json-schema-view-dark .type,json-schema-view[json-schema-view-dark] .type{color:#90ee90}.json-schema-view.json-schema-view-dark .type-any,json-schema-view[json-schema-view-dark] .type-any{color:#d4ebf2}.json-schema-view.json-schema-view-dark .required,json-schema-view[json-schema-view-dark] .required{color:#fe0000}.json-schema-view.json-schema-view-dark .inner,json-schema-view[json-schema-view-dark] .inner{padding-left:18px}.json-schema-view.json-schema-view-dark.collapsed .description,.json-schema-view.json-schema-view-dark.collapsed .property,json-schema-view[json-schema-view-dark].collapsed .description,json-schema-view[json-schema-view-dark].collapsed .property{display:none}.json-schema-view.json-schema-view-dark.collapsed .closeing.brace,json-schema-view[json-schema-view-dark].collapsed .closeing.brace{display:inline-block}.json-schema-view.json-schema-view-dark.collapsed .toggle-handle,json-schema-view[json-schema-view-dark].collapsed .toggle-handle{transform:rotate(-90deg)}
|
||||
* json-schema-view-js
|
||||
* https://github.com/mohsen1/json-schema-view-js#readme
|
||||
* Version: 0.4.1 - 2015-11-12T17:19:27.615Z
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
.json-schema-view .toggle-handle:after, .json-schema-view.json-schema-view-dark .toggle-handle:after, json-schema-view .toggle-handle:after, json-schema-view[json-schema-view-dark] .toggle-handle:after {
|
||||
content: "\25BC"
|
||||
}
|
||||
.json-schema-view .title, .json-schema-view.json-schema-view-dark .title, json-schema-view .title, json-schema-view[json-schema-view-dark] .title {
|
||||
font-weight: 700;
|
||||
cursor: pointer
|
||||
}
|
||||
.json-schema-view, json-schema-view {
|
||||
font-family: monospace;
|
||||
font-size: 0;
|
||||
display: table-cell
|
||||
}
|
||||
.json-schema-view>*, json-schema-view>* {
|
||||
font-size: 14px
|
||||
}
|
||||
.json-schema-view .toggle-handle, json-schema-view .toggle-handle {
|
||||
cursor: pointer;
|
||||
margin: auto .3em;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
transform-origin: 50% 40%;
|
||||
transition: transform 150ms ease-in
|
||||
}
|
||||
.json-schema-view .toggle-handle, .json-schema-view .toggle-handle:hover, json-schema-view .toggle-handle, json-schema-view .toggle-handle:hover {
|
||||
text-decoration: none;
|
||||
color: #333
|
||||
}
|
||||
.json-schema-view .description, json-schema-view .description {
|
||||
color: gray;
|
||||
font-style: italic
|
||||
}
|
||||
.json-schema-view .readOnly, json-schema-view .readOnly {
|
||||
color: gray;
|
||||
font-style: italic
|
||||
}
|
||||
.json-schema-view .nullable, json-schema-view .nullable {
|
||||
color: gray;
|
||||
font-style: italic
|
||||
}
|
||||
.pattern, .example {
|
||||
color: blue;
|
||||
}
|
||||
.default {
|
||||
color: black;
|
||||
}
|
||||
.required {
|
||||
color: black;
|
||||
}
|
||||
.json-schema-view .title, .json-schema-view .title:hover, json-schema-view .title, json-schema-view .title:hover {
|
||||
text-decoration: none;
|
||||
color: #333
|
||||
}
|
||||
.json-schema-view .brace, .json-schema-view .bracket, .json-schema-view .title, json-schema-view .brace, json-schema-view .bracket, json-schema-view .title {
|
||||
color: #333
|
||||
}
|
||||
.json-schema-view .property, json-schema-view .property {
|
||||
font-size: 0;
|
||||
display: table-row
|
||||
}
|
||||
.json-schema-view .property>*, json-schema-view .property>* {
|
||||
font-size: 14px;
|
||||
padding: .2em
|
||||
}
|
||||
.json-schema-view .name, json-schema-view .name {
|
||||
color: #00f;
|
||||
display: table-cell;
|
||||
vertical-align: top
|
||||
}
|
||||
.json-schema-view .type, json-schema-view .type {
|
||||
color: green
|
||||
}
|
||||
.json-schema-view .type-any, json-schema-view .type-any {
|
||||
color: #33f
|
||||
}
|
||||
.json-schema-view .required, json-schema-view .required {
|
||||
color: red
|
||||
}
|
||||
.json-schema-view .inner, json-schema-view .inner {
|
||||
padding-left: 18px
|
||||
}
|
||||
.json-schema-view.collapsed .description, .json-schema-view.collapsed .property, json-schema-view.collapsed .description, json-schema-view.collapsed .property {
|
||||
display: none
|
||||
}
|
||||
.json-schema-view.collapsed .closeing.brace, json-schema-view.collapsed .closeing.brace {
|
||||
display: inline-block
|
||||
}
|
||||
.json-schema-view.collapsed .toggle-handle, json-schema-view.collapsed .toggle-handle {
|
||||
transform: rotate(-90deg)
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark, json-schema-view[json-schema-view-dark] {
|
||||
font-family: monospace;
|
||||
font-size: 0;
|
||||
display: table-cell
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark>*, json-schema-view[json-schema-view-dark]>* {
|
||||
font-size: 14px
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .toggle-handle, json-schema-view[json-schema-view-dark] .toggle-handle {
|
||||
cursor: pointer;
|
||||
margin: auto .3em;
|
||||
font-size: 10px;
|
||||
display: inline-block;
|
||||
transform-origin: 50% 40%;
|
||||
transition: transform 150ms ease-in
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .toggle-handle, .json-schema-view.json-schema-view-dark .toggle-handle:hover, json-schema-view[json-schema-view-dark] .toggle-handle, json-schema-view[json-schema-view-dark] .toggle-handle:hover {
|
||||
text-decoration: none;
|
||||
color: #eee
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .description, json-schema-view[json-schema-view-dark] .description {
|
||||
color: gray;
|
||||
font-style: italic
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .title, .json-schema-view.json-schema-view-dark .title:hover, json-schema-view[json-schema-view-dark] .title, json-schema-view[json-schema-view-dark] .title:hover {
|
||||
text-decoration: none;
|
||||
color: #eee
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .brace, .json-schema-view.json-schema-view-dark .bracket, .json-schema-view.json-schema-view-dark .title, json-schema-view[json-schema-view-dark] .brace, json-schema-view[json-schema-view-dark] .bracket, json-schema-view[json-schema-view-dark] .title {
|
||||
color: #eee
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .property, json-schema-view[json-schema-view-dark] .property {
|
||||
font-size: 0;
|
||||
display: table-row
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .property>*, json-schema-view[json-schema-view-dark] .property>* {
|
||||
font-size: 14px;
|
||||
padding: .2em
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .name, json-schema-view[json-schema-view-dark] .name {
|
||||
color: #add8e6;
|
||||
display: table-cell;
|
||||
vertical-align: top
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .type, json-schema-view[json-schema-view-dark] .type {
|
||||
color: #90ee90
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .type-any, json-schema-view[json-schema-view-dark] .type-any {
|
||||
color: #d4ebf2
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .required, json-schema-view[json-schema-view-dark] .required {
|
||||
color: #fe0000
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark .inner, json-schema-view[json-schema-view-dark] .inner {
|
||||
padding-left: 18px
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark.collapsed .description, .json-schema-view.json-schema-view-dark.collapsed .property, json-schema-view[json-schema-view-dark].collapsed .description, json-schema-view[json-schema-view-dark].collapsed .property {
|
||||
display: none
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark.collapsed .closeing.brace, json-schema-view[json-schema-view-dark].collapsed .closeing.brace {
|
||||
display: inline-block
|
||||
}
|
||||
.json-schema-view.json-schema-view-dark.collapsed .toggle-handle, json-schema-view[json-schema-view-dark].collapsed .toggle-handle {
|
||||
transform: rotate(-90deg)
|
||||
}
|
||||
.exampleStyle {
|
||||
padding: 30px; border-left: 1px solid #eee; border-right: 1px solid #eee; border-bottom: 1px solid #eee;
|
||||
}
|
||||
@@ -39,6 +39,6 @@
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "{{packageName}}"
|
||||
version = "{{appVersion}}"
|
||||
authors = [{{#infoEmail}}"{{infoEmail}}"{{/infoEmail}}]
|
||||
name = "{{{packageName}}}"
|
||||
version = "{{{appVersion}}}"
|
||||
authors = [{{#infoEmail}}"{{{infoEmail}}}"{{/infoEmail}}]
|
||||
{{#appDescription}}
|
||||
description = "{{{appDescription}}}"
|
||||
{{/appDescription}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Rust API for {{packageName}}
|
||||
# Rust API for {{{packageName}}}
|
||||
|
||||
{{#appDescription}}
|
||||
{{{appDescription}}}
|
||||
@@ -14,25 +14,25 @@ To see how to make this your own, look here:
|
||||
|
||||
[README]((https://openapi-generator.tech))
|
||||
|
||||
- API version: {{appVersion}}
|
||||
- API version: {{{appVersion}}}
|
||||
{{^hideGenerationTimestamp}}
|
||||
- Build date: {{generatedDate}}
|
||||
- Build date: {{{generatedDate}}}
|
||||
{{/hideGenerationTimestamp}}
|
||||
{{#infoUrl}}
|
||||
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||
{{/infoUrl}}
|
||||
|
||||
This autogenerated project defines an API crate `{{packageName}}` which contains:
|
||||
This autogenerated project defines an API crate `{{{packageName}}}` which contains:
|
||||
* An `Api` trait defining the API in Rust.
|
||||
* Data types representing the underlying data model.
|
||||
* A `Client` type which implements `Api` and issues HTTP requests for each operation.
|
||||
* A router which accepts HTTP requests and invokes the appropriate `Api` method for each operation.
|
||||
|
||||
It also contains an example server and client which make use of `{{packageName}}`:
|
||||
* The example server starts up a web server using the `{{packageName}}` router,
|
||||
It also contains an example server and client which make use of `{{{packageName}}}`:
|
||||
* The example server starts up a web server using the `{{{packageName}}}` router,
|
||||
and supplies a trivial implementation of `Api` which returns failure for every operation.
|
||||
* The example client provides a CLI which lets you invoke any single operation on the
|
||||
`{{packageName}}` client by passing appropriate arguments on the command line.
|
||||
`{{{packageName}}}` client by passing appropriate arguments on the command line.
|
||||
|
||||
You can use the example server and client as a basis for your own code.
|
||||
See below for [more detail on implementing a server](#writing-a-server).
|
||||
@@ -63,7 +63,7 @@ cargo run --example server
|
||||
To run a client, follow one of the following simple steps:
|
||||
|
||||
```{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
cargo run --example client {{operationId}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
cargo run --example client {{{operationId}}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
```
|
||||
|
||||
### HTTPS
|
||||
@@ -82,17 +82,17 @@ This will use the keys/certificates from the examples directory. Note that the s
|
||||
The server example is designed to form the basis for implementing your own server. Simply follow these steps.
|
||||
|
||||
* Set up a new Rust project, e.g., with `cargo init --bin`.
|
||||
* Insert `{{packageName}}` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "{{packageName}}" ]`.
|
||||
* Add `{{packageName}} = {version = "{{appVersion}}", path = "{{packageName}}"}` under `[dependencies]` in the root `Cargo.toml`.
|
||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `{{packageName}}/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
||||
* Insert `{{{packageName}}}` into the `members` array under [workspace] in the root `Cargo.toml`, e.g., `members = [ "{{{packageName}}}" ]`.
|
||||
* Add `{{{packageName}}} = {version = "{{{appVersion}}}", path = "{{{packageName}}}"}` under `[dependencies]` in the root `Cargo.toml`.
|
||||
* Copy the `[dependencies]` and `[dev-dependencies]` from `{{{packageName}}}/Cargo.toml` into the root `Cargo.toml`'s `[dependencies]` section.
|
||||
* Copy all of the `[dev-dependencies]`, but only the `[dependencies]` that are required by the example server. These should be clearly indicated by comments.
|
||||
* Remove `"optional = true"` from each of these lines if present.
|
||||
|
||||
Each autogenerated API will contain an implementation stub and main entry point, which should be copied into your project the first time:
|
||||
```
|
||||
cp {{packageName}}/examples/server.rs src/main.rs
|
||||
cp {{packageName}}/examples/server_lib/mod.rs src/lib.rs
|
||||
cp {{packageName}}/examples/server_lib/server.rs src/server.rs
|
||||
cp {{{packageName}}}/examples/server.rs src/main.rs
|
||||
cp {{{packageName}}}/examples/server_lib/mod.rs src/lib.rs
|
||||
cp {{{packageName}}}/examples/server_lib/server.rs src/server.rs
|
||||
```
|
||||
|
||||
Now
|
||||
|
||||
@@ -39,7 +39,7 @@ use swagger;
|
||||
use swagger::{ApiError, XSpanId, XSpanIdString, Has, AuthData};
|
||||
|
||||
use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
use models;
|
||||
|
||||
@@ -237,17 +237,17 @@ impl<F, C> Api<C> for Client<F> where
|
||||
F: Future<Item=hyper::Response, Error=hyper::Error> + 'static,
|
||||
C: Has<XSpanIdString> {{#hasAuthMethods}}+ Has<Option<AuthData>>{{/hasAuthMethods}}{
|
||||
{{#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<Future<Item={{operationId}}Response, Error=ApiError>> {
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}, context: &C) -> Box<Future<Item={{{operationId}}}Response, Error=ApiError>> {
|
||||
{{#queryParams}}{{#-first}}
|
||||
// Query parameters
|
||||
{{/-first}}{{#required}} let query_{{paramName}} = format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=param_{{paramName}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
|
||||
{{/required}}{{^required}} let query_{{paramName}} = param_{{paramName}}.map_or_else(String::new, |query| format!("{{baseName}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{paramName}}=query{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}));
|
||||
{{/-first}}{{#required}} let query_{{{paramName}}} = format!("{{{baseName}}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{{paramName}}}=param_{{{paramName}}}{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}});
|
||||
{{/required}}{{^required}} let query_{{{paramName}}} = param_{{{paramName}}}.map_or_else(String::new, |query| format!("{{{baseName}}}={{=<% %>=}}{<% paramName %>}<%={{ }}=%>&", {{{paramName}}}=query{{#isListContainer}}.join(","){{/isListContainer}}{{^isListContainer}}.to_string(){{/isListContainer}}));
|
||||
{{/required}}{{/queryParams}}
|
||||
|
||||
let uri = format!(
|
||||
"{}{{basePathWithoutHost}}{{path}}{{#queryParams}}{{#-first}}?{{/-first}}{{=<% %>=}}{<% paramName %>}<%={{ }}=%>{{/queryParams}}",
|
||||
self.base_path{{#pathParams}}, {{baseName}}=utf8_percent_encode(¶m_{{paramName}}.to_string(), PATH_SEGMENT_ENCODE_SET){{/pathParams}}{{#queryParams}},
|
||||
{{paramName}}=utf8_percent_encode(&query_{{paramName}}, QUERY_ENCODE_SET){{/queryParams}}
|
||||
"{}{{{basePathWithoutHost}}}{{path}}{{#queryParams}}{{#-first}}?{{/-first}}{{=<% %>=}}{<% paramName %>}<%={{ }}=%>{{/queryParams}}",
|
||||
self.base_path{{#pathParams}}, {{{baseName}}}=utf8_percent_encode(¶m_{{{paramName}}}.to_string(), PATH_SEGMENT_ENCODE_SET){{/pathParams}}{{#queryParams}},
|
||||
{{{paramName}}}=utf8_percent_encode(&query_{{{paramName}}}, QUERY_ENCODE_SET){{/queryParams}}
|
||||
);
|
||||
|
||||
let uri = match Uri::from_str(&uri) {
|
||||
@@ -255,30 +255,30 @@ impl<F, C> Api<C> for Client<F> where
|
||||
Err(err) => return Box::new(futures::done(Err(ApiError(format!("Unable to build URI: {}", err))))),
|
||||
};
|
||||
|
||||
let mut request = hyper::Request::new(hyper::Method::{{#vendorExtensions}}{{HttpMethod}}{{/vendorExtensions}}, uri);
|
||||
let mut request = hyper::Request::new(hyper::Method::{{#vendorExtensions}}{{{HttpMethod}}}{{/vendorExtensions}}, uri);
|
||||
|
||||
{{#vendorExtensions}}{{#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}}
|
||||
("{{{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");
|
||||
|
||||
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone()));
|
||||
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}.clone()));
|
||||
request.set_body(body.into_bytes());{{/-last}}{{/formParams}}{{/vendorExtensions}}{{#bodyParam}}{{#-first}}
|
||||
// Body parameter
|
||||
{{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{paramName}};{{/consumesPlainText}}{{#consumesXml}}
|
||||
{{^has_namespace}} let body = serde_xml_rs::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/has_namespace}}{{#has_namespace}}
|
||||
{{/-first}}{{#vendorExtensions}}{{#required}}{{#consumesPlainText}} let body = param_{{{paramName}}};{{/consumesPlainText}}{{#consumesXml}}
|
||||
{{^has_namespace}} let body = serde_xml_rs::to_string(¶m_{{{paramName}}}).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(), models::namespaces::{{uppercase_data_type}}.clone());
|
||||
let body = serde_xml_rs::to_string_with_namespaces(¶m_{{paramName}}, namespaces).expect("impossible to fail to serialize");{{/has_namespace}}{{/consumesXml}}{{#consumesJson}}
|
||||
let body = serde_json::to_string(¶m_{{paramName}}).expect("impossible to fail to serialize");{{/consumesJson}}
|
||||
{{/required}}{{^required}}{{#consumesPlainText}} let body = param_{{paramName}};
|
||||
{{/consumesPlainText}}{{^consumesPlainText}} let body = param_{{paramName}}.map(|ref body| {
|
||||
namespaces.insert("".to_string(), models::namespaces::{{{uppercase_data_type}}}.clone());
|
||||
let body = serde_xml_rs::to_string_with_namespaces(¶m_{{{paramName}}}, namespaces).expect("impossible to fail to serialize");{{/has_namespace}}{{/consumesXml}}{{#consumesJson}}
|
||||
let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize");{{/consumesJson}}
|
||||
{{/required}}{{^required}}{{#consumesPlainText}} let body = param_{{{paramName}}};
|
||||
{{/consumesPlainText}}{{^consumesPlainText}} let body = param_{{{paramName}}}.map(|ref body| {
|
||||
{{#consumesXml}}
|
||||
{{^has_namespace}} 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(), models::namespaces::{{uppercase_data_type}}.clone());
|
||||
namespaces.insert("".to_string(), models::namespaces::{{{uppercase_data_type}}}.clone());
|
||||
serde_xml_rs::to_string_with_namespaces(body, namespaces).expect("impossible to fail to serialize"){{/has_namespace}}{{/consumesXml}}{{#consumesJson}}
|
||||
serde_json::to_string(body).expect("impossible to fail to serialize"){{/consumesJson}}
|
||||
});{{/consumesPlainText}}{{/required}}{{/vendorExtensions}}{{/bodyParam}}
|
||||
@@ -287,7 +287,7 @@ impl<F, C> Api<C> for Client<F> where
|
||||
{{/required}} request.set_body(body.into_bytes());
|
||||
{{^required}} }{{/required}}
|
||||
|
||||
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}.clone()));
|
||||
request.headers_mut().set(ContentType(mimetypes::requests::{{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}.clone()));
|
||||
{{/bodyParam}}
|
||||
request.headers_mut().set(XSpanId((context as &Has<XSpanIdString>).get().0.clone()));
|
||||
{{#authMethods}}{{#isBasic}} (context as &Has<Option<AuthData>>).get().as_ref().map(|auth_data| {
|
||||
@@ -298,10 +298,10 @@ impl<F, C> Api<C> for Client<F> where
|
||||
}
|
||||
});{{/isBasic}}{{/authMethods}}{{#headerParams}}{{#-first}}
|
||||
// Header parameters
|
||||
{{/-first}}{{^isMapContainer}} header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
|
||||
{{#required}} request.headers_mut().set(Request{{vendorExtensions.typeName}}(param_{{paramName}}{{#isListContainer}}.clone(){{/isListContainer}}));
|
||||
{{/required}}{{^required}} param_{{paramName}}.map(|header| request.headers_mut().set(Request{{vendorExtensions.typeName}}(header{{#isListContainer}}.clone(){{/isListContainer}})));
|
||||
{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{paramName}}: Option<{{{dataType}}}> = None;
|
||||
{{/-first}}{{^isMapContainer}} header! { (Request{{vendorExtensions.typeName}}, "{{{baseName}}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
|
||||
{{#required}} request.headers_mut().set(Request{{vendorExtensions.typeName}}(param_{{{paramName}}}{{#isListContainer}}.clone(){{/isListContainer}}));
|
||||
{{/required}}{{^required}} param_{{{paramName}}}.map(|header| request.headers_mut().set(Request{{vendorExtensions.typeName}}(header{{#isListContainer}}.clone(){{/isListContainer}})));
|
||||
{{/required}}{{/isMapContainer}}{{#isMapContainer}} let param_{{{paramName}}}: Option<{{{dataType}}}> = None;
|
||||
{{/isMapContainer}}{{/headerParams}}
|
||||
|
||||
Box::new(self.client_service.call(request)
|
||||
@@ -309,11 +309,11 @@ impl<F, C> Api<C> for Client<F> where
|
||||
.and_then(|mut response| {
|
||||
match response.status().as_u16() {
|
||||
{{#responses}}
|
||||
{{code}} => {
|
||||
{{#headers}} header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{datatype}}}] }
|
||||
let response_{{name}} = match response.headers().get::<Response{{nameInCamelCase}}>() {
|
||||
Some(response_{{name}}) => response_{{name}}.0.clone(),
|
||||
None => return Box::new(future::err(ApiError(String::from("Required response header {{baseName}} for response {{code}} was not found.")))) as Box<Future<Item=_, Error=_>>,
|
||||
{{{code}}} => {
|
||||
{{#headers}} header! { (Response{{{nameInCamelCase}}}, "{{{baseName}}}") => [{{{datatype}}}] }
|
||||
let response_{{{name}}} = match response.headers().get::<Response{{{nameInCamelCase}}}>() {
|
||||
Some(response_{{{name}}}) => response_{{{name}}}.0.clone(),
|
||||
None => return Box::new(future::err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found.")))) as Box<Future<Item=_, Error=_>>,
|
||||
};
|
||||
{{/headers}}
|
||||
let body = response.body();
|
||||
@@ -338,11 +338,11 @@ impl<F, C> Api<C> for Client<F> where
|
||||
{{/producesPlainText}}{{/vendorExtensions}}
|
||||
))
|
||||
.map(move |body|
|
||||
{{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{name}}: response_{{name}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}}
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{^headers}}(body){{/headers}}{{#headers}}{{#-first}}{ body: body, {{/-first}}{{{name}}}: response_{{{name}}}{{^-last}}, {{/-last}}{{#-last}} }{{/-last}}{{/headers}}
|
||||
)
|
||||
{{/dataType}}{{^dataType}}
|
||||
future::ok(
|
||||
{{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{#headers}}{{#-first}}{ {{/-first}}{{^-first}}, {{/-first}}{{name}}: response_{{name}}{{#-last}} }{{/-last}}{{/headers}}
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}{{#headers}}{{#-first}}{ {{/-first}}{{^-first}}, {{/-first}}{{{name}}}: response_{{{name}}}{{#-last}} }{{/-last}}{{/headers}}
|
||||
)
|
||||
{{/dataType}}
|
||||
) as Box<Future<Item=_, Error=_>>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#![allow(missing_docs, unused_variables, trivial_casts)]
|
||||
|
||||
extern crate {{externCrateName}};
|
||||
extern crate {{{externCrateName}}};
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate futures;
|
||||
#[allow(unused_extern_crates)]
|
||||
@@ -17,9 +17,9 @@ use swagger::{ContextBuilder, EmptyContext, XSpanIdString, Has, Push, AuthData};
|
||||
use futures::{Future, future, Stream, stream};
|
||||
use tokio_core::reactor;
|
||||
#[allow(unused_imports)]
|
||||
use {{externCrateName}}::{ApiNoContext, ContextWrapperExt,
|
||||
use {{{externCrateName}}}::{ApiNoContext, ContextWrapperExt,
|
||||
ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
use clap::{App, Arg};
|
||||
|
||||
@@ -28,7 +28,7 @@ fn main() {
|
||||
.arg(Arg::with_name("operation")
|
||||
.help("Sets the operation to run")
|
||||
.possible_values(&[
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#vendorExtensions}}{{^noClientExample}} "{{operationId}}",
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#vendorExtensions}}{{^noClientExample}} "{{{operationId}}}",
|
||||
{{/noClientExample}}{{/vendorExtensions}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}])
|
||||
.required(true)
|
||||
.index(1))
|
||||
@@ -38,12 +38,12 @@ fn main() {
|
||||
.arg(Arg::with_name("host")
|
||||
.long("host")
|
||||
.takes_value(true)
|
||||
.default_value("{{serverHost}}")
|
||||
.default_value("{{{serverHost}}}")
|
||||
.help("Hostname to contact"))
|
||||
.arg(Arg::with_name("port")
|
||||
.long("port")
|
||||
.takes_value(true)
|
||||
.default_value("{{serverPort}}")
|
||||
.default_value("{{{serverPort}}}")
|
||||
.help("Port to contact"))
|
||||
.get_matches();
|
||||
|
||||
@@ -55,11 +55,11 @@ fn main() {
|
||||
matches.value_of("port").unwrap());
|
||||
let client = if matches.is_present("https") {
|
||||
// Using Simple HTTPS
|
||||
{{externCrateName}}::Client::try_new_https(core.handle(), &base_url, "examples/ca.pem")
|
||||
{{{externCrateName}}}::Client::try_new_https(core.handle(), &base_url, "examples/ca.pem")
|
||||
.expect("Failed to create HTTPS client")
|
||||
} else {
|
||||
// Using HTTP
|
||||
{{externCrateName}}::Client::try_new_http(core.handle(), &base_url)
|
||||
{{{externCrateName}}}::Client::try_new_http(core.handle(), &base_url)
|
||||
.expect("Failed to create HTTP client")
|
||||
};
|
||||
|
||||
@@ -70,8 +70,8 @@ fn main() {
|
||||
match matches.value_of("operation") {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{#vendorExtensions}}{{#noClientExample}}// Disabled because there's no example.
|
||||
// {{/noClientExample}}Some("{{operationId}}") => {
|
||||
{{#noClientExample}}// {{/noClientExample}} let result = core.run(client.{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{^-first}}, {{/-first}}{{#vendorExtensions}}{{{example}}}{{/vendorExtensions}}{{/allParams}}));
|
||||
// {{/noClientExample}}Some("{{{operationId}}}") => {
|
||||
{{#noClientExample}}// {{/noClientExample}} let result = core.run(client.{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{^-first}}, {{/-first}}{{#vendorExtensions}}{{{example}}}{{/vendorExtensions}}{{/allParams}}));
|
||||
{{#vendorExtensions}}{{#noClientExample}}// {{/noClientExample}}{{/vendorExtensions}} println!("{:?} (X-Span-ID: {:?})", result, (client.context() as &Has<XSpanIdString>).get().clone());
|
||||
{{#vendorExtensions}}{{#noClientExample}}// {{/noClientExample}}{{/vendorExtensions}} },
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Main binary entry point for {{externCrateName}} implementation.
|
||||
//! 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 {{{externCrateName}}};
|
||||
extern crate swagger;
|
||||
extern crate hyper;
|
||||
extern crate openssl;
|
||||
@@ -14,7 +14,7 @@ extern crate tokio_tls;
|
||||
extern crate clap;
|
||||
|
||||
// Imports required by server library.
|
||||
// extern crate {{externCrateName}};
|
||||
// extern crate {{{externCrateName}}};
|
||||
// extern crate swagger;
|
||||
extern crate futures;
|
||||
extern crate chrono;
|
||||
@@ -55,14 +55,14 @@ fn main() {
|
||||
.get_matches();
|
||||
|
||||
let service_fn =
|
||||
{{externCrateName}}::server::auth::NewService::<_, EmptyContext>::new(
|
||||
{{{externCrateName}}}::server::auth::NewService::<_, EmptyContext>::new(
|
||||
AllowAllAuthenticator::new(
|
||||
server_lib::NewService::new(),
|
||||
"cosmo"
|
||||
)
|
||||
);
|
||||
|
||||
let addr = "127.0.0.1:{{serverPort}}".parse().expect("Failed to parse bind address");
|
||||
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);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Main library entry point for {{externCrateName}} implementation.
|
||||
//! Main library entry point for {{{externCrateName}}} implementation.
|
||||
|
||||
mod server;
|
||||
|
||||
@@ -11,7 +11,7 @@ use std::io;
|
||||
use std::clone::Clone;
|
||||
use std::marker::PhantomData;
|
||||
use hyper;
|
||||
use {{externCrateName}};
|
||||
use {{{externCrateName}}};
|
||||
use swagger::{Has, XSpanIdString};
|
||||
use swagger::auth::Authorization;
|
||||
|
||||
@@ -29,10 +29,10 @@ impl<C> hyper::server::NewService for NewService<C> where C: Has<XSpanIdString>
|
||||
type Request = (hyper::Request, C);
|
||||
type Response = hyper::Response;
|
||||
type Error = hyper::Error;
|
||||
type Instance = {{externCrateName}}::server::Service<server::Server<C>, C>;
|
||||
type Instance = {{{externCrateName}}}::server::Service<server::Server<C>, C>;
|
||||
|
||||
/// Instantiate a new server.
|
||||
fn new_service(&self) -> io::Result<Self::Instance> {
|
||||
Ok({{externCrateName}}::server::Service::new(server::Server::new()))
|
||||
Ok({{{externCrateName}}}::server::Service::new(server::Server::new()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Server implementation of {{externCrateName}}.
|
||||
//! Server implementation of {{{externCrateName}}}.
|
||||
|
||||
#![allow(unused_imports)]
|
||||
|
||||
@@ -10,10 +10,10 @@ use std::marker::PhantomData;
|
||||
use swagger;
|
||||
use swagger::{Has, XSpanIdString};
|
||||
|
||||
use {{externCrateName}}::{Api, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
use {{{externCrateName}}}::{Api, ApiError{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
use {{externCrateName}}::models;
|
||||
use {{{externCrateName}}}::models;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Server<C> {
|
||||
@@ -29,9 +29,9 @@ impl<C> Server<C> {
|
||||
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>> {
|
||||
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>> {
|
||||
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}}
|
||||
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}}
|
||||
|
||||
@@ -32,16 +32,16 @@ mod mimetypes;
|
||||
|
||||
pub use swagger::{ApiError, ContextWrapper};
|
||||
|
||||
pub const BASE_PATH: &'static str = "{{basePathWithoutHost}}";
|
||||
pub const API_VERSION: &'static str = "{{appVersion}}";
|
||||
pub const BASE_PATH: &'static str = "{{{basePathWithoutHost}}}";
|
||||
pub const API_VERSION: &'static str = "{{{appVersion}}}";
|
||||
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
{{^isResponseFile}}
|
||||
#[derive(Debug, PartialEq)]
|
||||
{{/isResponseFile}}
|
||||
pub enum {{operationId}}Response {
|
||||
pub enum {{{operationId}}}Response {
|
||||
{{#responses}}
|
||||
{{#message}} /// {{message}}{{/message}}
|
||||
{{#message}} /// {{{message}}}{{/message}}
|
||||
{{#vendorExtensions}}{{{x-responseId}}}{{/vendorExtensions}} {{#dataType}}{{^hasHeaders}}( {{{dataType}}} ) {{/hasHeaders}}{{#hasHeaders}}{{#-first}}{ body: {{{dataType}}}{{/-first}}{{/hasHeaders}}{{/dataType}}{{#dataType}}{{#hasHeaders}}, {{/hasHeaders}}{{/dataType}}{{^dataType}}{{#hasHeaders}} { {{/hasHeaders}}{{/dataType}}{{#headers}}{{^-first}}, {{/-first}}{{{name}}}: {{{datatype}}}{{#-last}} } {{/-last}}{{/headers}},
|
||||
{{/responses}}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ pub enum {{operationId}}Response {
|
||||
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<Future<Item={{operationId}}Response, Error=ApiError>>;
|
||||
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>>;
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ pub trait Api<C> {
|
||||
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<Future<Item={{operationId}}Response, Error=ApiError>>;
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<Future<Item={{{operationId}}}Response, Error=ApiError>>;
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
@@ -78,8 +78,8 @@ 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<Future<Item={{operationId}}Response, Error=ApiError>> {
|
||||
self.api().{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}{{paramName}}, {{/allParams}}&self.context())
|
||||
fn {{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}(&self{{#allParams}}, {{{paramName}}}: {{^required}}Option<{{/required}}{{#isListContainer}}&{{/isListContainer}}{{{dataType}}}{{^required}}>{{/required}}{{/allParams}}) -> Box<Future<Item={{{operationId}}}Response, Error=ApiError>> {
|
||||
self.api().{{#vendorExtensions}}{{{operation_id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&self.context())
|
||||
}
|
||||
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
@@ -4,22 +4,22 @@ pub mod responses {
|
||||
use hyper::mime::*;
|
||||
|
||||
// The macro is called per-operation to beat the recursion limit
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{operationId}}
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#responses}}{{#produces}}{{#-first}}{{#dataType}} /// Create Mime objects for the response content types for {{{operationId}}}
|
||||
lazy_static! {
|
||||
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = "{{{mediaType}}}".parse().unwrap();
|
||||
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}: Mime = "{{{mediaType}}}".parse().unwrap();
|
||||
}
|
||||
{{/dataType}}{{/-first}}{{/produces}}{{/responses}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
pub mod requests {
|
||||
use hyper::mime::*;
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{operationId}}
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{#bodyParam}} /// Create Mime objects for the request content types for {{{operationId}}}
|
||||
lazy_static! {
|
||||
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap();
|
||||
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}".parse().unwrap();
|
||||
}
|
||||
{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}} /// Create Mime objects for the request content types for {{operationId}}
|
||||
{{/bodyParam}}{{^bodyParam}}{{#vendorExtensions}}{{#formParams}}{{#-first}} /// Create Mime objects for the request content types for {{{operationId}}}
|
||||
lazy_static! {
|
||||
pub static ref {{#vendorExtensions}}{{uppercase_operation_id}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap();
|
||||
pub static ref {{#vendorExtensions}}{{{uppercase_operation_id}}}{{/vendorExtensions}}: Mime = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/x-www-form-urlencoded{{/consumes}}".parse().unwrap();
|
||||
}
|
||||
{{/-first}}{{/formParams}}{{/vendorExtensions}}{{/bodyParam}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
}
|
||||
|
||||
@@ -17,149 +17,149 @@ use swagger;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, Eq, Ord)]{{#xmlName}}
|
||||
#[serde(rename = "{{xmlName}}")]{{/xmlName}}
|
||||
pub enum {{classname}} { {{#allowableValues}}{{#enumVars}}
|
||||
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||
pub enum {{{classname}}} { {{#allowableValues}}{{#enumVars}}
|
||||
#[serde(rename = {{{value}}})]
|
||||
{{name}},{{/enumVars}}{{/allowableValues}}
|
||||
{{{name}}},{{/enumVars}}{{/allowableValues}}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for {{classname}} {
|
||||
impl ::std::fmt::Display for {{{classname}}} {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self { {{#allowableValues}}{{#enumVars}}
|
||||
{{classname}}::{{name}} => write!(f, "{}", {{{value}}}),{{/enumVars}}{{/allowableValues}}
|
||||
{{{classname}}}::{{{name}}} => write!(f, "{}", {{{value}}}),{{/enumVars}}{{/allowableValues}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::str::FromStr for {{classname}} {
|
||||
impl ::std::str::FromStr for {{{classname}}} {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
{{#allowableValues}}{{#enumVars}} {{{value}}} => Ok({{classname}}::{{name}}),
|
||||
{{#allowableValues}}{{#enumVars}} {{{value}}} => Ok({{{classname}}}::{{{name}}}),
|
||||
{{/enumVars}}{{/allowableValues}} _ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/isEnum}}{{^isEnum}}{{#dataType}}{{! newtype}}#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
{{#xmlName}}#[serde(rename = "{{xmlName}}")]{{/xmlName}}
|
||||
pub struct {{classname}}({{{dataType}}});
|
||||
{{#xmlName}}#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||
pub struct {{{classname}}}({{{dataType}}});
|
||||
|
||||
impl ::std::convert::From<{{dataType}}> for {{classname}} {
|
||||
fn from(x: {{dataType}}) -> Self {
|
||||
{{classname}}(x)
|
||||
impl ::std::convert::From<{{{dataType}}}> for {{{classname}}} {
|
||||
fn from(x: {{{dataType}}}) -> Self {
|
||||
{{{classname}}}(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<{{classname}}> for {{dataType}} {
|
||||
fn from(x: {{classname}}) -> Self {
|
||||
impl ::std::convert::From<{{{classname}}}> for {{{dataType}}} {
|
||||
fn from(x: {{{classname}}}) -> Self {
|
||||
x.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for {{classname}} {
|
||||
impl ::std::ops::Deref for {{{classname}}} {
|
||||
type Target = {{{dataType}}};
|
||||
fn deref(&self) -> &{{{dataType}}} {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::DerefMut for {{classname}} {
|
||||
impl ::std::ops::DerefMut for {{{classname}}} {
|
||||
fn deref_mut(&mut self) -> &mut {{{dataType}}} {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
{{/dataType}}{{^dataType}}{{#arrayModelType}}{{#vendorExtensions}}{{#itemXmlName}}// Utility function for wrapping list elements when serializing xml
|
||||
fn wrap_in_{{itemXmlName}}<S>(item: &Vec<{{arrayModelType}}>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
fn wrap_in_{{{itemXmlName}}}<S>(item: &Vec<{{{arrayModelType}}}>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serde_xml_rs::wrap_primitives(item, serializer, "{{itemXmlName}}")
|
||||
serde_xml_rs::wrap_primitives(item, serializer, "{{{itemXmlName}}}")
|
||||
}
|
||||
|
||||
{{/itemXmlName}}{{/vendorExtensions}}{{! vec}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct {{classname}}(Vec<{{{arrayModelType}}}>);
|
||||
pub struct {{{classname}}}(Vec<{{{arrayModelType}}}>);
|
||||
|
||||
impl ::std::convert::From<Vec<{{arrayModelType}}>> for {{classname}} {
|
||||
fn from(x: Vec<{{arrayModelType}}>) -> Self {
|
||||
{{classname}}(x)
|
||||
impl ::std::convert::From<Vec<{{{arrayModelType}}}>> for {{{classname}}} {
|
||||
fn from(x: Vec<{{{arrayModelType}}}>) -> Self {
|
||||
{{{classname}}}(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::From<{{classname}}> for Vec<{{arrayModelType}}> {
|
||||
fn from(x: {{classname}}) -> Self {
|
||||
impl ::std::convert::From<{{{classname}}}> for Vec<{{{arrayModelType}}}> {
|
||||
fn from(x: {{{classname}}}) -> Self {
|
||||
x.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::iter::FromIterator<{{arrayModelType}}> for {{classname}} {
|
||||
fn from_iter<U: IntoIterator<Item={{arrayModelType}}>>(u: U) -> Self {
|
||||
{{classname}}(Vec::<{{arrayModelType}}>::from_iter(u))
|
||||
impl ::std::iter::FromIterator<{{{arrayModelType}}}> for {{{classname}}} {
|
||||
fn from_iter<U: IntoIterator<Item={{{arrayModelType}}}>>(u: U) -> Self {
|
||||
{{{classname}}}(Vec::<{{{arrayModelType}}}>::from_iter(u))
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::iter::IntoIterator for {{classname}} {
|
||||
type Item = {{arrayModelType}};
|
||||
type IntoIter = ::std::vec::IntoIter<{{arrayModelType}}>;
|
||||
impl ::std::iter::IntoIterator for {{{classname}}} {
|
||||
type Item = {{{arrayModelType}}};
|
||||
type IntoIter = ::std::vec::IntoIter<{{{arrayModelType}}}>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::std::iter::IntoIterator for &'a {{classname}} {
|
||||
type Item = &'a {{arrayModelType}};
|
||||
type IntoIter = ::std::slice::Iter<'a, {{arrayModelType}}>;
|
||||
impl<'a> ::std::iter::IntoIterator for &'a {{{classname}}} {
|
||||
type Item = &'a {{{arrayModelType}}};
|
||||
type IntoIter = ::std::slice::Iter<'a, {{{arrayModelType}}}>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
(&self.0).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::std::iter::IntoIterator for &'a mut {{classname}} {
|
||||
type Item = &'a mut {{arrayModelType}};
|
||||
type IntoIter = ::std::slice::IterMut<'a, {{arrayModelType}}>;
|
||||
impl<'a> ::std::iter::IntoIterator for &'a mut {{{classname}}} {
|
||||
type Item = &'a mut {{{arrayModelType}}};
|
||||
type IntoIter = ::std::slice::IterMut<'a, {{{arrayModelType}}}>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
(&mut self.0).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for {{classname}} {
|
||||
impl ::std::ops::Deref for {{{classname}}} {
|
||||
type Target = Vec<{{{arrayModelType}}}>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::DerefMut for {{classname}} {
|
||||
impl ::std::ops::DerefMut for {{{classname}}} {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
{{/arrayModelType}}{{^arrayModelType}}{{! general struct}}#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]{{#xmlName}}
|
||||
#[serde(rename = "{{xmlName}}")]{{/xmlName}}
|
||||
pub struct {{classname}} {
|
||||
#[serde(rename = "{{{xmlName}}}")]{{/xmlName}}
|
||||
pub struct {{{classname}}} {
|
||||
{{#vars}}{{#description}} /// {{{description}}}
|
||||
{{/description}}{{#isEnum}} // Note: inline enums are not fully supported by openapi-generator
|
||||
{{/isEnum}} #[serde(rename = "{{baseName}}")]{{#vendorExtensions}}{{#itemXmlName}}
|
||||
#[serde(serialize_with = "wrap_in_{{itemXmlName}}")]{{/itemXmlName}}{{/vendorExtensions}}{{#required}}
|
||||
pub {{name}}: {{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{{dataType}}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}},
|
||||
{{/isEnum}} #[serde(rename = "{{{baseName}}}")]{{#vendorExtensions}}{{#itemXmlName}}
|
||||
#[serde(serialize_with = "wrap_in_{{{itemXmlName}}}")]{{/itemXmlName}}{{/vendorExtensions}}{{#required}}
|
||||
pub {{{name}}}: {{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{{dataType}}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}},
|
||||
{{/required}}{{^required}}{{#vendorExtensions}}{{#x-nullable}} #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")]
|
||||
#[serde(default = "swagger::nullable_format::default_optional_nullable")]
|
||||
{{/x-nullable}}{{/vendorExtensions}}
|
||||
#[serde(skip_serializing_if="Option::is_none")]
|
||||
pub {{name}}: Option<{{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{#isListContainer}}Vec<{{#items}}{{{dataType}}}{{/items}}>{{/isListContainer}}{{^isListContainer}}{{{dataType}}}{{/isListContainer}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}}>,
|
||||
pub {{{name}}}: Option<{{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{#isListContainer}}Vec<{{#items}}{{{dataType}}}{{/items}}>{{/isListContainer}}{{^isListContainer}}{{{dataType}}}{{/isListContainer}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}}>,
|
||||
{{/required}}
|
||||
|
||||
{{/vars}}
|
||||
}
|
||||
|
||||
impl {{classname}} {
|
||||
pub fn new({{#vars}}{{^defaultValue}}{{name}}: {{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{{dataType}}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}}, {{/defaultValue}}{{/vars}}) -> {{classname}} {
|
||||
{{classname}} {
|
||||
{{#vars}} {{name}}: {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{name}}{{/defaultValue}},
|
||||
impl {{{classname}}} {
|
||||
pub fn new({{#vars}}{{^defaultValue}}{{{name}}}: {{#vendorExtensions}}{{#x-nullable}}swagger::Nullable<{{/x-nullable}}{{/vendorExtensions}}{{{dataType}}}{{#vendorExtensions}}{{#x-nullable}}>{{/x-nullable}}{{/vendorExtensions}}, {{/defaultValue}}{{/vars}}) -> {{{classname}}} {
|
||||
{{{classname}}} {
|
||||
{{#vars}} {{{name}}}: {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}},
|
||||
{{/vars}}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ impl {{classname}} {
|
||||
//XML namespaces
|
||||
pub mod namespaces {
|
||||
lazy_static!{
|
||||
{{#models}}{{#model}}{{#xmlNamespace}}pub static ref {{#vendorExtensions}}{{upperCaseName}}{{/vendorExtensions}}: String = "{{xmlNamespace}}".to_string();
|
||||
{{#models}}{{#model}}{{#xmlNamespace}}pub static ref {{#vendorExtensions}}{{{upperCaseName}}}{{/vendorExtensions}}: String = "{{{xmlNamespace}}}".to_string();
|
||||
{{/xmlNamespace}}{{/model}}{{/models}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ impl<T, C> hyper::server::Service for Service<T, C>
|
||||
{{#isApiKey}}
|
||||
{{#isKeyInHeader}}
|
||||
{
|
||||
header! { (ApiKey{{-index}}, "{{keyParamName}}") => [String] }
|
||||
header! { (ApiKey{{-index}}, "{{{keyParamName}}}") => [String] }
|
||||
if let Some(header) = req.headers().get::<ApiKey{{-index}}>().cloned() {
|
||||
let auth_data = AuthData::ApiKey(header.0);
|
||||
let context = context.push(Some(auth_data));
|
||||
|
||||
@@ -37,7 +37,7 @@ use swagger::{ApiError, XSpanId, XSpanIdString, Has, RequestParser};
|
||||
use swagger::auth::Scopes;
|
||||
|
||||
use {Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}},
|
||||
{{operationId}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
{{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use models;
|
||||
@@ -52,15 +52,15 @@ mod paths {
|
||||
lazy_static! {
|
||||
pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(&[
|
||||
{{#pathSet}}
|
||||
r"^{{basePathWithoutHost}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
|
||||
r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}}
|
||||
{{/pathSet}}
|
||||
]).unwrap();
|
||||
}
|
||||
{{#pathSet}}
|
||||
pub static ID_{{PATH_ID}}: usize = {{index}};
|
||||
pub static ID_{{{PATH_ID}}}: usize = {{{index}}};
|
||||
{{#hasPathParams}}
|
||||
lazy_static! {
|
||||
pub static ref REGEX_{{PATH_ID}}: regex::Regex = regex::Regex::new(r"^{{basePathWithoutHost}}{{{pathRegEx}}}").unwrap();
|
||||
pub static ref REGEX_{{{PATH_ID}}}: regex::Regex = regex::Regex::new(r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}").unwrap();
|
||||
}
|
||||
{{/hasPathParams}}
|
||||
{{/pathSet}}
|
||||
@@ -129,7 +129,7 @@ where
|
||||
// Please update both places if changing how this code is autogenerated.
|
||||
match &method {
|
||||
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}
|
||||
// {{operationId}} - {{httpMethod}} {{path}}
|
||||
// {{{operationId}}} - {{{httpMethod}}} {{{path}}}
|
||||
&hyper::Method::{{vendorExtensions.HttpMethod}} if path.matched(paths::ID_{{vendorExtensions.PATH_ID}}) => {
|
||||
{{#hasAuthMethods}}
|
||||
{
|
||||
@@ -146,7 +146,7 @@ where
|
||||
if let Scopes::Some(ref scopes) = authorization.scopes {
|
||||
let required_scopes: BTreeSet<String> = vec![
|
||||
{{#scopes}}
|
||||
"{{scope}}".to_string(), // {{description}}
|
||||
"{{{scope}}}".to_string(), // {{{description}}}
|
||||
{{/scopes}}
|
||||
].into_iter().collect();
|
||||
|
||||
@@ -170,46 +170,46 @@ where
|
||||
// Path parameters
|
||||
let path = uri.path().to_string();
|
||||
let path_params =
|
||||
paths::REGEX_{{PATH_ID}}
|
||||
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())
|
||||
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::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter {{baseName}}: {}", e)))),
|
||||
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::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse path parameter {{{baseName}}}: {}", e)))),
|
||||
},
|
||||
Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{baseName}}"]))))
|
||||
Err(_) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))))
|
||||
};
|
||||
{{/pathParams}}
|
||||
{{#headerParams}}{{#-first}}
|
||||
// Header parameters
|
||||
{{/-first}}
|
||||
header! { (Request{{vendorExtensions.typeName}}, "{{baseName}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
|
||||
header! { (Request{{vendorExtensions.typeName}}, "{{{baseName}}}") => {{#isListContainer}}({{{baseType}}})*{{/isListContainer}}{{^isListContainer}}[{{{dataType}}}]{{/isListContainer}} }
|
||||
{{#required}}
|
||||
let param_{{paramName}} = match headers.get::<Request{{vendorExtensions.typeName}}>() {
|
||||
Some(param_{{paramName}}) => param_{{paramName}}.0.clone(),
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing or invalid required header {{baseName}}"))),
|
||||
let param_{{{paramName}}} = match headers.get::<Request{{vendorExtensions.typeName}}>() {
|
||||
Some(param_{{{paramName}}}) => param_{{{paramName}}}.0.clone(),
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing or invalid required header {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{^required}}
|
||||
let param_{{paramName}} = headers.get::<Request{{vendorExtensions.typeName}}>().map(|header| header.0.clone());
|
||||
let param_{{{paramName}}} = headers.get::<Request{{vendorExtensions.typeName}}>().map(|header| header.0.clone());
|
||||
{{/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())
|
||||
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())
|
||||
.filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok())
|
||||
.collect::<Vec<_>>();
|
||||
{{^required}}
|
||||
let param_{{paramName}} = if !param_{{paramName}}.is_empty() {
|
||||
Some(param_{{paramName}})
|
||||
let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() {
|
||||
Some(param_{{{paramName}}})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -217,15 +217,15 @@ where
|
||||
{{/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::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter {{baseName}} - doesn't match schema: {}", e)))),
|
||||
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::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e)))),
|
||||
},
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter {{baseName}}"))),
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required query parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}{{^required}}
|
||||
let param_{{paramName}} = param_{{paramName}}.and_then(|param_{{paramName}}| param_{{paramName}}.parse::<{{{baseType}}}>().ok());
|
||||
let param_{{{paramName}}} = param_{{{paramName}}}.and_then(|param_{{{paramName}}}| param_{{{paramName}}}.parse::<{{{baseType}}}>().ok());
|
||||
{{/required}}
|
||||
{{/isListContainer}}
|
||||
{{/queryParams}}
|
||||
@@ -241,7 +241,7 @@ where
|
||||
{{#vendorExtensions}}{{^consumesPlainText}}
|
||||
let mut unused_elements = Vec::new();
|
||||
{{/consumesPlainText}}
|
||||
let param_{{paramName}}: Option<{{{dataType}}}> = if !body.is_empty() {
|
||||
let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() {
|
||||
{{#consumesXml}}
|
||||
let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body);
|
||||
{{/consumesXml}}{{#consumesJson}}
|
||||
@@ -251,26 +251,26 @@ where
|
||||
warn!("Ignoring unknown field in body: {}", path);
|
||||
unused_elements.push(path.to_string());
|
||||
}) {
|
||||
Ok(param_{{paramName}}) => param_{{paramName}},
|
||||
Ok(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
{{#required}}
|
||||
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{baseName}} - doesn't match schema: {}", e)))),
|
||||
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e)))),
|
||||
{{/required}}{{^required}}
|
||||
Err(_) => None,
|
||||
{{/required}}
|
||||
}
|
||||
{{/consumesPlainText}}{{#consumesPlainText}}
|
||||
match String::from_utf8(body.to_vec()) {
|
||||
Ok(param_{{paramName}}) => Some(param_{{paramName}}),
|
||||
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{baseName}} - not valid UTF-8: {}", e)))),
|
||||
Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}),
|
||||
Err(e) => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e)))),
|
||||
}
|
||||
{{/consumesPlainText}}{{/vendorExtensions}}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
{{#required}}
|
||||
let param_{{paramName}} = match param_{{paramName}} {
|
||||
Some(param_{{paramName}}) => param_{{paramName}},
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter {{baseName}}"))),
|
||||
let param_{{{paramName}}} = match param_{{{paramName}}} {
|
||||
Some(param_{{{paramName}}}) => param_{{{paramName}}},
|
||||
None => return Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body("Missing required body parameter {{{baseName}}}"))),
|
||||
};
|
||||
{{/required}}
|
||||
{{/-first}}{{/bodyParams}}
|
||||
@@ -280,10 +280,10 @@ where
|
||||
{{#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}}
|
||||
let param_{{{paramName}}} = {{^isContainer}}{{#vendorExtensions}}{{{example}}};{{/vendorExtensions}}{{/isContainer}}{{#isListContainer}}{{#required}}Vec::new();{{/required}}{{^required}}None;{{/required}}{{/isListContainer}}{{#isMapContainer}}None;{{/isMapContainer}}
|
||||
{{/formParams}}
|
||||
{{/vendorExtensions}}{{/bodyParams}}
|
||||
Box::new(api_impl.{{#vendorExtensions}}{{operation_id}}{{/vendorExtensions}}({{#allParams}}param_{{paramName}}{{#isListContainer}}.as_ref(){{/isListContainer}}, {{/allParams}}&context)
|
||||
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();
|
||||
response.headers_mut().set(XSpanId((&context as &Has<XSpanIdString>).get().0.to_string()));
|
||||
@@ -295,7 +295,7 @@ where
|
||||
match result {
|
||||
Ok(rsp) => match rsp {
|
||||
{{#responses}}
|
||||
{{operationId}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{{operationId}}}Response::{{#vendorExtensions}}{{x-responseId}}{{/vendorExtensions}}
|
||||
{{#dataType}}{{^headers}}
|
||||
(body)
|
||||
{{/headers}}{{#headers}}
|
||||
@@ -303,7 +303,7 @@ where
|
||||
{
|
||||
body,
|
||||
{{/-first}}
|
||||
{{name}}{{^-last}}, {{/-last}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
@@ -311,19 +311,19 @@ where
|
||||
{{^dataType}}{{#headers}}{{#-first}}
|
||||
{
|
||||
{{/-first}}
|
||||
{{name}}{{^-last}}, {{/-last}}
|
||||
{{{name}}}{{^-last}}, {{/-last}}
|
||||
{{#-last}}
|
||||
}
|
||||
{{/-last}}
|
||||
{{/headers}}{{/dataType}}
|
||||
=> {
|
||||
response.set_status(StatusCode::try_from({{code}}).unwrap());
|
||||
response.set_status(StatusCode::try_from({{{code}}}).unwrap());
|
||||
{{#headers}}
|
||||
header! { (Response{{nameInCamelCase}}, "{{baseName}}") => [{{{dataType}}}] }
|
||||
response.headers_mut().set(Response{{nameInCamelCase}}({{name}}));
|
||||
header! { (Response{{{nameInCamelCase}}}, "{{{baseName}}}") => [{{{dataType}}}] }
|
||||
response.headers_mut().set(Response{{{nameInCamelCase}}}({{{name}}}));
|
||||
{{/headers}}
|
||||
{{#produces}}{{#-first}}{{#dataType}}
|
||||
response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{uppercase_operation_id}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone()));
|
||||
response.headers_mut().set(ContentType(mimetypes::responses::{{#vendorExtensions}}{{{uppercase_operation_id}}}_{{x-uppercaseResponseId}}{{/vendorExtensions}}.clone()));
|
||||
{{/dataType}}{{/-first}}{{/produces}}
|
||||
{{#dataType}}
|
||||
{{#vendorExtensions}}{{#producesXml}}{{^has_namespace}}
|
||||
@@ -331,7 +331,7 @@ where
|
||||
{{/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(), models::namespaces::{{uppercase_data_type}}.clone());
|
||||
namespaces.insert("".to_string(), models::namespaces::{{{uppercase_data_type}}}.clone());
|
||||
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");
|
||||
@@ -358,7 +358,7 @@ where
|
||||
{{/vendorExtensions}}{{/bodyParams}}
|
||||
{{#bodyParams}}{{#-first}}
|
||||
},
|
||||
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{baseName}}: {}", e)))),
|
||||
Err(e) => Box::new(future::ok(Response::new().with_status(StatusCode::BadRequest).with_body(format!("Couldn't read body parameter {{{baseName}}}: {}", e)))),
|
||||
}
|
||||
})
|
||||
) as Box<Future<Item=Response, Error=Error>>
|
||||
|
||||
@@ -37,6 +37,6 @@ if (String.valueOf(b.value).equals(text)) {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
{{#useNullForUnknownEnumValue}}return null;{{/useNullForUnknownEnumValue}}{{^useNullForUnknownEnumValue}}throw new IllegalArgumentException("Unexpected value '" + text + "'");{{/useNullForUnknownEnumValue}}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ public class AbstractJavaCodegenTest {
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "org.openapitools");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "org.openapitools");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.BOOLEAN_GETTER_PREFIX), "get");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.USE_NULL_FOR_UNKNOWN_ENUM_VALUE), Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,6 +109,7 @@ public class AbstractJavaCodegenTest {
|
||||
codegen.setApiPackage("xyz.yyyyy.zzzzzzz.api");
|
||||
codegen.setInvokerPackage("xyz.yyyyy.zzzzzzz.invoker");
|
||||
codegen.setBooleanGetterPrefix("is");
|
||||
codegen.setUseNullForUnknownEnumValue(true);
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.TRUE);
|
||||
@@ -119,6 +121,7 @@ public class AbstractJavaCodegenTest {
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "xyz.yyyyy.zzzzzzz.invoker");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.zzzzzzz.invoker");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.BOOLEAN_GETTER_PREFIX), "is");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.USE_NULL_FOR_UNKNOWN_ENUM_VALUE), Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,6 +132,7 @@ public class AbstractJavaCodegenTest {
|
||||
codegen.additionalProperties().put(CodegenConstants.API_PACKAGE, "xyz.yyyyy.api.oooooo");
|
||||
codegen.additionalProperties().put(CodegenConstants.INVOKER_PACKAGE, "xyz.yyyyy.invoker.oooooo");
|
||||
codegen.additionalProperties().put(AbstractJavaCodegen.BOOLEAN_GETTER_PREFIX, "getBoolean");
|
||||
codegen.additionalProperties().put(AbstractJavaCodegen.USE_NULL_FOR_UNKNOWN_ENUM_VALUE, "true");
|
||||
codegen.processOpts();
|
||||
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP), Boolean.FALSE);
|
||||
@@ -140,6 +144,7 @@ public class AbstractJavaCodegenTest {
|
||||
Assert.assertEquals(codegen.getInvokerPackage(), "xyz.yyyyy.invoker.oooooo");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.invoker.oooooo");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.BOOLEAN_GETTER_PREFIX), "getBoolean");
|
||||
Assert.assertEquals(codegen.additionalProperties().get(AbstractJavaCodegen.USE_NULL_FOR_UNKNOWN_ENUM_VALUE), Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.openapitools.codegen.php;
|
||||
|
||||
import org.openapitools.codegen.CodegenOperation;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -24,6 +25,9 @@ import org.openapitools.codegen.CodegenConstants;
|
||||
import org.openapitools.codegen.CodegenType;
|
||||
import org.openapitools.codegen.languages.AbstractPhpCodegen;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class AbstractPhpCodegenTest {
|
||||
|
||||
@Test
|
||||
@@ -79,6 +83,24 @@ public class AbstractPhpCodegenTest {
|
||||
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "PHPinvoker");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeMediaType() throws Exception {
|
||||
HashMap<String, String> all = new HashMap<>();
|
||||
all.put("mediaType", "*/*");
|
||||
HashMap<String, String> applicationJson = new HashMap<>();
|
||||
applicationJson.put("mediaType", "application/json");
|
||||
|
||||
CodegenOperation codegenOperation = new CodegenOperation();
|
||||
codegenOperation.hasProduces = true;
|
||||
codegenOperation.produces = Arrays.asList(all, applicationJson);
|
||||
|
||||
final AbstractPhpCodegen codegen = new P_AbstractPhpCodegen();
|
||||
codegen.escapeMediaType(Arrays.asList(codegenOperation));
|
||||
|
||||
Assert.assertEquals(codegenOperation.produces.get(0).get("mediaType"), "*_/_*");
|
||||
Assert.assertEquals(codegenOperation.produces.get(1).get("mediaType"), "application/json");
|
||||
}
|
||||
|
||||
private static class P_AbstractPhpCodegen extends AbstractPhpCodegen {
|
||||
@Override
|
||||
public CodegenType getTag() {
|
||||
|
||||
@@ -59,7 +59,7 @@ public class EnumArrays {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class EnumArrays {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public enum EnumClass {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public class MapTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Order {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public enum OuterEnum {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class Pet {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ public class EnumArrays {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ public class EnumArrays {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public enum EnumClass {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ public class EnumTest {
|
||||
return b;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
throw new IllegalArgumentException("Unexpected value '" + text + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user