diff --git a/.github/workflows/samples-rust.yaml b/.github/workflows/samples-rust.yaml index 832ddf3e7e6a..b46265ca16a6 100644 --- a/.github/workflows/samples-rust.yaml +++ b/.github/workflows/samples-rust.yaml @@ -26,12 +26,54 @@ jobs: - samples/client/others/rust/ - samples/client/petstore/rust/ - samples/server/petstore/rust-server/ + - samples/server/petstore/rust-server-deprecated/ - samples/server/petstore/rust-axum/ steps: - uses: actions/checkout@v4 - uses: actions-rs/toolchain@v1 with: toolchain: stable + + - name: Rust cache + uses: Swatinem/rust-cache@v2 + with: + cache-targets: false # Don't cache workspace target directories as they don't exist + cache-directories: + ${{ matrix.sample }}/target + workspaces: | + ${{ matrix.sample }}/output/* + - name: Build working-directory: ${{ matrix.sample }} run: cargo build --all-targets --all-features + - name: Tests + working-directory: ${{ matrix.sample }} + run: | + set -e + # Skip samples/client/petstore/rust/ as it's tests are failing. + if [[ "${{ matrix.sample }}" == "samples/client/petstore/rust/" ]]; then + echo "Skipping tests for samples/client/petstore/rust/" + exit 0 + fi + + # Iterate through each example and test various features + for package in $(find . -maxdepth 1 -mindepth 1 -type d) + do + # Not all versions have a client example + if test -f examples/client/main.rs; then + cargo build --example client --features="client" + fi + # Not all versions have a server example + if test -f examples/server/main.rs; then + cargo build --example server --features="server" + fi + # Test the CLI works if present + if test -f bin/cli.rs; then + cargo build --bin ${package##*/} --features cli + target/debug/${package##*/} --help + fi + cargo fmt + cargo test + cargo clippy + cargo doc + done diff --git a/bin/configs/rust-server-deprecated-multipart-v3.yaml b/bin/configs/rust-server-deprecated-multipart-v3.yaml new file mode 100644 index 000000000000..e014bc087895 --- /dev/null +++ b/bin/configs/rust-server-deprecated-multipart-v3.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/multipart-v3 +inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-server/multipart-v3.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: multipart-v3 diff --git a/bin/configs/rust-server-deprecated-no-example-v3.yaml b/bin/configs/rust-server-deprecated-no-example-v3.yaml new file mode 100644 index 000000000000..df0e2c2271ae --- /dev/null +++ b/bin/configs/rust-server-deprecated-no-example-v3.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/no-example-v3 +inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-server/no-example-v3.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: no-example-v3 diff --git a/bin/configs/rust-server-deprecated-openapi-v3.yaml b/bin/configs/rust-server-deprecated-openapi-v3.yaml new file mode 100644 index 000000000000..f4fc0e28ed8c --- /dev/null +++ b/bin/configs/rust-server-deprecated-openapi-v3.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/openapi-v3 +inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: openapi-v3 diff --git a/bin/configs/rust-server-deprecated-ops-v3.yaml b/bin/configs/rust-server-deprecated-ops-v3.yaml new file mode 100644 index 000000000000..471bb16e0c94 --- /dev/null +++ b/bin/configs/rust-server-deprecated-ops-v3.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/ops-v3 +inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-server/ops-v3.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: ops-v3 diff --git a/bin/configs/rust-server-deprecated-petstore-with-fake-endpoints-models-for-testing.yaml b/bin/configs/rust-server-deprecated-petstore-with-fake-endpoints-models-for-testing.yaml new file mode 100644 index 000000000000..0a88b74392b3 --- /dev/null +++ b/bin/configs/rust-server-deprecated-petstore-with-fake-endpoints-models-for-testing.yaml @@ -0,0 +1,9 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing +inputSpec: modules/openapi-generator/src/test/resources/2_0/rust-server/petstore-with-fake-endpoints-models-for-testing.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: petstore-with-fake-endpoints-models-for-testing + publishRustRegistry: crates-io diff --git a/bin/configs/rust-server-deprecated-ping-bearer-auth-v3.yaml b/bin/configs/rust-server-deprecated-ping-bearer-auth-v3.yaml new file mode 100644 index 000000000000..fb4dcf78258f --- /dev/null +++ b/bin/configs/rust-server-deprecated-ping-bearer-auth-v3.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth +inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-server/ping-bearer-auth.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: ping-bearer-auth diff --git a/bin/configs/rust-server-deprecated-test.yaml b/bin/configs/rust-server-deprecated-test.yaml new file mode 100644 index 000000000000..bcda8dfb0161 --- /dev/null +++ b/bin/configs/rust-server-deprecated-test.yaml @@ -0,0 +1,8 @@ +generatorName: rust-server-deprecated +outputDir: samples/server/petstore/rust-server-deprecated/output/rust-server-test +inputSpec: modules/openapi-generator/src/test/resources/2_0/rust-server/rust-server-test.yaml +templateDir: modules/openapi-generator/src/main/resources/rust-server-deprecated +generateAliasAsModel: true +additionalProperties: + hideGenerationTimestamp: "true" + packageName: rust-server-test diff --git a/docs/generators.md b/docs/generators.md index c74dfe531722..4c968c0f87a0 100644 --- a/docs/generators.md +++ b/docs/generators.md @@ -142,6 +142,7 @@ The following generators are available: * [ruby-sinatra](generators/ruby-sinatra.md) * [rust-axum (beta)](generators/rust-axum.md) * [rust-server](generators/rust-server.md) +* [rust-server-deprecated](generators/rust-server-deprecated.md) * [scala-akka-http-server (beta)](generators/scala-akka-http-server.md) * [scala-cask](generators/scala-cask.md) * [scala-finch](generators/scala-finch.md) diff --git a/docs/generators/rust-server-deprecated.md b/docs/generators/rust-server-deprecated.md new file mode 100644 index 000000000000..1aca84f8e75d --- /dev/null +++ b/docs/generators/rust-server-deprecated.md @@ -0,0 +1,232 @@ +--- +title: Documentation for the rust-server-deprecated Generator +--- + +## METADATA + +| Property | Value | Notes | +| -------- | ----- | ----- | +| generator name | rust-server-deprecated | pass this to the generate command after -g | +| generator stability | STABLE | | +| generator type | SERVER | | +| generator language | Rust | | +| generator default templating engine | mustache | | +| helpTxt | Generates a Rust Hyper/Tower server library based on hyper 0.14. Also generates a matching Hyper client library within the same crate that implements the same trait. | | + +## CONFIG OPTIONS +These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details. + +| Option | Description | Values | Default | +| ------ | ----------- | ------ | ------- | +|packageName|Rust crate name (convention: snake_case).| |openapi_client| +|packageVersion|Rust crate version.| |null| + +## IMPORT MAPPING + +| Type/Alias | Imports | +| ---------- | ------- | + + +## INSTANTIATION TYPES + +| Type/Alias | Instantiated By | +| ---------- | --------------- | +|array|Vec| +|map|std::collections::HashMap| + + +## LANGUAGE PRIMITIVES + + + +## RESERVED WORDS + + + +## FEATURE SET + + +### Client Modification Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasePath|✓|ToolingExtension +|Authorizations|✗|ToolingExtension +|UserAgent|✗|ToolingExtension +|MockServer|✗|ToolingExtension + +### Data Type Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Custom|✗|OAS2,OAS3 +|Int32|✓|OAS2,OAS3 +|Int64|✓|OAS2,OAS3 +|Float|✓|OAS2,OAS3 +|Double|✓|OAS2,OAS3 +|Decimal|✓|ToolingExtension +|String|✓|OAS2,OAS3 +|Byte|✓|OAS2,OAS3 +|Binary|✓|OAS2,OAS3 +|Boolean|✓|OAS2,OAS3 +|Date|✓|OAS2,OAS3 +|DateTime|✓|OAS2,OAS3 +|Password|✓|OAS2,OAS3 +|File|✓|OAS2 +|Uuid|✗| +|Array|✓|OAS2,OAS3 +|Null|✗|OAS3 +|AnyType|✗|OAS2,OAS3 +|Object|✓|OAS2,OAS3 +|Maps|✓|ToolingExtension +|CollectionFormat|✓|OAS2 +|CollectionFormatMulti|✓|OAS2 +|Enum|✓|OAS2,OAS3 +|ArrayOfEnum|✓|ToolingExtension +|ArrayOfModel|✓|ToolingExtension +|ArrayOfCollectionOfPrimitives|✓|ToolingExtension +|ArrayOfCollectionOfModel|✓|ToolingExtension +|ArrayOfCollectionOfEnum|✓|ToolingExtension +|MapOfEnum|✓|ToolingExtension +|MapOfModel|✓|ToolingExtension +|MapOfCollectionOfPrimitives|✓|ToolingExtension +|MapOfCollectionOfModel|✓|ToolingExtension +|MapOfCollectionOfEnum|✓|ToolingExtension + +### Documentation Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Readme|✓|ToolingExtension +|Model|✓|ToolingExtension +|Api|✓|ToolingExtension + +### Global Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Host|✓|OAS2,OAS3 +|BasePath|✓|OAS2,OAS3 +|Info|✓|OAS2,OAS3 +|Schemes|✗|OAS2,OAS3 +|PartialSchemes|✓|OAS2,OAS3 +|Consumes|✓|OAS2 +|Produces|✓|OAS2 +|ExternalDocumentation|✓|OAS2,OAS3 +|Examples|✓|OAS2,OAS3 +|XMLStructureDefinitions|✗|OAS2,OAS3 +|MultiServer|✗|OAS3 +|ParameterizedServer|✗|OAS3 +|ParameterStyling|✗|OAS3 +|Callbacks|✓|OAS3 +|LinkObjects|✗|OAS3 + +### Parameter Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Path|✓|OAS2,OAS3 +|Query|✓|OAS2,OAS3 +|Header|✓|OAS2,OAS3 +|Body|✓|OAS2 +|FormUnencoded|✓|OAS2 +|FormMultipart|✓|OAS2 +|Cookie|✗|OAS3 + +### Schema Support Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|Simple|✓|OAS2,OAS3 +|Composite|✓|OAS2,OAS3 +|Polymorphism|✗|OAS2,OAS3 +|Union|✗|OAS3 +|allOf|✗|OAS2,OAS3 +|anyOf|✗|OAS3 +|oneOf|✗|OAS3 +|not|✗|OAS3 + +### Security Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|BasicAuth|✓|OAS2,OAS3 +|ApiKey|✓|OAS2,OAS3 +|OpenIDConnect|✗|OAS3 +|BearerToken|✓|OAS3 +|OAuth2_Implicit|✓|OAS2,OAS3 +|OAuth2_Password|✗|OAS2,OAS3 +|OAuth2_ClientCredentials|✗|OAS2,OAS3 +|OAuth2_AuthorizationCode|✗|OAS2,OAS3 +|SignatureAuth|✗|OAS3 +|AWSV4Signature|✗|ToolingExtension + +### Wire Format Feature +| Name | Supported | Defined By | +| ---- | --------- | ---------- | +|JSON|✓|OAS2,OAS3 +|XML|✓|OAS2,OAS3 +|PROTOBUF|✗|ToolingExtension +|Custom|✓|OAS2,OAS3 diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 33918bed8462..2a4f74bf7d7d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -54,6 +54,7 @@ import org.openapitools.codegen.languages.PhpNextgenClientCodegen; import org.openapitools.codegen.languages.RustAxumServerCodegen; import org.openapitools.codegen.languages.RustServerCodegen; +import org.openapitools.codegen.languages.RustServerCodegenDeprecated; import org.openapitools.codegen.meta.FeatureSet; import org.openapitools.codegen.meta.GeneratorMetadata; import org.openapitools.codegen.meta.Stability; @@ -5328,7 +5329,7 @@ public CodegenParameter fromParameter(Parameter parameter, Set imports) parameterSchema = unaliasSchema(parameter.getSchema()); parameterModelName = getParameterDataType(parameter, parameterSchema); CodegenProperty prop; - if (this instanceof RustServerCodegen) { + if (this instanceof RustServerCodegen || this instanceof RustServerCodegenDeprecated) { // for rust server, we need to do something special as it uses // $ref (e.g. #components/schemas/Pet) to determine whether it's a model prop = fromProperty(parameter.getName(), parameterSchema, false); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java index ec9b3de2340a..54112fcc5e1d 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegen.java @@ -46,6 +46,7 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static org.openapitools.codegen.utils.StringUtils.camelize; import static org.openapitools.codegen.utils.StringUtils.underscore; @@ -222,7 +223,7 @@ public RustServerCodegen() { */ supportingFiles.add(new SupportingFile("openapi.mustache", "api", "openapi.yaml")); supportingFiles.add(new SupportingFile("Cargo.mustache", "", "Cargo.toml")); - supportingFiles.add(new SupportingFile("cargo-config", ".cargo", "config")); + supportingFiles.add(new SupportingFile("cargo-config", ".cargo", "config.toml")); supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs")); supportingFiles.add(new SupportingFile("context.mustache", "src", "context.rs")); @@ -1531,7 +1532,16 @@ private void processParam(CodegenParameter param, CodegenOperation op) { } } else if (param.isArray) { param.vendorExtensions.put("x-format-string", "{:?}"); - example = (param.example != null) ? param.example : "&Vec::new()"; + if (param.items.isString) { + // We iterate through the list of string and ensure they end up in the format vec!["example".to_string()] + example = (param.example != null) + ? "&vec![" + Arrays.stream(param.example.replace("[", "").replace("]", "").split(",")) + .map(item -> item + ".to_string()") + .collect(Collectors.joining(", ")) + "]" + : "&Vec::new()"; + } else { + example = (param.example != null) ? param.example : "&Vec::new()"; + } } else { param.vendorExtensions.put("x-format-string", "{:?}"); if (param.example != null) { diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegenDeprecated.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegenDeprecated.java new file mode 100644 index 000000000000..7297b8b4de41 --- /dev/null +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustServerCodegenDeprecated.java @@ -0,0 +1,1658 @@ +/* + * 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 + * + * https://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 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.*; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; +import joptsimple.internal.Strings; +import lombok.Setter; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.openapitools.codegen.*; +import org.openapitools.codegen.meta.features.*; +import org.openapitools.codegen.model.*; +import org.openapitools.codegen.utils.ModelUtils; +import org.openapitools.codegen.utils.URLPathUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.math.BigInteger; +import java.net.URL; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.openapitools.codegen.utils.StringUtils.camelize; +import static org.openapitools.codegen.utils.StringUtils.underscore; + +public class RustServerCodegenDeprecated extends AbstractRustCodegen implements CodegenConfig { + + private final Logger LOGGER = LoggerFactory.getLogger(RustServerCodegenDeprecated.class); + + private Map modelXmlNames = new HashMap(); + + protected String apiVersion = "1.0.0"; + protected String serverHost = "localhost"; + protected int serverPort = 8080; + protected String projectName = "openapi-server"; + protected String apiPath = "rust-server"; + protected String apiDocPath = "docs/"; + protected String modelDocPath = "docs/"; + protected String packageName; + @Setter protected String packageVersion; + protected String externCrateName; + protected Map> pathSetMap = new HashMap(); + protected Map> callbacksPathSetMap = new HashMap(); + + private static final String uuidType = "uuid::Uuid"; + private static final String bytesType = "swagger::ByteArray"; + + private static final String xmlMimeType = "application/xml"; + private static final String textXmlMimeType = "text/xml"; + private static final String octetMimeType = "application/octet-stream"; + private static final String plainTextMimeType = "text/plain"; + private static final String jsonMimeType = "application/json"; + + // RFC 7386 support + private static final String mergePatchJsonMimeType = "application/merge-patch+json"; + + // RFC 7807 Support + private static final String problemJsonMimeType = "application/problem+json"; + private static final String problemXmlMimeType = "application/problem+xml"; + + public RustServerCodegenDeprecated() { + super(); + + modifyFeatureSet(features -> features + .includeDocumentationFeatures(DocumentationFeature.Readme) + .wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON, WireFormatFeature.XML, WireFormatFeature.Custom)) + .securityFeatures(EnumSet.of( + SecurityFeature.ApiKey, + SecurityFeature.BasicAuth, + SecurityFeature.BearerToken, + SecurityFeature.OAuth2_Implicit + )) + .excludeGlobalFeatures( + GlobalFeature.LinkObjects, + GlobalFeature.ParameterStyling + ) + .excludeSchemaSupportFeatures( + SchemaSupportFeature.Polymorphism + ) + .excludeParameterFeatures( + ParameterFeature.Cookie + ) + .includeClientModificationFeatures( + ClientModificationFeature.BasePath + ) + ); + + // We need inline enums to be resolved to a separate model so that + // anyOf/oneOf that contain them work correctly. + inlineSchemaOption.put("RESOLVE_INLINE_ENUMS", "true"); + + // Show the generation timestamp by default + hideGenerationTimestamp = Boolean.FALSE; + + // set the output folder here + outputFolder = "generated-code/rust-server"; + + /* + * 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.clear(); + + /* + * 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.clear(); + + modelDocTemplateFiles.put("model_doc.mustache", ".md"); + apiDocTemplateFiles.put("api_doc.mustache", ".md"); + + /* + * 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 = "rust-server"; + + defaultIncludes = new HashSet<>( + Arrays.asList( + "map", + "array") + ); + + languageSpecificPrimitives = new HashSet<>( + Arrays.asList( + "bool", + "char", + "i8", + "i16", + "i32", + "i64", + "u8", + "u16", + "u32", + "u64", + "isize", + "usize", + "f32", + "f64", + "str", + "String") + ); + + instantiationTypes.clear(); + instantiationTypes.put("array", "Vec"); + instantiationTypes.put("map", "std::collections::HashMap"); + + typeMapping.clear(); + typeMapping.put("number", "f64"); + typeMapping.put("integer", "i32"); + typeMapping.put("long", "i64"); + typeMapping.put("float", "f32"); + typeMapping.put("double", "f64"); + typeMapping.put("string", "String"); + typeMapping.put("UUID", uuidType); + typeMapping.put("URI", "String"); + typeMapping.put("byte", "u8"); + typeMapping.put("ByteArray", bytesType); + typeMapping.put("binary", bytesType); + typeMapping.put("boolean", "bool"); + typeMapping.put("date", "chrono::naive::NaiveDate"); + typeMapping.put("DateTime", "chrono::DateTime::"); + typeMapping.put("password", "String"); + typeMapping.put("File", bytesType); + typeMapping.put("file", bytesType); + typeMapping.put("array", "Vec"); + typeMapping.put("map", "std::collections::HashMap"); + typeMapping.put("object", "serde_json::Value"); + typeMapping.put("AnyType", "serde_json::Value"); + + importMapping = new HashMap(); + + cliOptions.clear(); + cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, + "Rust crate name (convention: snake_case).") + .defaultValue("openapi_client")); + cliOptions.add(new CliOption(CodegenConstants.PACKAGE_VERSION, + "Rust crate version.")); + + /* + * 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("apiPath", apiPath); + + /* + * Supporting Files. You can write single files for the generator with the + * entire object tree available. If the input file has a suffix of `.mustache + * it will be processed by the template engine. Otherwise, it will be copied + */ + supportingFiles.add(new SupportingFile("openapi.mustache", "api", "openapi.yaml")); + supportingFiles.add(new SupportingFile("Cargo.mustache", "", "Cargo.toml")); + supportingFiles.add(new SupportingFile("cargo-config", ".cargo", "config")); + supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore")); + supportingFiles.add(new SupportingFile("lib.mustache", "src", "lib.rs")); + supportingFiles.add(new SupportingFile("context.mustache", "src", "context.rs")); + supportingFiles.add(new SupportingFile("models.mustache", "src", "models.rs")); + supportingFiles.add(new SupportingFile("header.mustache", "src", "header.rs")); + supportingFiles.add(new SupportingFile("auth.mustache", "src", "auth.rs")); + supportingFiles.add(new SupportingFile("server-mod.mustache", "src/server", "mod.rs")); + supportingFiles.add(new SupportingFile("server-server_auth.mustache", "src/server", "server_auth.rs")); + supportingFiles.add(new SupportingFile("client-mod.mustache", "src/client", "mod.rs")); + supportingFiles.add(new SupportingFile("example-server-main.mustache", "examples/server", "main.rs")); + supportingFiles.add(new SupportingFile("example-server-server.mustache", "examples/server", "server.rs")); + supportingFiles.add(new SupportingFile("example-server-auth.mustache", "examples/server", "server_auth.rs")); + supportingFiles.add(new SupportingFile("example-client-main.mustache", "examples/client", "main.rs")); + supportingFiles.add(new SupportingFile("example-client-auth.mustache", "examples/client", "client_auth.rs")); + supportingFiles.add(new SupportingFile("example-ca.pem", "examples", "ca.pem")); + supportingFiles.add(new SupportingFile("example-server-chain.pem", "examples", "server-chain.pem")); + supportingFiles.add(new SupportingFile("example-server-key.pem", "examples", "server-key.pem")); + supportingFiles.add(new SupportingFile("bin-cli.mustache", "bin", "cli.rs")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md") + .doNotOverwrite()); + } + + @Override + public void processOpts() { + super.processOpts(); + + if (StringUtils.isEmpty(System.getenv("RUST_POST_PROCESS_FILE"))) { + LOGGER.info("Environment variable RUST_POST_PROCESS_FILE not defined. rustfmt will be used" + + " by default. To choose a different tool, try" + + " 'export RUST_POST_PROCESS_FILE=\"/usr/local/bin/rustfmt\"' (Linux/Mac)"); + LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` " + + " (--enable-post-process-file for CLI)."); + } else if (!this.isEnablePostProcessFile()) { + LOGGER.info("Warning: Environment variable 'RUST_POST_PROCESS_FILE' is set but file post-processing is not enabled. To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); + } + + if (!Boolean.TRUE.equals(ModelUtils.isGenerateAliasAsModel())) { + LOGGER.warn("generateAliasAsModel is set to false, which means array/map will be generated as model instead and the resulting code may have issues. Please enable `generateAliasAsModel` to address the issue."); + } + + setPackageName((String) additionalProperties.getOrDefault(CodegenConstants.PACKAGE_NAME, "openapi_client")); + + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) { + setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION)); + } + + additionalProperties.put("apiDocPath", apiDocPath); + additionalProperties.put("modelDocPath", modelDocPath); + + additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName); + additionalProperties.put("externCrateName", externCrateName); + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + + // Also set the extern crate name, which has any '-' replace with a '_'. + this.externCrateName = packageName.replace('-', '_'); + } + + @Override + public String apiPackage() { + return apiPath; + } + + /** + * 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 "rust-server-deprecated"; + } + + /** + * 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 Rust Hyper/Tower server library based on hyper 0.14. Also generates a matching Hyper client library within " + + "the same crate that implements the same trait."; + } + + @Override + public void preprocessOpenAPI(OpenAPI openAPI) { + + Info info = openAPI.getInfo(); + + URL url = URLPathUtils.getServerURL(openAPI, serverVariableOverrides()); + additionalProperties.put("serverHost", url.getHost()); + additionalProperties.put("serverPort", URLPathUtils.getPort(url, serverPort)); + + if (packageVersion == null || packageVersion.isEmpty()) { + List versionComponents = new ArrayList<>(Arrays.asList(info.getVersion().split("[.]"))); + if (versionComponents.size() < 1) { + versionComponents.add("1"); + } + while (versionComponents.size() < 3) { + versionComponents.add("0"); + } + + setPackageVersion(StringUtils.join(versionComponents, ".")); + } + + additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion); + } + + @Override + public String toApiName(String name) { + if (name.isEmpty()) { + return "default"; + } + return sanitizeIdentifier(name, CasingType.SNAKE_CASE, "api", "API", true); + } + + /** + * Location to write api files. You can use the apiPackage() as defined when the class is + * instantiated + */ + @Override + public String apiFileFolder() { + return outputFolder + File.separator + apiPackage().replace('.', File.separatorChar); + } + + @Override + public String toOperationId(String operationId) { + // rust-server uses camel case instead + return sanitizeIdentifier(operationId, CasingType.CAMEL_CASE, "call", "method", true); + } + + @Override + public String toEnumValue(String value, String datatype) { + // rust-server templates expect value to be in quotes + return "\"" + super.toEnumValue(value, datatype) + "\""; + } + + @Override + public String apiDocFileFolder() { + return (outputFolder + "/" + apiDocPath).replace('/', File.separatorChar); + } + + @Override + public String modelDocFileFolder() { + return (outputFolder + "/" + modelDocPath).replace('/', File.separatorChar); + } + + @Override + public String toApiDocFilename(String name) { + return toApiName(name) + "_api"; + } + + private boolean isMimetypeXml(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith(xmlMimeType) || + mimetype.toLowerCase(Locale.ROOT).startsWith(problemXmlMimeType) || + mimetype.toLowerCase(Locale.ROOT).startsWith(textXmlMimeType); + } + + private boolean isMimetypeJson(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith(jsonMimeType) || + mimetype.toLowerCase(Locale.ROOT).startsWith(mergePatchJsonMimeType) || + mimetype.toLowerCase(Locale.ROOT).startsWith(problemJsonMimeType); + } + + private boolean isMimetypeWwwFormUrlEncoded(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith("application/x-www-form-urlencoded"); + } + + private boolean isMimetypeMultipartFormData(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith("multipart/form-data"); + } + + private boolean isMimetypeOctetStream(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith(octetMimeType); + } + + private boolean isMimetypeMultipartRelated(String mimetype) { + return mimetype.toLowerCase(Locale.ROOT).startsWith("multipart/related"); + } + + private boolean isMimetypeUnknown(String mimetype) { + return "*/*".equals(mimetype); + } + + /** + * Do we have any special handling for this mimetype? + */ + boolean isMimetypePlain(String mimetype) { + boolean result = !(isMimetypeUnknown(mimetype) || + isMimetypeXml(mimetype) || + isMimetypeJson(mimetype) || + isMimetypeWwwFormUrlEncoded(mimetype) || + isMimetypeMultipartFormData(mimetype) || + isMimetypeMultipartRelated(mimetype)); + return result; + } + + private String tidyUpRuntimeCallbackParam(String param) { + return underscore(param.replace("-", "_").replace(".", "_").replace("{", "").replace("#", "_").replace("/", "_").replace("}", "").replace("$", "").replaceAll("_+", "_")); + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List servers) { + Map definitions = ModelUtils.getSchemas(this.openAPI); + CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); + + String pathFormatString = op.path; + for (CodegenParameter param : op.pathParams) { + // Replace {baseName} with {paramName} for format string + String paramSearch = "{" + param.baseName + "}"; + String paramReplace = "{" + param.paramName + "}"; + + pathFormatString = pathFormatString.replace(paramSearch, paramReplace); + } + op.vendorExtensions.put("x-path-format-string", pathFormatString); + + // The Rust code will need to contain a series of regular expressions. + // For performance, we'll construct these at start-of-day and re-use + // them. That means we need labels for them. + // + // Construct a Rust constant (uppercase) token name, and ensure it's + // unique using a numeric tie-breaker if required. + String basePathId = sanitizeName(op.path.replace("/", "_").replace("{", "").replace("}", "").replaceAll("^_", "")).toUpperCase(Locale.ROOT); + String pathId = basePathId; + int pathIdTiebreaker = 2; + boolean found = false; + + Map> pathSetMap; + + // The callback API is logically distinct from the main API, so + // it uses a separate path set map. + if (op.isCallbackRequest) { + pathSetMap = this.callbacksPathSetMap; + } else { + pathSetMap = this.pathSetMap; + } + + while (pathSetMap.containsKey(pathId)) { + Map pathSetEntry = pathSetMap.get(pathId); + if (pathSetEntry.get("path").equals(op.path)) { + found = true; + break; + } + pathId = basePathId + pathIdTiebreaker; + pathIdTiebreaker++; + } + + boolean hasPathParams = !op.pathParams.isEmpty(); + + // String for matching for path using a regex + // Don't prefix with '^' so that the templates can put the + // basePath on the front. + String regex = op.path; + // String for formatting the path for a client to make a request + String formatPath = op.path; + + for (CodegenParameter param : op.pathParams) { + // Replace {baseName} with {paramName} for format string + String paramSearch = "{" + param.baseName + "}"; + String paramReplace = "{" + param.paramName + "}"; + + formatPath = formatPath.replace(paramSearch, paramReplace); + } + + // Handle runtime callback parameters. Runtime callback parameters + // are different from regular path parameters: + // - They begin with a "{$" sequence, which allows us to identify them. + // - They can contain multiple path segments, so we need to use a different + // regular expression. + // - They may contain special characters such as "#", "." and "/" which aren't + // valid in Rust identifiers. + // In the future, we may support parsing them directly + if (op.isCallbackRequest) { + formatPath = formatPath.substring(1); // Callback paths are absolute so strip initial '/' + + List params = new ArrayList(); + + Matcher match = Pattern.compile("\\{\\$[^}{]*\\}").matcher(op.path); + + while (match.find()) { + String param = match.group(); + + // Convert to a rust variable name + String rustParam = tidyUpRuntimeCallbackParam(param); + params.add(rustParam); + + // Convert to a format arg + String formatParam = "{" + rustParam + "}"; + + formatPath = formatPath.replace(param, formatParam); + + // Convert to a regex + String newParam = "(?P<" + rustParam + ">.*)"; + + regex = regex.replace(param, newParam); + + hasPathParams = true; + } + + op.vendorExtensions.put("x-callback-params", params); + } + + // Save off the regular expression and path details in the relevant + // "pathSetMap", which we'll add to the source document that will be + // processed by the templates. + if (!found) { + Map pathSetEntry = new HashMap(); + pathSetEntry.put("path", op.path); + pathSetEntry.put("PATH_ID", pathId); + + if (hasPathParams) { + pathSetEntry.put("hasPathParams", "true"); + } + + // Don't prefix with '^' so that the templates can put the + // basePath on the front. + for (CodegenParameter param : op.pathParams) { + // Replace {baseName} with (?P[^/?#]*) for regex + // TODO: Sanitize baseName to avoid using '-' (see clippy::invalid_regex) + String paramSearch = "{" + param.baseName + "}"; + String paramReplace = "(?P<" + param.baseName + ">[^/?#]*)"; + + regex = regex.replace(paramSearch, paramReplace); + } + + pathSetEntry.put("pathRegEx", regex + "$"); + pathSetMap.put(pathId, pathSetEntry); + } + + String underscoredOperationId = underscore(op.operationId); + op.vendorExtensions.put("x-operation-id", underscoredOperationId); + op.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId.toUpperCase(Locale.ROOT)); + String vendorExtensionPath = op.path.replace("{", ":").replace("}", ""); + op.vendorExtensions.put("x-path", vendorExtensionPath); + op.vendorExtensions.put("x-path-id", pathId); + op.vendorExtensions.put("x-has-path-params", hasPathParams); + op.vendorExtensions.put("x-path-format-string", formatPath); + + String vendorExtensionHttpMethod = op.httpMethod.toUpperCase(Locale.ROOT); + op.vendorExtensions.put("x-http-method", vendorExtensionHttpMethod); + + boolean isDelete = op.httpMethod.toUpperCase(Locale.ROOT).equals("DELETE"); + op.vendorExtensions.put("x-is-delete", isDelete); + + if (isDelete) { + additionalProperties.put("apiHasDeleteMethods", true); + } + + if (!op.vendorExtensions.containsKey("x-must-use-response")) { + // If there's more than one response, than by default the user must explicitly handle them + op.vendorExtensions.put("x-must-use-response", op.responses.size() > 1); + } + + for (CodegenParameter param : op.allParams) { + processParam(param, op); + } + + // We keep track of the 'default' model type for this API. If there are + // *any* XML responses, then we set the default to XML, otherwise we + // let the default be JSON. It would be odd for an API to want to use + // both XML and JSON on a single operation, and if we don't know + // anything then JSON is a more modern (ergo reasonable) choice. + boolean defaultsToXml = false; + + // Determine the types that this operation produces. `getProducesInfo` + // simply lists all the types, and then we add the correct imports to + // the generated library. + List produces = new ArrayList(getProducesInfo(openAPI, operation)); + boolean producesXml = false; + boolean producesPlainText = false; + if (produces != null && !produces.isEmpty()) { + List> c = new ArrayList>(); + for (String mimeType : produces) { + Map mediaType = new HashMap(); + + if (isMimetypeXml(mimeType)) { + additionalProperties.put("usesXml", true); + defaultsToXml = true; + producesXml = true; + } else if (isMimetypePlain(mimeType)) { + producesPlainText = true; + } + + mediaType.put("mediaType", mimeType); + c.add(mediaType); + } + op.produces = c; + op.hasProduces = true; + } + + for (CodegenParameter param : op.headerParams) { + processParam(param, op); + + // Give header params a name in camel case. CodegenParameters don't have a nameInCamelCase property. + param.vendorExtensions.put("x-type-name", toModelName(param.baseName)); + } + + // Set for deduplication of response IDs + Set responseIds = new HashSet(); + + for (CodegenResponse rsp : op.responses) { + + // Get the original API response so we get process the schema + // directly. + ApiResponse original; + if ("0".equals(rsp.code)) { + original = operation.getResponses().get("default"); + } else { + original = operation.getResponses().get(rsp.code); + } + original = ModelUtils.getReferencedApiResponse(openAPI, original); + String[] words = rsp.message.split("[^A-Za-z ]"); + + // Create a unique responseID for this response. + String responseId; + + if (rsp.vendorExtensions.containsKey("x-response-id")) { + // If it's been specified directly, use that. + responseId = (String) rsp.vendorExtensions.get("x-response-id"); + } else if ((words.length != 0) && (words[0].trim().length() != 0)) { + // If there's a description, build it from the description. + responseId = camelize(words[0].replace(" ", "_")); + } else { + // Otherwise fall back to the http response code. + responseId = "Status" + rsp.code; + } + + // Deduplicate response IDs that would otherwise contain the same + // text. We rely on the ID being unique, but since we form it from + // the raw description field we can't require that the spec writer + // provides unique descriptions. + int idTieBreaker = 2; + while (responseIds.contains(responseId)) { + String trial = String.format(Locale.ROOT, "%s_%d", responseId, idTieBreaker); + if (!responseIds.contains(trial)) { + responseId = trial; + } else { + idTieBreaker++; + } + } + + responseIds.add(responseId); + + String underscoredResponseId = underscore(responseId).toUpperCase(Locale.ROOT); + rsp.vendorExtensions.put("x-response-id", responseId); + rsp.vendorExtensions.put("x-uppercase-response-id", underscoredResponseId.toUpperCase(Locale.ROOT)); + rsp.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId.toUpperCase(Locale.ROOT)); + if (rsp.dataType != null) { + String uppercaseDataType = (rsp.dataType.replace("models::", "")).toUpperCase(Locale.ROOT); + rsp.vendorExtensions.put("x-uppercase-data-type", uppercaseDataType); + + // Get the mimetype which is produced by this response. Note + // that although in general responses produces a set of + // different mimetypes currently we only support 1 per + // response. + String firstProduces = null; + + if (original.getContent() != null) { + firstProduces = original.getContent().keySet().stream().findFirst().orElse(null); + } + + // The output mime type. This allows us to do sensible fallback + // to JSON/XML rather than using only the default operation + // mimetype. + String outputMime; + + if (firstProduces == null) { + if (producesXml) { + outputMime = xmlMimeType; + } else if (producesPlainText) { + if (bytesType.equals(rsp.dataType)) { + outputMime = octetMimeType; + } else { + outputMime = plainTextMimeType; + } + } else { + outputMime = jsonMimeType; + } + } else { + // If we know exactly what mimetype this response is + // going to produce, then use that. If we have not found + // anything, then we'll fall back to the 'producesXXX' + // definitions we worked out above for the operation as a + // whole. + if (isMimetypeXml(firstProduces)) { + producesXml = true; + producesPlainText = false; + } else if (isMimetypePlain(firstProduces)) { + producesXml = false; + producesPlainText = true; + } else { + producesXml = false; + producesPlainText = false; + } + + outputMime = firstProduces; + } + + rsp.vendorExtensions.put("x-mime-type", outputMime); + + // Write out the type of data we actually expect this response + // to make. + if (producesXml) { + rsp.vendorExtensions.put("x-produces-xml", true); + } else if (producesPlainText) { + // Plain text means that there is not structured data in + // this response. So it'll either be a UTF-8 encoded string + // 'plainText' or some generic 'bytes'. + // + // Note that we don't yet distinguish between string/binary + // and string/bytes - that is we don't auto-detect whether + // base64 encoding should be done. They both look like + // 'producesBytes'. + if (bytesType.equals(rsp.dataType)) { + rsp.vendorExtensions.put("x-produces-bytes", true); + } else { + rsp.vendorExtensions.put("x-produces-plain-text", true); + } + } else { + rsp.vendorExtensions.put("x-produces-json", true); + // If the data type is just "object", then ensure that the + // Rust data type is "serde_json::Value". This allows us + // to define APIs that can return arbitrary JSON bodies. + if ("object".equals(rsp.dataType)) { + rsp.dataType = "serde_json::Value"; + } + } + + Schema response = (Schema) rsp.schema; + // Check whether we're returning an object with a defined XML namespace. + if (response != null && (!StringUtils.isEmpty(response.get$ref()))) { + Schema model = definitions.get(ModelUtils.getSimpleRef(response.get$ref())); + if ((model != null)) { + XML xml = model.getXml(); + if ((xml != null) && (xml.getNamespace() != null)) { + rsp.vendorExtensions.put("x-has-namespace", "true"); + } + } + } + } + for (CodegenProperty header : rsp.headers) { + if (uuidType.equals(header.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + header.nameInPascalCase = toModelName(header.baseName); + header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT); + } + } + + for (CodegenParameter header : op.headerParams) { + header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT); + } + + for (CodegenProperty header : op.responseHeaders) { + if (uuidType.equals(header.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + header.nameInPascalCase = toModelName(header.baseName); + header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT); + } + + return op; + } + + @Override + public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) { + OperationMap operations = objs.getOperations(); + List operationList = operations.getOperation(); + + for (CodegenOperation op : operationList) { + postProcessOperationWithModels(op, allModels); + } + + operationList.sort((one, another) -> { + int params_compare = ObjectUtils.compare(one.pathParams.size(), another.pathParams.size()); + if (params_compare == 0) { + return ObjectUtils.compare(one.operationId, another.operationId); + } else { + return params_compare; + } + }); + + return objs; + } + + private void postProcessOperationWithModels(CodegenOperation op, List allModels) { + boolean consumesPlainText = false; + boolean consumesXml = false; + + if (op.consumes != null) { + for (Map consume : op.consumes) { + if (consume.get("mediaType") != null) { + String mediaType = consume.get("mediaType"); + + if (isMimetypeXml(mediaType)) { + additionalProperties.put("usesXml", true); + consumesXml = true; + } else if (isMimetypePlain(mediaType)) { + consumesPlainText = true; + } else if (isMimetypeWwwFormUrlEncoded(mediaType)) { + op.vendorExtensions.put("x-consumes-form", true); + additionalProperties.put("usesUrlEncodedForm", true); + } else if (isMimetypeMultipartFormData(mediaType)) { + op.vendorExtensions.put("x-consumes-multipart", true); + op.vendorExtensions.put("x-consumes-multipart-form", true); + additionalProperties.put("apiUsesMultipartFormData", true); + additionalProperties.put("apiUsesMultipart", true); + } else if (isMimetypeMultipartRelated(mediaType)) { + op.vendorExtensions.put("x-consumes-multipart", true); + op.vendorExtensions.put("x-consumes-multipart-related", true); + additionalProperties.put("apiUsesMultipartRelated", true); + additionalProperties.put("apiUsesMultipart", true); + } + } + } + } + + if (op.bodyParams.size() > 0 || op.formParams.size() > 0) { + op.vendorExtensions.put("x-has-request-body", true); + } + + // The CLI generates a structopt structure for each operation. This can only have a single + // use of a short option, which comes from the parameter name, so we need to police + // against duplicates + HashMap availableOptions = new HashMap(); + + for (CodegenParameter p : op.allParams) { + if (p.isBoolean && p.isPrimitiveType) { + char shortOption = p.paramName.charAt(0); + if (shortOption == 'a' || shortOption == 'o' || shortOption == 'f') { + // These are used by serverAddress, output, and force + p.vendorExtensions.put("x-provide-cli-short-opt", false); + } else if (availableOptions.containsKey(shortOption)) { + availableOptions.get(shortOption).vendorExtensions.put("x-provide-cli-short-opt", false); + p.vendorExtensions.put("x-provide-cli-short-opt", false); + } else { + availableOptions.put(shortOption, p); + p.vendorExtensions.put("x-provide-cli-short-opt", true); + } + } + } + + String underscoredOperationId = underscore(op.operationId).toUpperCase(Locale.ROOT); + + if (op.bodyParam != null) { + // Default to consuming json + op.bodyParam.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId); + if (consumesXml) { + op.vendorExtensions.put("x-consumes-basic", true); + op.bodyParam.vendorExtensions.put("x-consumes-xml", true); + } else if (consumesPlainText) { + op.vendorExtensions.put("x-consumes-basic", true); + op.bodyParam.vendorExtensions.put("x-consumes-plain-text", true); + } else { + op.vendorExtensions.put("x-consumes-basic", true); + op.bodyParam.vendorExtensions.put("x-consumes-json", true); + } + } + + for (CodegenParameter param : op.bodyParams) { + processParam(param, op); + + param.vendorExtensions.put("x-uppercase-operation-id", underscoredOperationId); + + // Default to producing json if nothing else is specified + if (consumesXml) { + op.vendorExtensions.put("x-consumes-basic", true); + param.vendorExtensions.put("x-consumes-xml", true); + } else if (consumesPlainText) { + op.vendorExtensions.put("x-consumes-basic", true); + param.vendorExtensions.put("x-consumes-plain-text", true); + } else { + op.vendorExtensions.put("x-consumes-basic", true); + param.vendorExtensions.put("x-consumes-json", true); + } + } + + for (CodegenParameter param : op.queryParams) { + // If the MIME type is JSON, mark it. We don't currently support any other MIME types. + if (param.contentType != null && isMimetypeJson(param.contentType)) { + param.vendorExtensions.put("x-consumes-json", true); + } + } + + for (CodegenParameter param : op.formParams) { + processParam(param, op); + } + + for (CodegenParameter header : op.headerParams) { + header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT); + } + + for (CodegenProperty header : op.responseHeaders) { + if (uuidType.equals(header.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + header.nameInPascalCase = toModelName(header.baseName); + header.nameInLowerCase = header.baseName.toLowerCase(Locale.ROOT); + } + + if (op.authMethods != null) { + boolean headerAuthMethods = false; + + for (CodegenSecurity s : op.authMethods) { + if (s.isApiKey && s.isKeyInHeader) { + s.vendorExtensions.put("x-api-key-name", toModelName(s.keyParamName)); + headerAuthMethods = true; + } + + if (s.isBasicBasic || s.isBasicBearer || s.isOAuth) { + headerAuthMethods = true; + } + } + + if (headerAuthMethods) { + op.vendorExtensions.put("x-has-header-auth-methods", "true"); + } + } + + for (CodegenCallback callback : op.callbacks) { + for (CodegenCallback.Url url : callback.urls) { + for (CodegenOperation innerOp : url.requests) { + postProcessOperationWithModels(innerOp, allModels); + } + } + } + } + + @Override + public boolean isDataTypeFile(final String dataType) { + return dataType != null && dataType.equals(typeMapping.get("File")); + } + + /** + * Add operation to group + * + * @param tag name of the tag + * @param resourcePath path of the resource + * @param operation OAS Operation object + * @param co Codegen Operation object + * @param operations map of Codegen operations + */ + @SuppressWarnings("static-method") + @Override + public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation + co, Map> operations) { + // only generate operation for the first tag of the tags + if (tag != null && co.tags.size() > 1) { + String expectedTag = sanitizeTag(co.tags.get(0).getName()); + if (!tag.equals(expectedTag)) { + LOGGER.info("generated skip additional tag `{}` with operationId={}", tag, co.operationId); + return; + } + } + super.addOperationToGroup(tag, resourcePath, operation, co, operations); + } + + // This is a really terrible hack. We're working around the fact that the + // base version of `fromRequestBody` checks to see whether the body is a + // ref. If so, it unwraps the reference and replaces it with its inner + // type. This causes problems in rust-server, as it means that we use inner + // types in the API, rather than the correct outer type. + // + // Thus, we grab the inner schema beforehand, and then tinker afterwards to + // restore things to sensible values. + @Override + public CodegenParameter fromRequestBody(RequestBody body, Set imports, String bodyParameterName) { + Schema original_schema = ModelUtils.getSchemaFromRequestBody(body); + CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); + + if (StringUtils.isNotBlank(original_schema.get$ref())) { + // Undo the mess `super.fromRequestBody` made - re-wrap the inner + // type. + codegenParameter.dataType = getTypeDeclaration(original_schema); + codegenParameter.isPrimitiveType = false; + codegenParameter.isArray = false; + codegenParameter.isString = false; + codegenParameter.isByteArray = ModelUtils.isByteArraySchema(original_schema); + + + // This is a model, so should only have an example if explicitly + // defined. + if (codegenParameter.vendorExtensions != null && codegenParameter.vendorExtensions.containsKey("x-example")) { + codegenParameter.example = Json.pretty(codegenParameter.vendorExtensions.get("x-example")); + } else if (!codegenParameter.required) { + //mandatory parameter use the example in the yaml. if no example, it is also null. + codegenParameter.example = null; + } + } + + return codegenParameter; + } + + @Override + public String getTypeDeclaration(String name) { + return "models::" + name; + } + + private String modelFromSchema(Schema schema) { + String ref = null; + + if (schema != null) { + ref = schema.get$ref(); + } + + if (ref != null && ref.indexOf("#/components/schemas/") == 0) { + ref = toModelName(ref.substring("#/components/schemas/".length())); + } else { + ref = null; + } + + return ref; + } + + @Override + public String getTypeDeclaration(Schema p) { + LOGGER.trace("Getting type declaration for schema"); + + String type; + + if (ModelUtils.isArraySchema(p)) { + ArraySchema ap = (ArraySchema) p; + Schema inner = ap.getItems(); + String innerType = getTypeDeclaration(inner); + type = typeMapping.get("array") + "<" + innerType + ">"; + } else if (ModelUtils.isMapSchema(p)) { + Schema inner = ModelUtils.getAdditionalProperties(p); + String innerType = getTypeDeclaration(inner); + StringBuilder typeDeclaration = new StringBuilder(typeMapping.get("map")).append("<").append(typeMapping.get("string")).append(", "); + typeDeclaration.append(innerType).append(">"); + type = typeDeclaration.toString(); + } else if (!StringUtils.isEmpty(p.get$ref())) { + try { + type = modelFromSchema(p); + + if (type != null) { + type = "models::" + type; + LOGGER.debug("Returning " + type + " from ref"); + } + } catch (Exception e) { + type = null; + LOGGER.error("Error obtaining the datatype from schema (model): " + p + ". Error was: " + e.getMessage(), e); + } + } else if (p instanceof FileSchema) { + type = typeMapping.get("File").toString(); + } else { + type = super.getTypeDeclaration(p); + } + + // We are using extrinsic nullability, rather than intrinsic, so we need to dig into the inner + // layer of the referenced schema. + Schema rp = ModelUtils.getReferencedSchema(openAPI, p); + + if (rp.getNullable() == Boolean.TRUE) { + type = "swagger::Nullable<" + type + ">"; + } + + LOGGER.debug("Returning " + type + " for type declaration"); + + return type; + } + + @Override + public String toInstantiationType(Schema p) { + if (ModelUtils.isArraySchema(p)) { + Schema inner = ModelUtils.getSchemaItems(p); + return instantiationTypes.get("array") + "<" + getSchemaType(inner) + ">"; + } else if (ModelUtils.isMapSchema(p)) { + Schema inner = ModelUtils.getAdditionalProperties(p); + return instantiationTypes.get("map") + "<" + typeMapping.get("string") + ", " + getSchemaType(inner) + ">"; + } else { + return null; + } + } + + @Override + public CodegenModel fromModel(String name, Schema model) { + LOGGER.trace("Creating model from schema: {}", model); + + Map allDefinitions = ModelUtils.getSchemas(this.openAPI); + CodegenModel mdl = super.fromModel(name, model); + + LOGGER.debug("fromModel (base end): " + mdl); + + if (!StringUtils.isEmpty(model.get$ref())) { + String ref = ModelUtils.getSimpleRef(model.get$ref()); + String dataType = toModelName(ref); + mdl.dataType = dataType; + mdl.isAlias = false; + LOGGER.debug("Schema for: " + name + " is wrapper for: " + dataType); + } + + + if (ModelUtils.isArraySchema(model)) { + Schema inner = ModelUtils.getSchemaItems(model); + String xmlName = null; + + // Detect XML list where the inner item is defined directly. + if ((inner != null) && + (inner.getXml() != null)) { + xmlName = inner.getXml().getName(); + } + + // Detect XML list where the inner item is a reference. + if (model.getXml() != null && model.getXml().getWrapped() && + inner != null && + !StringUtils.isEmpty(inner.get$ref())) { + Schema inner_schema = allDefinitions.get( + ModelUtils.getSimpleRef(inner.get$ref())); + + if (inner_schema.getXml() != null && + inner_schema.getXml().getName() != null) { + xmlName = inner_schema.getXml().getName(); + } + } + + // If this model's items require wrapping in xml, squirrel away the + // xml name so we can insert it into the relevant model fields. + if (xmlName != null) { + mdl.vendorExtensions.put("x-item-xml-name", xmlName); + modelXmlNames.put("models::" + mdl.classname, xmlName); + } + } else if ((mdl.anyOf.size() > 0) || (mdl.oneOf.size() > 0)) { + mdl.dataType = getSchemaType(model); + } + + if (mdl.xmlNamespace != null) { + additionalProperties.put("usesXmlNamespaces", true); + } + + Schema modelAdditionalProperties = ModelUtils.getAdditionalProperties(model); + + if (modelAdditionalProperties != null) { + mdl.additionalPropertiesType = getTypeDeclaration(modelAdditionalProperties); + } + + // Does this support partial ordering? + boolean partialOrdSupport = true; + + if (mdl.dataType != null && mdl.dataType.equals("object")) { + // Object isn't a sensible default. Instead, we set it to + // 'null'. This ensures that we treat this model as a struct + // with multiple parameters. + mdl.dataType = null; + } else if ("map".equals(mdl.dataType)) { + if (!mdl.allVars.isEmpty() || mdl.additionalPropertiesType == null) { + // We don't yet support `additionalProperties` that also have + // properties. If we see variables, we ignore the + // `additionalProperties` type ('map') and warn the user. This + // will produce code that compiles, but won't feature the + // `additionalProperties` - but that's likely more useful to + // the user than the alternative. + LOGGER.warn("Ignoring additionalProperties (see https://github.com/OpenAPITools/openapi-generator/issues/318) alongside defined properties"); + mdl.dataType = null; + } else { + mdl.dataType = "std::collections::HashMap"; + partialOrdSupport = false; + } + } else if (mdl.dataType != null && mdl.isAlias) { + // We need to hack about with single-parameter models to + // get them recognised correctly. + mdl.isAlias = false; + mdl.dataType = typeMapping.get(mdl.dataType); + } + + if (uuidType.equals(mdl.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + + for (CodegenProperty prop : mdl.vars) { + if (uuidType.equals(prop.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + + String xmlName = modelXmlNames.get(prop.dataType); + if (xmlName != null) { + prop.vendorExtensions.put("x-item-xml-name", xmlName); + } + } + + // Do we support doing ToString/FromStr conversions for query parameters? + boolean toStringSupport = true; + boolean isString = "String".equals(mdl.dataType); + + if (isString) { + toStringSupport = true; + } else if (mdl.dataType != null + && (mdl.dataType.startsWith("swagger::OneOf") || mdl.dataType.startsWith("swagger::AnyOf"))) { + toStringSupport = false; + partialOrdSupport = false; + } else if (mdl.getAdditionalPropertiesType() != null) { + toStringSupport = false; + } else if (model instanceof ComposedSchema) { + for (Schema schema : ModelUtils.getInterfaces((ComposedSchema) model)) { + if (additionalProperties != null) { + toStringSupport = false; + } + } + } + + mdl.vendorExtensions.put("x-upper-case-name", name.toUpperCase(Locale.ROOT)); + mdl.vendorExtensions.put("x-is-string", isString); + mdl.vendorExtensions.put("x-to-string-support", toStringSupport); + mdl.vendorExtensions.put("x-partial-ord", partialOrdSupport); + + LOGGER.trace("Created model: " + name + ": " + mdl + " from schema: " + model); + + return mdl; + } + + @Override + public Map postProcessSupportingFileData(Map bundle) { + generateYAMLSpecFile(bundle); + + addPathSetMapToBundle(pathSetMap, bundle); + + // If we have callbacks, add the callbacks module, otherwise remove it + boolean hasCallbacks = haveCallbacks(bundle); + bundle.put("hasCallbacks", hasCallbacks); + SupportingFile[] callbackFiles = { + new SupportingFile("client-callbacks.mustache", "src/client", "callbacks.rs"), + new SupportingFile("server-callbacks.mustache", "src/server", "callbacks.rs"), + new SupportingFile("example-client-server.mustache", "examples/client", "server.rs") + }; + for (SupportingFile callbackFile : callbackFiles) { + if (hasCallbacks) { + supportingFiles.add(callbackFile); + } else { + supportingFiles.remove(callbackFile); + } + } + + if (hasCallbacks) { + Map callbackData = new HashMap(); + addPathSetMapToBundle(callbacksPathSetMap, callbackData); + bundle.put("callbacks", callbackData); + } + + // Flag whether we have any OAuth scopes + Map securitySchemeMap = openAPI.getComponents() != null ? openAPI.getComponents().getSecuritySchemes() : null; + List authMethods = fromSecurity(securitySchemeMap); + boolean hasAuthScopes = false; + if (authMethods != null && !authMethods.isEmpty()) { + for (CodegenSecurity authMethod : authMethods) { + if (authMethod.hasScopes != null && authMethod.hasScopes) { + hasAuthScopes = true; + break; + } + } + } + bundle.put("hasAuthScopes", hasAuthScopes); + + return super.postProcessSupportingFileData(bundle); + } + + /** + * Add a built path set map to the provided bundle + * + * @param pathSetMap A previously built path set map + * @param bundle Bundle for the supporting files to add the data to. + */ + private static void addPathSetMapToBundle(Map> pathSetMap, Map bundle) { + // We previously built a mapping from path to path ID and regular + // expression - see fromOperation for details. Sort it and add an + // index, and then add it to the objects that we're about to pass to + // the templates to process. + List>> pathSetEntryList = new ArrayList(pathSetMap.entrySet()); + Collections.sort(pathSetEntryList, new Comparator>>() { + @Override + public int compare(Map.Entry> a, Map.Entry> b) { + return a.getValue().get("path").compareTo(b.getValue().get("path")); + } + }); + List pathSet = new ArrayList>(); + int index = 0; + for (Map.Entry> pathSetEntry : pathSetEntryList) { + Map pathSetEntryValue = pathSetEntry.getValue(); + pathSetEntryValue.put("index", Integer.toString(index)); + index++; + pathSet.add(pathSetEntryValue); + } + bundle.put("pathSet", pathSet); + } + + /** + * Does the API being generated use callbacks? + * + * @param bundle Bundle data from DefaultGenerator which will be passed to the templates + * @return true if any operation has a callback, false otherwise + */ + private static boolean haveCallbacks(Map bundle) { + ApiInfoMap apiInfo = (ApiInfoMap) bundle.get("apiInfo"); + for (OperationsMap api : apiInfo.getApis()) { + List ops = api.getOperations().getOperation(); + for (CodegenOperation op : ops) { + if (!op.callbacks.isEmpty()) { + return true; + } + } + } + + return false; + } + + @Override + public String toDefaultValue(Schema p) { + String defaultValue = null; + if ((ModelUtils.isNullable(p)) && (p.getDefault() != null) && ("null".equalsIgnoreCase(p.getDefault().toString()))) + return "swagger::Nullable::Null"; + else if (ModelUtils.isBooleanSchema(p)) { + if (p.getDefault() != null) { + if ("false".equalsIgnoreCase(p.getDefault().toString())) + defaultValue = "false"; + else + defaultValue = "true"; + } + } else if (ModelUtils.isNumberSchema(p)) { + if (p.getDefault() != null) { + defaultValue = p.getDefault().toString(); + } + } else if (ModelUtils.isIntegerSchema(p)) { + if (p.getDefault() != null) { + defaultValue = p.getDefault().toString(); + } + } else if (ModelUtils.isStringSchema(p)) { + if (p.getDefault() != null) { + defaultValue = "\"" + String.valueOf(p.getDefault()) + "\".to_string()"; + } + } + if ((defaultValue != null) && (ModelUtils.isNullable(p))) + defaultValue = "swagger::Nullable::Present(" + defaultValue + ")"; + return defaultValue; + } + + @Override + public String toOneOfName(List names, Schema composedSchema) { + Map exts = null; + if (composedSchema != null) { + exts = composedSchema.getExtensions(); + } + if (exts != null && exts.containsKey("x-one-of-name")) { + return (String) exts.get("x-one-of-name"); + } + + List schemas = ModelUtils.getInterfaces(composedSchema); + + List types = new ArrayList<>(); + for (Schema s : schemas) { + types.add(getTypeDeclaration(s)); + } + return "swagger::OneOf" + types.size() + "<" + String.join(",", types) + ">"; + } + + @Override + public String toAnyOfName(List names, Schema composedSchema) { + List schemas = ModelUtils.getInterfaces(composedSchema); + + List types = new ArrayList<>(); + for (Schema s : schemas) { + types.add(getTypeDeclaration(s)); + } + return "swagger::AnyOf" + types.size() + "<" + String.join(",", types) + ">"; + } + + /** + * Strip a swagger::Nullable wrapper on a datatype + * + * @deprecated Avoid using this - use a different mechanism instead. + */ + private static String stripNullable(String type) { + if (type.startsWith("swagger::Nullable<") && type.endsWith(">")) { + return type.substring("swagger::Nullable<".length(), type.length() - 1); + } else { + return type; + } + } + + @Override + public String toAllOfName(List names, Schema composedSchema) { + // Handle all of objects as freeform + return null; + } + + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + super.postProcessModelProperty(model, property); + + // TODO: We should avoid reverse engineering primitive type status from the data type + if (!languageSpecificPrimitives.contains(stripNullable(property.dataType))) { + // If we use a more qualified model name, then only camelize the actual type, not the qualifier. + if (property.dataType.contains(":")) { + int position = property.dataType.lastIndexOf(":"); + property.dataType = property.dataType.substring(0, position) + camelize(property.dataType.substring(position)); + } else { + property.dataType = camelize(property.dataType); + } + property.isPrimitiveType = property.isContainer && languageSpecificPrimitives.contains(typeMapping.get(stripNullable(property.complexType))); + } else { + property.isPrimitiveType = true; + } + + // Integer type fitting + if (Objects.equals(property.baseType, "integer")) { + + BigInteger minimum = Optional.ofNullable(property.getMinimum()).map(BigInteger::new).orElse(null); + BigInteger maximum = Optional.ofNullable(property.getMaximum()).map(BigInteger::new).orElse(null); + + boolean unsigned = canFitIntoUnsigned(minimum, property.getExclusiveMinimum()); + + if (Strings.isNullOrEmpty(property.dataFormat)) { + property.dataType = bestFittingIntegerType(minimum, + property.getExclusiveMinimum(), + maximum, + property.getExclusiveMaximum(), + true); + } else { + switch (property.dataFormat) { + // custom integer formats (legacy) + case "uint32": + property.dataType = "u32"; + break; + case "uint64": + property.dataType = "u64"; + break; + case "int32": + property.dataType = unsigned ? "u32" : "i32"; + break; + case "int64": + property.dataType = unsigned ? "u64" : "i64"; + break; + default: + LOGGER.warn("The integer format '{}' is not recognized and will be ignored.", property.dataFormat); + property.dataType = bestFittingIntegerType(minimum, + property.getExclusiveMinimum(), + maximum, + property.getExclusiveMaximum(), + true); + } + } + } + + property.name = underscore(property.name); + + if (!property.required) { + property.defaultValue = (property.defaultValue != null) ? "Some(" + property.defaultValue + ")" : "None"; + } + + // If a property has no type defined in the schema, it can take values of any type. + // This clashes with Rust being statically typed. Hence, assume it's sent as a json + // blob and return the json value to the user of the API and let the user determine + // the type from the value. If the property has no type, at this point it will have + // baseType "object" allowing us to identify such properties. Moreover, set to not + // nullable, we can use the serde_json::Value::Null enum variant. + if ("object".equals(property.baseType)) { + property.dataType = "serde_json::Value"; + property.isNullable = false; + } + } + + @Override + public ModelsMap postProcessModels(ModelsMap objs) { + return super.postProcessModelsEnum(objs); + } + + private void processParam(CodegenParameter param, CodegenOperation op) { + String example = null; + + // If a parameter uses UUIDs, we need to import the UUID package. + if (uuidType.equals(param.dataType)) { + additionalProperties.put("apiUsesUuid", true); + } + + if (Boolean.TRUE.equals(param.isFreeFormObject)) { + param.vendorExtensions.put("x-format-string", "{:?}"); + example = null; + } else if (param.isArray && param.isString) { + // This occurs if the parameter is a form property and is Vec + param.vendorExtensions.put("x-format-string", "{:?}"); + example = (param.example != null) ? "&vec![\"" + param.example + "\".to_string()]" : "&Vec::new()"; + } else if (param.isString) { + param.vendorExtensions.put("x-format-string", "\\\"{}\\\""); + example = "\"" + ((param.example != null) ? param.example : "") + "\".to_string()"; + } else if (param.isPrimitiveType) { + if ((param.isByteArray) || (param.isBinary)) { + // Binary primitive types don't implement `Display`. + param.vendorExtensions.put("x-format-string", "{:?}"); + example = "swagger::ByteArray(Vec::from(\"" + ((param.example != null) ? param.example : "") + "\"))"; + } else { + param.vendorExtensions.put("x-format-string", "{}"); + example = (param.example != null) ? param.example : ""; + } + } else if (param.isArray) { + param.vendorExtensions.put("x-format-string", "{:?}"); + if (param.items.isString) { + // We iterate through the list of string and ensure they end up in the format vec!["example".to_string()] + example = (param.example != null) + ? "&vec![" + Arrays.stream(param.example.replace("[", "").replace("]", "").split(",")) + .map(item -> item + ".to_string()") + .collect(Collectors.joining(", ")) + "]" + : "&Vec::new()"; + } else { + example = (param.example != null) ? param.example : "&Vec::new()"; + } + } + else { + param.vendorExtensions.put("x-format-string", "{:?}"); + if (param.example != null) { + example = "serde_json::from_str::<" + param.dataType + ">(r#\"" + param.example + "\"#).expect(\"Failed to parse JSON example\")"; + } + } + + if (param.required) { + if (example != null) { + param.vendorExtensions.put("x-example", example); + } else if (param.isArray) { + // Use the empty list if we don't have an example + param.vendorExtensions.put("x-example", "&Vec::new()"); + } else { + // If we don't have an example that we can provide, we need to disable the client example, as it won't build. + param.vendorExtensions.put("x-example", "???"); + op.vendorExtensions.put("x-no-client-example", Boolean.TRUE); + } + } else if ((param.dataFormat != null) && (("date-time".equals(param.dataFormat)) || ("date".equals(param.dataFormat)))) { + param.vendorExtensions.put("x-format-string", "{:?}"); + param.vendorExtensions.put("x-example", "None"); + } else { + // Not required, so override the format string and example + param.vendorExtensions.put("x-format-string", "{:?}"); + String exampleString = (example != null) ? "Some(" + example + ")" : "None"; + param.vendorExtensions.put("x-example", exampleString); + } + } + + @Override + public void postProcessFile(File file, String fileType) { + super.postProcessFile(file, fileType); + if (file == null) { + return; + } + + String commandPrefix = System.getenv("RUST_POST_PROCESS_FILE"); + if (StringUtils.isEmpty(commandPrefix)) { + commandPrefix = "rustfmt"; + } + + // only process files with .rs extension + if ("rs".equals(FilenameUtils.getExtension(file.toString()))) { + this.executePostProcessor(new String[]{commandPrefix, file.toString()}); + } + } + + @Override + protected void updateParameterForString(CodegenParameter codegenParameter, Schema parameterSchema) { + /** + * we have a custom version of this function to set isString to false for uuid + */ + if (ModelUtils.isEmailSchema(parameterSchema)) { + codegenParameter.isEmail = true; + } else if (ModelUtils.isUUIDSchema(parameterSchema)) { + codegenParameter.setIsString(false); + codegenParameter.isUuid = true; + } else if (ModelUtils.isByteArraySchema(parameterSchema)) { + codegenParameter.setIsString(false); + codegenParameter.isByteArray = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isBinarySchema(parameterSchema)) { + codegenParameter.isBinary = true; + codegenParameter.isFile = true; // file = binary in OAS3 + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDate = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDateTimeSchema(parameterSchema)) { + codegenParameter.setIsString(false); // for backward compatibility with 2.x + codegenParameter.isDateTime = true; + codegenParameter.isPrimitiveType = true; + } else if (ModelUtils.isDecimalSchema(parameterSchema)) { // type: string, format: number + codegenParameter.setIsString(false); + codegenParameter.isDecimal = true; + codegenParameter.isPrimitiveType = true; + } + if (Boolean.TRUE.equals(codegenParameter.isString)) { + codegenParameter.isPrimitiveType = true; + } + } + + @Override + protected void updatePropertyForAnyType(CodegenProperty property, Schema p) { + /** + * we have a custom version of this function to not set isNullable to true + */ + // The 'null' value is allowed when the OAS schema is 'any type'. + // See https://github.com/OAI/OpenAPI-Specification/issues/1389 + if (Boolean.FALSE.equals(p.getNullable())) { + LOGGER.warn("Schema '{}' is any type, which includes the 'null' value. 'nullable' cannot be set to 'false'", p.getName()); + } + if (languageSpecificPrimitives.contains(property.dataType)) { + property.isPrimitiveType = true; + } + if (ModelUtils.isMapSchema(p)) { + // an object or anyType composed schema that has additionalProperties set + // some of our code assumes that any type schema with properties defined will be a map + // even though it should allow in any type and have map constraints for properties + updatePropertyForMap(property, p); + } + } + + @Override + protected String getParameterDataType(Parameter parameter, Schema schema) { + if (parameter.get$ref() != null) { + String refName = ModelUtils.getSimpleRef(parameter.get$ref()); + return toModelName(refName); + } + return null; + } +} diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 94b3eade53a7..80c9c105b641 100644 --- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -122,6 +122,7 @@ org.openapitools.codegen.languages.RubySinatraServerCodegen org.openapitools.codegen.languages.RustAxumServerCodegen org.openapitools.codegen.languages.RustClientCodegen org.openapitools.codegen.languages.RustServerCodegen +org.openapitools.codegen.languages.RustServerCodegenDeprecated org.openapitools.codegen.languages.ScalatraServerCodegen org.openapitools.codegen.languages.ScalaAkkaClientCodegen org.openapitools.codegen.languages.ScalaCaskServerCodegen @@ -156,4 +157,4 @@ org.openapitools.codegen.languages.TypeScriptReduxQueryClientCodegen org.openapitools.codegen.languages.TypeScriptRxjsClientCodegen org.openapitools.codegen.languages.WsdlSchemaCodegen org.openapitools.codegen.languages.XojoClientCodegen -org.openapitools.codegen.languages.ZapierClientCodegen \ No newline at end of file +org.openapitools.codegen.languages.ZapierClientCodegen diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/Cargo.mustache new file mode 100644 index 000000000000..cec9e012796a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/Cargo.mustache @@ -0,0 +1,176 @@ +[package] +name = "{{{packageName}}}" +version = "{{{packageVersion}}}" +{{#infoEmail}} +authors = ["{{{.}}}"] +{{/infoEmail}} +{{^infoEmail}} +authors = ["OpenAPI Generator team and contributors"] +{{/infoEmail}} +{{#appDescription}} +description = "{{{.}}}" +{{/appDescription}} +{{#licenseInfo}} +license = "{{.}}" +{{/licenseInfo}} +{{^licenseInfo}} +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +{{/licenseInfo}} +edition = "2018" +{{#publishRustRegistry}} +publish = ["{{.}}"] +{{/publishRustRegistry}} +{{#repositoryUrl}} +repository = "{{.}}" +{{/repositoryUrl}} +{{#documentationUrl}} +documentation = "{{.}}" +{{/documentationUrl}} +{{#homePageUrl}} +homepage = "{{.}}" +{{/homePageUrl}} + +[features] +default = ["client", "server"] +client = [ +{{#apiUsesMultipart}} + "mime_0_2", +{{/apiUsesMultipart}} +{{#apiUsesMultipartFormData}} + "multipart", "multipart/client", "swagger/multipart_form", +{{/apiUsesMultipartFormData}} +{{#apiUsesMultipartRelated}} + "hyper_0_10", "mime_multipart", "swagger/multipart_related", +{{/apiUsesMultipartRelated}} +{{#usesUrlEncodedForm}} + "serde_urlencoded", +{{/usesUrlEncodedForm}} +{{#hasCallbacks}} + "serde_ignored", "regex", "percent-encoding", "lazy_static", +{{/hasCallbacks}} +{{! Anything added to the list below, should probably be added to the callbacks list below }} + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ +{{#apiUsesMultipart}} + "mime_0_2", +{{/apiUsesMultipart}} +{{#apiUsesMultipartFormData}} + "multipart", "multipart/server", "swagger/multipart_form", +{{/apiUsesMultipartFormData}} +{{#apiUsesMultipartRelated}} + "hyper_0_10", "mime_multipart", "swagger/multipart_related", +{{/apiUsesMultipartRelated}} +{{#hasCallbacks}} + "native-tls", "hyper-openssl", "hyper-tls", "openssl", +{{/hasCallbacks}} +{{! Anything added to the list below, should probably be added to the callbacks list above }} + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ +{{#apiHasDeleteMethods}} + "dialoguer", +{{/apiHasDeleteMethods}} + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition +{{#usesXml}} +# TODO: this should be updated to point at the official crate once +# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream +serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} +{{/usesXml}} +{{#apiUsesMultipart}} +mime_0_2 = { package = "mime", version = "0.2.6", optional = true } +{{/apiUsesMultipart}} +{{#apiUsesMultipartFormData}} +multipart = { version = "0.16", default-features = false, optional = true } +{{/apiUsesMultipartFormData}} +{{#apiUsesUuid}} +uuid = {version = "1.3.1", features = ["serde", "v4"]} +{{/apiUsesUuid}} + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +{{#apiUsesMultipartRelated}} +mime_multipart = {version = "0.5", optional = true} +hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} +{{/apiUsesMultipartRelated}} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific +{{#usesUrlEncodedForm}} +serde_urlencoded = {version = "0.6.1", optional = true} +{{/usesUrlEncodedForm}} + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +{{#apiHasDeleteMethods}} +dialoguer = { version = "0.8", optional = true } +{{/apiHasDeleteMethods}} + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "{{{packageName}}}" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.md b/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.md new file mode 100644 index 000000000000..bacaef541d14 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.md @@ -0,0 +1,48 @@ +# Rust Server Generator Templates + +The Rust Server Generator templates use Mustache Partials. + +The following tree shows which templates include which: + +- `api_doc.mustache` +- `bin-cli.mustache` +- `cargo-config` +- `Cargo.mustache` +- `context.mustache` +- `client-callbacks-mod.mustache` + - `server-imports.mustache` + - `server-make-service.mustache` + - `server-service-footer.mustache` + - `server-service-header.mustache` + - `server-operation.mustache` +- `client-mod.mustache` + - `client-imports.mustache` + - `client-operation.mustache` +- `example-ca.pem` +- `example-client-main.mustache` +- `example-client-server.mustache` +- `example-server-chain.pem` +- `example-server-common.mustache` +- `example-server-key.pem` +- `example-server-main.mustache` +- `example-server-server.mustache` + - `example-server-operation.mustache` +- `gitignore` +- `header.mustache` +- `lib.mustache` + - `response.mustache` +- `model_doc.mustache` +- `models.mustache` +- `openapi.mustache` +- `README.mustache` +- `server-callbacks.mustache` + - `client-imports.mustache` + - `client-operation.mustache` +- `server-service-header.mustache` +- `server-mod.mustache` + - `server-imports.mustache` + - `server-make-service.mustache` + - `server-service-footer.mustache` + - `server-service-header.mustache` + - `server-operation.mustache` +- `server-paths.mustache` diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.mustache new file mode 100644 index 000000000000..3bb4bf7fc648 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/README.mustache @@ -0,0 +1,200 @@ +# Rust API for {{{packageName}}} + +{{#appDescriptionWithNewLines}} +{{{.}}} +{{/appDescriptionWithNewLines}} + +## Overview + +This client/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}} +- Generator version: {{generatorVersion}} + +{{#infoUrl}}For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}){{/infoUrl}} + +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. +* A CLI tool to drive basic API operations from the command line. + +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. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#vendorExtensions}} + {{^x-no-client-example}} +cargo run --example client {{{operationId}}} + {{/x-no-client-example}} + {{/vendorExtensions}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}[**{{{operationIdOriginal}}}**]({{{apiDocPath}}}{{classname}}_api.md#{{{operationIdOriginal}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Documentation For Models + +{{#models}}{{#model}} - [{{{classname}}}]({{{modelDocPath}}}{{{classname}}}.md) +{{/model}}{{/models}} + +## Documentation For Authorization +{{^authMethods}}Endpoints do not require authorization.{{/authMethods}} +{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}} +{{#authMethods}} +### {{{name}}} +{{#isApiKey}}- **Type**: API key + +Example +``` + {{! TODO: Add API Key example }} +``` +{{/isApiKey}} +{{#isBasicBasic}}- **Type**: HTTP basic authentication + +Example +``` + {{! TODO: Add HTTP basic authentication }} +``` +{{/isBasicBasic}} +{{#isBasicBearer}}- **Type**: Bearer token authentication + +Example +``` + {{! TODO: Add Bearer token authentication }} +``` +{{/isBasicBearer}} +{{#isHttpSignature}}- **Type**: HTTP signature authentication +{{/isHttpSignature}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{{flow}}} +- **Authorization URL**: {{{authorizationUrl}}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - **{{{scope}}}**: {{{description}}} +{{/scopes}} + +Example +``` + {{! TODO: OAuth example }} +``` + +Or via OAuth2 module to automatically refresh tokens and perform user authentication. +``` + {{! TODO: OAuth example }} +``` +{{/isOAuth}} +{{/authMethods}} + +## Author + +{{#apiInfo}}{{#apis}}{{#-last}}{{{infoEmail}}} +{{/-last}}{{/apis}}{{/apiInfo}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/api_doc.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/api_doc.mustache new file mode 100644 index 000000000000..df9d992b7c4d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/api_doc.mustache @@ -0,0 +1,50 @@ +# {{{invokerPackage}}}{{{classname}}}_api{{#description}} +{{{.}}}{{/description}} + +All URIs are relative to *{{{basePath}}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#operations}}{{#operation}}**{{{operationIdOriginal}}}**]({{classname}}_api.md#{{{operationIdOriginal}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} +{{/operation}}{{/operations}} + +{{#operations}} +{{#operation}} +# **{{{operationIdOriginal}}}** +> {{#returnType}}{{{.}}} {{/returnType}}{{{operationIdOriginal}}}({{#authMethods}}ctx, {{/authMethods}}{{#allParams}}{{#required}}{{{paramName}}}{{^-last}}, {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}optional{{/hasOptionalParams}}) +{{{summary}}}{{#notes}} + +{{{.}}}{{/notes}} + +### Required Parameters +{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{#authMethods}} + **ctx** | **context.Context** | context containing the authentication | nil if no authentication{{/authMethods}}{{/-last}}{{/allParams}}{{#allParams}}{{#required}} + **{{{paramName}}}** | {{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{baseType}}}**]({{{baseType}}}.md){{/isPrimitiveType}}| {{{description}}} | {{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}{{/required}}{{/allParams}}{{#hasOptionalParams}} + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. +{{#allParams}}{{#-last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}{{#allParams}} + **{{{paramName}}}** | {{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{{baseType}}}**]({{{baseType}}}.md){{/isPrimitiveType}}| {{{description}}} | {{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}{{/allParams}}{{/hasOptionalParams}} + +### Return type + +{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{{returnBaseType}}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}} (empty response body){{/returnType}} + +### Authorization + +{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}} + +### HTTP request headers + + - **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}} + - **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}} + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +{{/operation}} +{{/operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/auth.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/auth.mustache new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/auth.mustache @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/bin-cli.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/bin-cli.mustache new file mode 100644 index 000000000000..0406c5c12e03 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/bin-cli.mustache @@ -0,0 +1,317 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +{{#apiHasDeleteMethods}} +use dialoguer::Confirm; +{{/apiHasDeleteMethods}} +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use {{{externCrateName}}}::{ + models, ApiNoContext, Client, ContextWrapperExt, +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{{operationId}}}Response, + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +{{! See code in RustServerCodegen if you are adding additional short option usage here. }} +#[derive(StructOpt, Debug)] +#[structopt( + name = "{{appName}}", + version = "{{version}}", + about = "CLI access to {{appName}}" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, +{{#apiHasDeleteMethods}} + + /// Don't ask for any confirmation prompts + #[allow(dead_code)] + #[structopt(short, long)] + force: bool, +{{/apiHasDeleteMethods}} +{{#hasHttpBearerMethods}} + + /// Bearer token if used for authentication + #[structopt(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env_values = true)] + bearer_token: Option, +{{/hasHttpBearerMethods}} +{{^hasHttpBearerMethods}} +{{#hasOAuthMethods}} + + /// Bearer token if used for authentication + #[structopt(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env_values = true)] + bearer_token: Option, +{{/hasOAuthMethods}} +{{/hasHttpBearerMethods}} +} + +#[derive(StructOpt, Debug)] +enum Operation { +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#summary}} + /// {{{summary}}} + {{/summary}} + {{operationId}} { + {{#allParams}} + {{#description}} + /// {{{description}}} + {{/description}} + {{^isPrimitiveType}} + #[structopt(parse(try_from_str = parse_json){{#isArray}}, long{{/isArray}})] + {{/isPrimitiveType}} + {{#isByteArray}} + #[structopt(parse(try_from_str = parse_json))] + {{/isByteArray}} + {{#isBinary}} + #[structopt(parse(try_from_str = parse_json))] + {{/isBinary}} + {{#isBoolean}} + {{#isPrimitiveType}} + {{#vendorExtensions.x-provide-cli-short-opt}} + #[structopt(short, long)] + {{/vendorExtensions.x-provide-cli-short-opt}} + {{^vendorExtensions.x-provide-cli-short-opt}} + #[structopt(long)] + {{/vendorExtensions.x-provide-cli-short-opt}} + {{/isPrimitiveType}} + {{/isBoolean}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{{dataType}}}{{^required}}>{{/required}}, + {{/allParams}} + }, + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + +{{#hasHttpBearerMethods}} + let mut auth_data: Option = None; + + if let Some(ref bearer_token) = args.bearer_token { + debug!("Using bearer token"); + auth_data = Some(AuthData::bearer(bearer_token)); + } +{{/hasHttpBearerMethods}} +{{^hasHttpBearerMethods}} + {{#hasOAuthMethods}} + let mut auth_data: Option = None; + + if let Some(ref bearer_token) = args.bearer_token { + debug!("Using bearer token"); + auth_data = Some(AuthData::bearer(bearer_token)); + } + {{/hasOAuthMethods}} +{{/hasHttpBearerMethods}} +{{^hasHttpBearerMethods}} + {{^hasOAuthMethods}} + let auth_data: Option = None; + {{/hasOAuthMethods}} +{{/hasHttpBearerMethods}} + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + Operation::{{operationId}} { + {{#allParams}} + {{paramName}}, + {{/allParams}} + } => { + {{#vendorExtensions.x-is-delete}} + prompt(args.force, "This will delete the given entry, are you sure?")?; + {{/vendorExtensions.x-is-delete}} + info!("Performing a {{operationId}} request{{^pathParams}}");{{/pathParams}}{{#pathParams}}{{#-first}} on {:?}", ({{/-first}}{{/pathParams}} + {{#pathParams}} + &{{paramName}}{{^-last}},{{/-last}} + {{#-last}} + )); + {{/-last}} + {{/pathParams}} + + let result = client.{{{vendorExtensions.x-operation-id}}}( + {{#allParams}} + {{{paramName}}}{{#isArray}}.as_ref(){{/isArray}}, + {{/allParams}} + ).await?; + debug!("Result: {:?}", result); + + match result { + {{#responses}} + {{{operationId}}}Response::{{{vendorExtensions.x-response-id}}} + {{#dataType}} + {{^hasHeaders}} + (body) + {{/hasHeaders}} + {{#hasHeaders}} + { + body, + {{/hasHeaders}} + {{/dataType}} + {{^dataType}} + {{#hasHeaders}} + { + {{/hasHeaders}} + {{/dataType}} + {{#headers}} + {{{name}}}, + {{#-last}} + } + {{/-last}} + {{/headers}} + => "{{{vendorExtensions.x-response-id}}}\n".to_string() + {{#dataType}} + + + {{/dataType}} + {{^dataType}} + {{#hasHeaders}} + + + {{/hasHeaders}} + {{^hasHeaders}} + , + {{/hasHeaders}} + {{/dataType}} + {{#dataType}} + {{^hasHeaders}} + &serde_json::to_string_pretty(&body)?, + {{/hasHeaders}} + {{#hasHeaders}} + &format!("body: {}\n", serde_json::to_string_pretty(&body)?) + + {{/hasHeaders}} + {{/dataType}} + {{#headers}} + &format!( + "{{{name}}}: {}\n", + serde_json::to_string_pretty(&{{{name}}})? + ){{^-last}} +{{/-last}}{{#-last}},{{/-last}} + {{/headers}} + {{/responses}} + } + } + {{/operation}} + {{/operations}} + {{/apis}} + {{/apiInfo}} + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} +{{#apiHasDeleteMethods}} + +fn prompt(force: bool, text: &str) -> Result<()> { + if force || Confirm::new().with_prompt(text).interact()? { + Ok(()) + } else { + Err(anyhow!("Aborting")) + } +} +{{/apiHasDeleteMethods}} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server/.cargo/config b/modules/openapi-generator/src/main/resources/rust-server-deprecated/cargo-config similarity index 100% rename from samples/server/petstore/rust-server/.cargo/config rename to modules/openapi-generator/src/main/resources/rust-server-deprecated/cargo-config diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-callbacks.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-callbacks.mustache new file mode 100644 index 000000000000..44e16903d948 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-callbacks.mustache @@ -0,0 +1,72 @@ +{{>server-imports}} +use crate::CallbackApi as Api; +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +use crate::{{{operationId}}}Response; + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + +{{#callbacks}} +{{>server-paths}} +{{/callbacks}} + +{{>server-make-service}} + +{{>server-service-header}} +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{>server-operation}} + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +{{#callbacks}} + {{#pathSet}} + _ if path.matched(paths::ID_{{PATH_ID}}) => method_not_allowed(), + {{/pathSet}} +{{/callbacks}} +{{>server-service-footer}} +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} + // {{{operationId}}} - {{{httpMethod}}} {{{path}}} + hyper::Method::{{{vendorExtensions.x-http-method}}} if path.matched(paths::ID_{{{vendorExtensions.x-path-id}}}) => Some("{{{operationId}}}"), + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + _ => None, + } + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-imports.mustache new file mode 100644 index 000000000000..1dd5de79e2b3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-imports.mustache @@ -0,0 +1,47 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + +{{#apiUsesMultipartFormData}} +use mime::Mime; +use std::io::Cursor; +use multipart::client::lazy::Multipart; +{{/apiUsesMultipartFormData}} +{{#apiUsesMultipartRelated}} +use hyper_0_10::header::{Headers, ContentType}; +use mime_multipart::{Node, Part, write_multipart}; +{{/apiUsesMultipartRelated}} + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-mod.mustache new file mode 100644 index 000000000000..9e7b94564ace --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-mod.mustache @@ -0,0 +1,360 @@ +{{>client-imports}} +use crate::{Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, + {{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + }; + +{{#hasCallbacks}} +pub mod callbacks; + +{{/hasCallbacks}} +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{>client-operation}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-operation.mustache new file mode 100644 index 000000000000..5b4aeabaeb75 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-operation.mustache @@ -0,0 +1,266 @@ + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}: String, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + param_{{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + context: &C) -> Result<{{{operationId}}}Response, ApiError> + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( +{{#isCallbackRequest}} + "{{vendorExtensions.x-path-format-string}}" +{{/isCallbackRequest}} +{{^isCallbackRequest}} + "{}{{^servers}}{{{basePathWithoutHost}}}{{/servers}}{{#servers.0}}{{{url}}}{{/servers.0}}{{vendorExtensions.x-path-format-string}}", + self.base_path +{{/isCallbackRequest}} +{{#pathParams}} + ,{{{paramName}}}=utf8_percent_encode(¶m_{{{paramName}}}.to_string(), ID_ENCODE_SET) +{{/pathParams}} +{{#vendorExtensions}} + {{#x-callback-params}} + ,{{.}}=callback_{{.}} + {{/x-callback-params}} +{{/vendorExtensions}} + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); +{{#queryParams}} + {{^required}} + if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { + {{/required}} + query_string.append_pair("{{{baseName}}}", + {{#vendorExtensions}} + {{#x-consumes-json}} + &match serde_json::to_string(¶m_{{{paramName}}}) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {e}"))), + }); + {{/x-consumes-json}} + {{^x-consumes-json}} + {{#isArray}} + ¶m_{{{paramName}}}.iter().map(ToString::to_string).collect::>().join(",")); + {{/isArray}} + {{^isArray}} + ¶m_{{{paramName}}}{{^isString}}.to_string(){{/isString}}); + {{/isArray}} + {{/x-consumes-json}} + {{/vendorExtensions}} + {{^required}} + } + {{/required}} +{{/queryParams}} +{{#authMethods}} + {{#isApiKey}} + {{#isKeyInQuery}} + if let Some(AuthData::ApiKey(ref api_key)) = (context as &dyn Has>).get().as_ref() { + query_string.append_pair("{{keyParamName}}", api_key); + } + {{/isKeyInQuery}} + {{/isApiKey}} +{{/authMethods}} + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("{{{vendorExtensions.x-http-method}}}") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; +{{>client-request-body-instance}} + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + +{{#hasAuthMethods}} + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + {{! Currently only authentication with Basic and Bearer are supported }} + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + {{#authMethods}} + {{#isBasicBasic}} + AuthData::Basic(basic_header) => { + let auth = swagger::auth::Header(basic_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + {{/isBasicBasic}} + {{#isBasicBearer}} + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + {{/isBasicBearer}} + {{#isOAuth}} + {{^isBasicBearer}} + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + {{/isBasicBearer}} + {{/isOAuth}} + {{/authMethods}} + _ => {} + } + } + +{{/hasAuthMethods}} +{{#headerParams}} +{{#-first}} + // Header parameters +{{/-first}} +{{^isMap}} +{{^required}} + #[allow(clippy::single_match)] + match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => { +{{/required}} + request.headers_mut().append( + HeaderName::from_static("{{{nameInLowerCase}}}"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_{{{paramName}}}.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header {{{paramName}}} - {e}"))); + }, + }); +{{^required}} + }, + None => {} + } +{{/required}} +{{/isMap}} +{{#isMap}} + let param_{{{paramName}}}: Option<{{{dataType}}}> = None; +{{/isMap}} + +{{/headerParams}} + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { +{{#responses}} + {{{code}}} => { +{{#headers}} + let response_{{{name}}} = match response.headers().get(HeaderName::from_static("{{{nameInLowerCase}}}")) { + Some(response_{{{name}}}) => { + let response_{{{name}}} = response_{{{name}}}.clone(); + let response_{{{name}}} = match TryInto::>::try_into(response_{{{name}}}) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header {{baseName}} for response {{code}} - {e}"))); + }, + }; + {{#required}} + response_{{{name}}}.0 + {{/required}} + {{^required}} + Some(response_{{{name}}}.0) + {{/required}} + }, + {{#required}} + None => return Err(ApiError(String::from("Required response header {{{baseName}}} for response {{{code}}} was not found."))), + {{/required}} + {{^required}} + None => None, + {{/required}} + }; + +{{/headers}} +{{#dataType}} + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + +{{>client-response-body-instance}} + + Ok({{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}} +{{^headers}} + (body) +{{/headers}} +{{#headers}} + {{#-first}} + { + body, + {{/-first}} + {{{name}}}: response_{{name}}, + {{#-last}} + } + {{/-last}} +{{/headers}} + ) +{{/dataType}} +{{^dataType}} + Ok( + {{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}} +{{#headers}} + {{#-first}} + { + {{/-first}} + {{{name}}}: response_{{name}}, + {{#-last}} + } + {{/-last}} +{{/headers}} + ) +{{/dataType}} + } +{{/responses}} + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-instance.mustache new file mode 100644 index 000000000000..7fb50831700b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-instance.mustache @@ -0,0 +1,110 @@ +{{#vendorExtensions}} + {{#x-consumes-multipart-form}} + + // Consumes multipart/form body +{{>client-request-body-multipart-form}} + {{/x-consumes-multipart-form}} + {{#x-consumes-multipart-related}} + + // Consumes multipart/related body + {{#formParams}} +{{>generate-multipart-related}} + {{/formParams}} + + let header = "multipart/related"; + request.headers_mut().insert(CONTENT_TYPE, + match HeaderValue::from_bytes( + &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() + ) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + // Add the message body to the request object. + *request.body_mut() = Body::from(body); + {{/x-consumes-multipart-related}} + {{#x-consumes-form}} + + // Consumes form body + {{#formParams}} + {{#-first}} + let mut params = vec![]; + {{/-first}} + {{^required}} + if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { + {{/required}} + {{#isArray}} + // style=form,explode=true + for param_{{{paramName}}} in param_{{{paramName}}} { + {{/isArray}} + #[allow(clippy::uninlined_format_args)] + params.push(("{{{baseName}}}", + {{^isString}} + format!("{{{vendorExtensions.x-format-string}}}", param_{{{paramName}}}) + {{/isString}} + {{#isString}} + {{#isArray}} + param_{{{paramName}}}.to_string() + {{/isArray}} + {{^isArray}} + param_{{{paramName}}} + {{/isArray}} + {{/isString}} + )); + {{#isArray}} + } + {{/isArray}} + {{^required}} + } + {{/required}} + {{#-last}} + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + {{/-last}} + {{/formParams}} + {{/x-consumes-form}} + {{#x-consumes-basic}} + + // Consumes basic body + {{#bodyParam}} + // Body parameter + {{^required}} + if let Some(param_{{{paramName}}}) = param_{{{paramName}}} { + {{/required}} + {{#vendorExtensions}} + {{#x-consumes-plain-text}} + {{#isByteArray}} + let body = param_{{{paramName}}}.0; + {{/isByteArray}} + {{^isByteArray}} + let body = param_{{{paramName}}}; + {{/isByteArray}} + {{/x-consumes-plain-text}} + {{#x-consumes-xml}} + let body = param_{{{paramName}}}.as_xml(); + {{/x-consumes-xml}} + {{#x-consumes-json}} + let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize"); + {{/x-consumes-json}} + {{/vendorExtensions}} + *request.body_mut() = Body::from(body); + {{^required}} + } + {{/required}} + + let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + {{/bodyParam}} + {{/x-consumes-basic}} +{{/vendorExtensions}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-multipart-form.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-multipart-form.mustache new file mode 100644 index 000000000000..a5806ace49ac --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-request-body-multipart-form.mustache @@ -0,0 +1,65 @@ + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); + + {{#vendorExtensions}} + {{#formParams}} + {{#-first}} + // For each parameter, encode as appropriate and add to the multipart body as a stream. + {{/-first}} + + {{^isByteArray}} + {{#jsonSchema}} + let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {e}"))), + }; + + let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec(); + let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); + + multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime)); + {{/jsonSchema}} + {{/isByteArray}} + + {{#isByteArray}} + let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec(); + + let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + Ok(mime) => mime, + Err(err) => return Err(ApiError(format!("Unable to get mime type: {err:?}"))), + }; + + let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); + + let filename = None as Option<&str> ; + multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, filename, Some({{{paramName}}}_mime)); + {{/isByteArray}} + {{/formParams}} + {{/vendorExtensions}} + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;{boundary}"); + + (body_string, multipart_header) + }; + + *request.body_mut() = Body::from(body_string); + + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) + }); diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-instance.mustache new file mode 100644 index 000000000000..6ff1719ca0e0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-instance.mustache @@ -0,0 +1,22 @@ +{{#vendorExtensions}} + {{#x-produces-bytes}} + let body = swagger::ByteArray(body.to_vec()); + {{/x-produces-bytes}} + {{^x-produces-bytes}} + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + {{#x-produces-xml}} + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::<{{{dataType}}}>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + {{/x-produces-xml}} + {{#x-produces-json}} + let body = serde_json::from_str::<{{{dataType}}}>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + {{/x-produces-json}} + {{#x-produces-plain-text}} + let body = body.to_string(); + {{/x-produces-plain-text}} + {{/x-produces-bytes}} +{{/vendorExtensions}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-multipart-related.mustache new file mode 100644 index 000000000000..3e4df32f66ef --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/client-response-body-multipart-related.mustache @@ -0,0 +1,76 @@ +// Create headers from top-level content type header. +let multipart_headers = match swagger::multipart::related::create_multipart_headers(header.headers.get(CONTENT_TYPE)) { + Ok(headers) => headers, + Err(e) => { + return Err(ApiError(e)); + } +}; + +// &*body expresses the body as a byteslice, &mut provides a +// mutable reference to that byteslice. +let nodes = match read_multipart_body(&mut&*body, &multipart_headers, false) { + Ok(nodes) => nodes, + Err(e) => { + return Err(ApiError(format!("Could not read multipart body for {{operationId}}: {e}"))); + } +}; + +{{#formParams}} +let mut param_{{{paramName}}} = None; +{{/formParams}} + +for node in nodes { + if let Node::Part(part) = node { + let content_type = part.content_type().map(|x| format!("{x}")); + match content_type.as_ref().map(|x| x.as_str()) { +{{#formParams}} + {{^isBinary}} + Some("{{{contentType}}}") if param_{{{paramName}}}.is_none() => { + // Extract JSON part. + let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); + let json_data: {{{dataType}}} = match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in JSON part: {path}"); + }) { + Ok(json_data) => json_data, + Err(e) => return Err(ApiError(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {e}"))) + }; + // Push JSON part to return object. + param_{{{paramName}}}.get_or_insert(json_data); + }, + {{/isBinary}} + {{#isBinary}} + Some("{{{contentType}}}") if param_{{{paramName}}}.is_none() => { + param_{{{paramName}}}.get_or_insert(swagger::ByteArray(part.body)); + }, + {{/isBinary}} +{{/formParams}} + Some(content_type) => { + warn!("Ignoring unexpected content type: {content_type}"); + }, + None => { + warn!("Missing content type"); + }, + } + } else { + return Err(ApiError(format!("Unexpected part in multipart body for {{operationId}}: {node:?}"))); + } +} +{{#formParams}} + {{#-first}} + +// Check that the required multipart chunks are present. + {{/-first}} + {{#required}} +let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(x) => x, + None => return Err(ApiError("Missing required multipart/related parameter {{{paramName}}}")) +}; + {{/required}} +{{/formParams}} + {{^vendorExtensions.x-consumes-basic}} + let body = {{{dataType}}} { + {{#formParams}} + {{{paramName}}}: param_{{{paramName}}}, + {{/formParams}} + }; + {{/vendorExtensions.x-consumes-basic}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/context.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/context.mustache new file mode 100644 index 000000000000..061bd4fbf2d8 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/context.mustache @@ -0,0 +1,227 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + {{#authMethods}} + {{#isBasic}} + {{#isBasicBasic}} + { + use swagger::auth::Basic; + use std::ops::Deref; + if let Some(basic) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.basic_authorization(&basic); + let auth_data = AuthData::Basic(basic); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + {{/isBasicBasic}} + {{#isBasicBearer}} + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + {{/isBasicBearer}} + {{/isBasic}} + {{#isOAuth}} + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + {{/isOAuth}} + {{#isApiKey}} + {{#isKeyInHeader}} + { + use swagger::auth::api_key_from_header; + + if let Some(header) = api_key_from_header(headers, "{{{keyParamName}}}") { + let authorization = self.inner.apikey_authorization(&header); + let auth_data = AuthData::ApiKey(header); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + {{/isKeyInHeader}} + {{#isKeyInQuery}} + { + let key = form_urlencoded::parse(request.uri().query().unwrap_or_default().as_bytes()) + .filter(|e| e.0 == "{{{keyParamName}}}") + .map(|e| e.1.clone().into_owned()) + .next(); + if let Some(key) = key { + let authorization = self.inner.apikey_authorization(&key); + let auth_data = AuthData::ApiKey(key); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + {{/isKeyInQuery}} + {{/isApiKey}} + {{/authMethods}} + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-ca.pem b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-auth.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-auth.mustache new file mode 100644 index 000000000000..07b7713d820d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-auth.mustache @@ -0,0 +1,17 @@ +use {{{externCrateName}}}::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-main.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-main.mustache new file mode 100644 index 000000000000..511739d707d1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-main.mustache @@ -0,0 +1,175 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + +{{#hasCallbacks}} +mod server; +{{/hasCallbacks}} + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use {{{externCrateName}}}::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{{operationId}}}Response, + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#vendorExtensions}} + {{^x-no-client-example}} + "{{{operationId}}}", + {{/x-no-client-example}} + {{/vendorExtensions}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("{{{serverHost}}}") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("{{{serverPort}}}") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + {{#hasAuthScopes}} + [ + {{#authMethods}} + {{#scopes}} + "{{{scope}}}", + {{/scopes}} + {{/authMethods}} + ].join::<&str>(", ") + {{/hasAuthScopes}} + {{^hasAuthScopes}} + "".to_owned() + {{/hasAuthScopes}} + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); +{{#hasCallbacks}} + + // We could do HTTPS here, but for simplicity we don't + rt.spawn(server::create("127.0.0.1:8081", false)); +{{/hasCallbacks}} + + match matches.value_of("operation") { +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#vendorExtensions}} + {{#x-no-client-example}} + /* Disabled because there's no example. + {{/x-no-client-example}} + {{/vendorExtensions}} + Some("{{{operationId}}}") => { + let result = rt.block_on(client.{{{vendorExtensions.x-operation-id}}}( + {{#allParams}} + {{{vendorExtensions.x-example}}}{{^-last}},{{/-last}} + {{/allParams}} + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + {{#vendorExtensions}} + {{#x-no-client-example}} + */ + {{/x-no-client-example}} + {{/vendorExtensions}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-server.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-server.mustache new file mode 100644 index 000000000000..126af4cf7471 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-client-server.mustache @@ -0,0 +1,40 @@ +{{>example-server-common}} +use {{{externCrateName}}}::CallbackApi; +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +use {{{externCrateName}}}::{{{operationId}}}Response; + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +use {{{externCrateName}}}::client::callbacks::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl CallbackApi for Server where C: Has + Send + Sync +{ +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{>example-server-operation}} + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-auth.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-auth.mustache new file mode 100644 index 000000000000..7e0eac398fe9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-auth.mustache @@ -0,0 +1,138 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use {{{externCrateName}}}::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + {{#hasAuthScopes}} + [ + {{#authMethods}} + {{#scopes}} + "{{{scope}}}", + {{/scopes}} + {{/authMethods}} + ].join::<&str>(", ") + {{/hasAuthScopes}} + {{^hasAuthScopes}} + "".to_owned() + {{/hasAuthScopes}} + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-chain.pem b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-common.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-common.mustache new file mode 100644 index 000000000000..ee1167be8dcb --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-common.mustache @@ -0,0 +1,94 @@ +//! Main library entry point for {{{externCrateName}}} implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use {{{externCrateName}}}::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + {{{externCrateName}}}::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-key.pem b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-main.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-main.mustache new file mode 100644 index 000000000000..58d6f9e2a65f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-main.mustache @@ -0,0 +1,28 @@ +//! Main binary entry point for {{{externCrateName}}} implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:{{{serverPort}}}"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-operation.mustache new file mode 100644 index 000000000000..aea5b6543760 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-operation.mustache @@ -0,0 +1,18 @@ +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}: String, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + context: &C) -> Result<{{{operationId}}}Response, ApiError> + { + info!("{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}({{#allParams}}{{#vendorExtensions}}{{{x-format-string}}}{{/vendorExtensions}}{{^-last}}, {{/-last}}{{/allParams}}) - X-Span-ID: {:?}"{{#allParams}}, {{{paramName}}}{{/allParams}}, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-server.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-server.mustache new file mode 100644 index 000000000000..bfa094f523c2 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/example-server-server.mustache @@ -0,0 +1,37 @@ +{{>example-server-common}} + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use {{{externCrateName}}}::{ + Api, +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{{operationId}}}Response, + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +}; +use {{{externCrateName}}}::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{>example-server-operation}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/generate-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/generate-multipart-related.mustache new file mode 100644 index 000000000000..59b647a4130c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/generate-multipart-related.mustache @@ -0,0 +1,39 @@ +{{#-first}} + let boundary = swagger::multipart::related::generate_boundary(); + let mut body_parts = vec![]; + +{{/-first}} +{{#required}} + { +{{/required}} +{{^required}} + if let Some({{{paramName}}}) = param_{{{paramName}}} { +{{/required}} + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("{{{contentType}}}".parse().unwrap())); + h.set_raw("Content-ID", vec![b"{{{baseName}}}".to_vec()]); + h + }, + {{#isBinary}} + body: {{#required}}param_{{/required}}{{{paramName}}}.0, + {{/isBinary}} + {{^isBinary}} + body: serde_json::to_string(&{{{paramName}}}) + .expect("Impossible to fail to serialize") + .into_bytes(), + {{/isBinary}} + }); + body_parts.push(part); + } +{{#-last}} + + // Write the body into a vec. + // RFC 13341 Section 7.2.1 suggests that the body should begin with a + // CRLF prior to the first boundary. The mime_multipart library doesn't + // do this, so we do it instead. + let mut body: Vec = vec![b'\r', b'\n']; + write_multipart(&mut body, &boundary, &body_parts) + .expect("Failed to write multipart body"); +{{/-last}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/gitignore b/modules/openapi-generator/src/main/resources/rust-server-deprecated/gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/header.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/header.mustache new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/header.mustache @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/lib.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/lib.mustache new file mode 100644 index 000000000000..e6d2bf190130 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/lib.mustache @@ -0,0 +1,325 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = "{{{basePathWithoutHost}}}"; +{{#appVersion}} +pub const API_VERSION: &str = "{{{.}}}"; +{{/appVersion}} + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{>response}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + context: &C) -> Result<{{{operationId}}}Response, ApiError>; + + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + ) -> Result<{{{operationId}}}Response, ApiError>; + + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + ) -> Result<{{{operationId}}}Response, ApiError> + { + let context = self.context().clone(); + self.api().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}({{#allParams}}{{{paramName}}}, {{/allParams}}&context).await + } + + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +{{#hasCallbacks}} + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{>response}} + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + +/// Callback API +#[async_trait] +pub trait CallbackApi { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}: String, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + context: &C) -> Result<{{{operationId}}}Response, ApiError>; + + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +/// Callback API without a `Context` +#[async_trait] +pub trait CallbackApiNoContext { + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{#summary}} + /// {{{.}}} +{{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}: String, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + ) -> Result<{{{operationId}}}Response, ApiError>; + + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +pub trait CallbackContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} + {{#summary}} + /// {{{.}}} + {{/summary}} + async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + &self, +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}: String, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + {{{paramName}}}: {{^required}}Option<{{/required}}{{#isArray}}&{{/isArray}}{{{dataType}}}{{^required}}>{{/required}}, +{{/allParams}} + ) -> Result<{{{operationId}}}Response, ApiError> + { + let context = self.context().clone(); + self.api().{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( +{{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}, + {{/x-callback-params}} +{{/vendorExtensions}} +{{#allParams}} + {{{paramName}}}, +{{/allParams}} + &context).await + } + + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} + +{{/hasCallbacks}} + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +{{#hasCallbacks}} +#[cfg(any(feature = "client", feature = "server"))] +{{/hasCallbacks}} +{{^hasCallbacks}} +#[cfg(feature = "server")] +{{/hasCallbacks}} +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/model_doc.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/model_doc.mustache new file mode 100644 index 000000000000..7c3ecd7c316f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/model_doc.mustache @@ -0,0 +1,11 @@ +{{#models}}{{#model}}# {{{classname}}} + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#vars}}**{{{name}}}** | {{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{^isContainer}}{{^isDateTime}}*{{/isDateTime}}{{/isContainer}}{{{dataType}}}**]({{{complexType}}}.md){{/isPrimitiveType}} | {{{description}}} | {{^required}}[optional] {{/required}}{{#isReadOnly}}[readonly] {{/isReadOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}} +{{/vars}} + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + +{{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/models.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/models.mustache new file mode 100644 index 000000000000..4dfc68f61cb0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/models.mustache @@ -0,0 +1,648 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; +{{! Don't "use" structs here - they can conflict with the names of models, and mean that the code won't compile }} +{{#models}} +{{#model}} + +{{#description}} +/// {{{.}}} +{{/description}} +{{#isEnum}} +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))]{{#xmlName}} +#[serde(rename = "{{{.}}}")]{{/xmlName}} +pub enum {{{classname}}} { +{{#allowableValues}} + {{#enumVars}} + #[serde(rename = {{{value}}})] + {{{name}}}, + {{/enumVars}} +{{/allowableValues}} +} + +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}} + } + } +} + +impl std::str::FromStr for {{{classname}}} { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { +{{#allowableValues}} + {{#enumVars}} + {{{value}}} => std::result::Result::Ok({{{classname}}}::{{{name}}}), + {{/enumVars}} +{{/allowableValues}} + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} +{{/isEnum}} +{{^isEnum}} +{{#dataType}} +#[derive(Debug, Clone, PartialEq, {{#vendorExtensions.x-partial-ord}}PartialOrd, {{/vendorExtensions.x-partial-ord}}serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +{{#xmlName}} +#[serde(rename = "{{{.}}}")] +{{/xmlName}} +pub struct {{{classname}}}({{{dataType}}}); + +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 { + x.0 + } +} + +impl std::ops::Deref for {{{classname}}} { + type Target = {{{dataType}}}; + fn deref(&self) -> &{{{dataType}}} { + &self.0 + } +} + +impl std::ops::DerefMut for {{{classname}}} { + fn deref_mut(&mut self) -> &mut {{{dataType}}} { + &mut self.0 + } +} + +{{#vendorExtensions.x-to-string-support}} +{{#vendorExtensions.x-is-string}} +impl std::string::ToString for {{{classname}}} { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for {{{classname}}} { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok({{{classname}}}(x.to_owned())) + } +} +{{/vendorExtensions.x-is-string}} +{{^vendorExtensions.x-is-string}} +/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for {{{classname}}} { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for {{{classname}}} { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok({{{classname}}}(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to {{{classname}}}: {e:?}")), + } + } +} +{{/vendorExtensions.x-is-string}} +{{/vendorExtensions.x-to-string-support}} +{{^vendorExtensions.x-to-string-support}} +/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for {{{classname}}} { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for {{{classname}}} { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing {{{classname}}} is not supported") + } +} +{{/vendorExtensions.x-to-string-support}} +{{/dataType}} +{{^dataType}} +{{#arrayModelType}} +{{#vendorExtensions}}{{#x-item-xml-name}}// Utility function for wrapping list elements when serializing xml +#[allow(non_snake_case)] +fn wrap_in_{{{x-item-xml-name}}}(item: &Vec<{{{arrayModelType}}}>, serializer: S) -> std::result::Result +where + S: serde::ser::Serializer, +{ + serde_xml_rs::wrap_primitives(item, serializer, "{{{x-item-xml-name}}}") +} + +{{/x-item-xml-name}} +{{/vendorExtensions}} +{{! vec}} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct {{{classname}}}( +{{#vendorExtensions}} +{{#x-item-xml-name}} + #[serde(serialize_with = "wrap_in_{{{x-item-xml-name}}}")] +{{/x-item-xml-name}} +{{/vendorExtensions}} + Vec<{{{arrayModelType}}}> +); + +impl std::convert::From> for {{{classname}}} { + fn from(x: Vec<{{{arrayModelType}}}>) -> Self { + {{{classname}}}(x) + } +} + +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: U) -> Self { + {{{classname}}}(Vec::<{{{arrayModelType}}}>::from_iter(u)) + } +} + +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}}}>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +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 { + self.0.iter_mut() + } +} + +impl std::ops::Deref for {{{classname}}} { + type Target = Vec<{{{arrayModelType}}}>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for {{{classname}}} { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for {{{classname}}} { + fn to_string(&self) -> String { + self.iter().map(|x| x.to_string()).collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for {{{classname}}} { + type Err = <{{{arrayModelType}}} as std::str::FromStr>::Err; + + fn from_str(s: &str) -> std::result::Result { + let mut items = vec![]; + for item in s.split(',') + { + items.push(item.parse()?); + } + std::result::Result::Ok({{{classname}}}(items)) + } +} + +{{/arrayModelType}} +{{^arrayModelType}} +{{! general struct}} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +{{#xmlName}} +#[serde(rename = "{{{.}}}")] +{{/xmlName}} +pub struct {{{classname}}} { +{{#vars}}{{#description}} /// {{{.}}} +{{/description}}{{#isEnum}} // Note: inline enums are not fully supported by openapi-generator +{{/isEnum}} + #[serde(rename = "{{{baseName}}}")] +{{#vendorExtensions}} +{{#x-item-xml-name}} + #[serde(serialize_with = "wrap_in_{{{x-item-xml-name}}}")] +{{/x-item-xml-name}} +{{/vendorExtensions}} +{{#hasValidation}} + #[validate( + {{#maxLength}} + {{#minLength}} + length(min = {{minLength}}, max = {{maxLength}}), + {{/minLength}} + {{^minLength}} + length(max = {{maxLength}}), + {{/minLength}} + {{/maxLength}} + {{^maxLength}} + {{#minLength}} + length(min = {{minLength}}), + {{/minLength}} + {{/maxLength}} + {{#pattern}} + {{^isByteArray}} + regex = "RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}", + {{/isByteArray}} + {{#isByteArray}} + custom ="validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowercase}}" + {{/isByteArray}} + {{/pattern}} + {{#maximum}} + {{#minimum}} + range(min = {{minimum}}, max = {{maximum}}), + {{/minimum}} + {{^minimum}} + range(max = {{maximum}}), + {{/minimum}} + {{/maximum}} + {{#minimum}} + {{^maximum}} + range(min = {{minimum}}), + {{/maximum}} + {{/minimum}} + {{#maxItems}} + {{#minItems}} + length(min = {{minItems}}, max = {{maxItems}}), + {{/minItems}} + {{^minItems}} + length(max = {{maxItems}}), + {{/minItems}} + {{/maxItems}} + {{^maxItems}} + {{#minItems}} + length(min = {{minItems}}), + {{/minItems}} + {{/maxItems}} + )] +{{/hasValidation}} +{{#required}} + pub {{{name}}}: {{{dataType}}}, +{{/required}} +{{^required}} +{{#isNullable}} + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] +{{/isNullable}} + #[serde(skip_serializing_if="Option::is_none")] + pub {{{name}}}: Option<{{{dataType}}}>, +{{/required}} + +{{/vars}} +} + +{{#vars}} +{{#hasValidation}} +{{#pattern}} +{{^isByteArray}} +lazy_static::lazy_static! { + static ref RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}: regex::Regex = regex::Regex::new(r"{{ pattern }}").unwrap(); +} +{{/isByteArray}} +{{#isByteArray}} +lazy_static::lazy_static! { + static ref RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}: regex::bytes::Regex = regex::bytes::Regex::new(r"{{ pattern }}").unwrap(); +} +fn validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowercase}}( + b: &swagger::ByteArray +) -> Result<(), validator::ValidationError> { + if !RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}.is_match(b) { + return Err(validator::ValidationError::new("Character not allowed")); + } + Ok(()) +} +{{/isByteArray}} +{{/pattern}} +{{/hasValidation}} +{{/vars}} + +impl {{{classname}}} { + #[allow(clippy::new_without_default)] + pub fn new({{#vars}}{{^defaultValue}}{{{name}}}: {{{dataType}}}, {{/defaultValue}}{{/vars}}) -> {{{classname}}} { + {{{classname}}} { +{{#vars}} {{#defaultValue}}{{{name}}}: {{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}{{{name}}}{{/defaultValue}}, +{{/vars}} + } + } +} + +/// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for {{{classname}}} { + fn to_string(&self) -> String { + let params: Vec> = vec![ +{{#vars}} +{{#isByteArray}} + // Skipping byte array {{baseName}} in query parameter serialization +{{/isByteArray}} +{{^isByteArray}} +{{#isBinary}} + // Skipping binary data {{baseName}} in query parameter serialization +{{/isBinary}} +{{^isBinary}} +{{#isMap}} + // Skipping map {{baseName}} in query parameter serialization +{{/isMap}} +{{^isMap}} +{{^isPrimitiveType}} + // Skipping non-primitive type {{baseName}} in query parameter serialization +{{/isPrimitiveType}} +{{#isPrimitiveType}} +{{#required}} + Some("{{{baseName}}}".to_string()), +{{^isArray}} +{{#isNullable}} + Some(self.{{{name}}}.as_ref().map_or("null".to_string(), |x| x.to_string())), +{{/isNullable}} +{{^isNullable}} + Some(self.{{{name}}}.to_string()), +{{/isNullable}} +{{/isArray}} +{{#isArray}} +{{#isNullable}} + Some(self.{{{name}}}.as_ref().map_or(vec!["null".to_string()], |x| x.iter().map(|x| x.to_string()).collect::>().join(","))), +{{/isNullable}} +{{^isNullable}} + Some(self.{{{name}}}.iter().map(|x| x.to_string()).collect::>().join(",")), +{{/isNullable}} +{{/isArray}} +{{/required}} +{{^required}} + self.{{{name}}}.as_ref().map(|{{{name}}}| { + [ + "{{{baseName}}}".to_string(), +{{^isArray}} +{{#isNullable}} + {{{name}}}.as_ref().map_or("null".to_string(), |x| x.to_string()), +{{/isNullable}} +{{^isNullable}} + {{{name}}}.to_string(), +{{/isNullable}} +{{/isArray}} +{{#isArray}} +{{#isNullable}} + {{{name}}}.as_ref().map_or("null".to_string(), |x| x.iter().map(|x| x.to_string()).collect::>().join(",")), +{{/isNullable}} +{{^isNullable}} + {{{name}}}.iter().map(|x| x.to_string()).collect::>().join(","), +{{/isNullable}} +{{/isArray}} + ].join(",") + }), +{{/required}} +{{/isPrimitiveType}} +{{/isMap}} +{{/isBinary}} +{{/isByteArray}} +{{/vars}} + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for {{{classname}}} { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + {{#vars}} + pub {{{name}}}: Vec<{{{dataType}}}>, + {{/vars}} + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing {{{classname}}}".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + {{#vars}} + {{#isBinary}} + "{{{baseName}}}" => return std::result::Result::Err("Parsing binary data in this style is not supported in {{{classname}}}".to_string()), + {{/isBinary}} + {{^isBinary}} + {{#isByteArray}} + "{{{baseName}}}" => return std::result::Result::Err("Parsing binary data in this style is not supported in {{{classname}}}".to_string()), + {{/isByteArray}} + {{^isByteArray}} + {{#isContainer}} + "{{{baseName}}}" => return std::result::Result::Err("Parsing a container in this style is not supported in {{{classname}}}".to_string()), + {{/isContainer}} + {{^isContainer}} + {{#isNullable}} + "{{{baseName}}}" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in {{{classname}}}".to_string()), + {{/isNullable}} + {{^isNullable}} + #[allow(clippy::redundant_clone)] + "{{{baseName}}}" => intermediate_rep.{{{name}}}.push(<{{{dataType}}} as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?), + {{/isNullable}} + {{/isContainer}} + {{/isByteArray}} + {{/isBinary}} + {{/vars}} + _ => return std::result::Result::Err("Unexpected key while parsing {{{classname}}}".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok({{{classname}}} { + {{#vars}} + {{#isNullable}} + {{{name}}}: std::result::Result::Err("Nullable types not supported in {{{classname}}}".to_string())?, + {{/isNullable}} + {{^isNullable}} + {{{name}}}: intermediate_rep.{{{name}}}.into_iter().next(){{#required}}.ok_or_else(|| "{{{baseName}}} missing in {{{classname}}}".to_string())?{{/required}}, + {{/isNullable}} + {{/vars}} + }) + } +} +{{/arrayModelType}} +{{/dataType}} +{{/isEnum}} + +// Methods for converting between header::IntoHeaderValue<{{{classname}}}> and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue<{{{classname}}}>) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for {{classname}} - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue<{{{classname}}}> { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match <{{{classname}}} as std::str::FromStr>::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into {{classname}} - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec<{{{classname}}}> = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match <{{{classname}}} as std::str::FromStr>::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into {{classname}} - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} +{{#usesXml}} +{{#usesXmlNamespaces}} +{{#xmlNamespace}} + +impl {{{classname}}} { + /// Associated constant for this model's XML namespace. + #[allow(dead_code)] + pub const NAMESPACE: &'static str = "{{{xmlNamespace}}}"; +} +{{/xmlNamespace}} +{{/usesXmlNamespaces}} + +impl {{{classname}}} { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + {{#xmlNamespace}} + let mut namespaces = std::collections::BTreeMap::new(); + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), Self::NAMESPACE.to_string()); + serde_xml_rs::to_string_with_namespaces(&self, namespaces).expect("impossible to fail to serialize") + {{/xmlNamespace}} + {{^xmlNamespace}} + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + {{/xmlNamespace}} + } +} +{{/usesXml}} +{{/model}} +{{/models}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/openapi.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/openapi.mustache new file mode 100644 index 000000000000..34fbb53f3317 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/openapi.mustache @@ -0,0 +1 @@ +{{{openapi-yaml}}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/response.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/response.mustache new file mode 100644 index 000000000000..ac74c0b4e2a3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/response.mustache @@ -0,0 +1,60 @@ +#[derive(Debug, PartialEq, Serialize, Deserialize)] +{{#vendorExtensions.x-must-use-response}} +#[must_use] +{{/vendorExtensions.x-must-use-response}} +pub enum {{{operationId}}}Response { +{{#responses}} + {{#message}} + /// {{{.}}}{{/message}} + {{#vendorExtensions}} + {{{x-response-id}}} + {{/vendorExtensions}} + {{^dataType}} + {{#hasHeaders}} + { + {{/hasHeaders}} + {{/dataType}} + {{#dataType}} + {{^hasHeaders}} + {{#vendorExtensions}} + {{#x-produces-plain-text}} + (String) + {{/x-produces-plain-text}} + {{^x-produces-plain-text}} + ({{{dataType}}}) + {{/x-produces-plain-text}} + {{/vendorExtensions}} + {{/hasHeaders}} + {{#hasHeaders}} + { + {{#vendorExtensions}} + {{#x-produces-plain-text}} + body: String, + {{/x-produces-plain-text}} + {{^x-produces-plain-text}} + body: {{{dataType}}}, + {{/x-produces-plain-text}} + {{/vendorExtensions}} + {{/hasHeaders}} + {{/dataType}} + {{#headers}} + {{{name}}}: + {{^required}} + Option< + {{/required}} + {{{dataType}}} + {{^required}} + > + {{/required}} + {{^-last}} + , + {{/-last}} + {{#-last}} + } + {{/-last}} + {{/headers}} + {{^-last}} + , + {{/-last}} +{{/responses}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-callbacks.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-callbacks.mustache new file mode 100644 index 000000000000..2c95e530895d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-callbacks.mustache @@ -0,0 +1,224 @@ +{{>client-imports}} +use crate::CallbackApi; +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +use crate::{{{operationId}}}Response; + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client") + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `new_http`, `new_https` + /// and `new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn new_with_connector(connector: Connector) -> Self + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Self { + client_service, + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + pub fn new_http() -> Self { + let http_connector = Connector::builder().build(); + Self::new_with_connector(http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server. + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + pub fn new_https() -> Result + { + let https_connector = Connector::builder().https().build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a TLS connection to the server. + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https() -> Result + { + let https_connector = Connector::builder().https().build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a TLS connection to the server, pinning the certificate + /// + /// # Arguments + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https_pinned( + ca_certificate: CA, + ) -> Result where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https_mutual( + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build()?; + Ok(Self::new_with_connector(https_connector)) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn new_with_client_service( + client_service: S, + ) -> Self { + Client { + client_service, + marker: PhantomData, + } + } +} + +#[async_trait] +impl CallbackApi for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Clone + Send + Sync, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + {{#callbacks}} + {{#urls}} + {{#requests}} +{{>client-operation}} + {{/requests}} + {{/urls}} + {{/callbacks}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-imports.mustache new file mode 100644 index 000000000000..305b5440e327 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-imports.mustache @@ -0,0 +1,33 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; +{{#apiUsesMultipartRelated}} +use hyper_0_10::header::{Headers, ContentType}; +use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; +use mime_multipart::{read_multipart_body, Node, Part}; +{{/apiUsesMultipartRelated}} +{{#apiUsesMultipartFormData}} +use multipart::server::Multipart; +use multipart::server::save::{PartialReason, SaveResult}; +{{/apiUsesMultipartFormData}} + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-make-service.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-make-service.mustache new file mode 100644 index 000000000000..7471c9c2278c --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-make-service.mustache @@ -0,0 +1,60 @@ + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + api_impl: T, +{{#apiUsesMultipartFormData}} + multipart_form_size_limit: Option, +{{/apiUsesMultipartFormData}} + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, +{{#apiUsesMultipartFormData}} + multipart_form_size_limit: Some(8 * 1024 * 1024), +{{/apiUsesMultipartFormData}} + marker: PhantomData + } + } +{{#apiUsesMultipartFormData}} + + /// Configure size limit when inspecting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +{{/apiUsesMultipartFormData}} +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()){{^apiUsesMultipartFormData}};{{/apiUsesMultipartFormData}} +{{#apiUsesMultipartFormData}} + .multipart_form_size_limit(self.multipart_form_size_limit); +{{/apiUsesMultipartFormData}} + + future::ok(service) + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-mod.mustache new file mode 100644 index 000000000000..4111630d6e3f --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-mod.mustache @@ -0,0 +1,47 @@ +{{>server-imports}} +use crate::{Api{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}, + {{{operationId}}}Response{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} +}; + +mod server_auth; + +{{#hasCallbacks}} +pub mod callbacks; + +{{/hasCallbacks}} +{{>server-paths}} +{{>server-make-service}} +{{>server-service-header}} +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} +{{>server-operation}} + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} +{{#pathSet}} + _ if path.matched(paths::ID_{{PATH_ID}}) => method_not_allowed(), +{{/pathSet}} +{{>server-service-footer}} +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { +{{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + // {{{operationId}}} - {{{httpMethod}}} {{{path}}} + hyper::Method::{{{vendorExtensions.x-http-method}}} if path.matched(paths::ID_{{{vendorExtensions.x-path-id}}}) => Some("{{{operationId}}}"), + {{/operation}} + {{/operations}} + {{/apis}} +{{/apiInfo}} + _ => None, + } + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-operation.mustache new file mode 100644 index 000000000000..c9a67fc39a46 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-operation.mustache @@ -0,0 +1,318 @@ + // {{{operationId}}} - {{{httpMethod}}} {{{path}}} + hyper::Method::{{vendorExtensions.x-http-method}} if path.matched(paths::ID_{{vendorExtensions.x-path-id}}) => { +{{#hasAuthMethods}} + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + {{#authMethods}} + {{#isOAuth}} + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + {{#scopes}} + "{{{scope}}}".to_string(), // {{{description}}} + {{/scopes}} + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + {{/isOAuth}} + {{/authMethods}} + } + +{{/hasAuthMethods}} +{{#vendorExtensions}} + {{#x-has-path-params}} + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_{{{x-path-id}}} + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE {{{x-path-id}}} in set but failed match against \"{}\"", path, paths::REGEX_{{{x-path-id}}}.as_str()) + ); + + {{/x-has-path-params}} +{{/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 Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter {{{baseName}}}: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + +{{/pathParams}} +{{#vendorExtensions}} + {{#x-callback-params}} + let callback_{{.}} = path_params["{{{.}}}"].to_string(); + {{/x-callback-params}} +{{/vendorExtensions}} +{{#headerParams}} + {{#-first}} + // Header parameters + {{/-first}} + let param_{{{paramName}}} = headers.get(HeaderName::from_static("{{{nameInLowerCase}}}")); + + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(v) => match header::IntoHeaderValue::<{{{dataType}}}>::try_from((*v).clone()) { + Ok(result) => +{{#required}} + result.0, +{{/required}} +{{^required}} + Some(result.0), +{{/required}} + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header {{{baseName}}} - {err}"))) + .expect("Unable to create Bad Request response for invalid header {{{baseName}}}")); + + }, + }, + None => { +{{#required}} + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required header {{{baseName}}}")) + .expect("Unable to create Bad Request response for missing required header {{{baseName}}}")); +{{/required}} +{{^required}} + None +{{/required}} + } + }; + {{#-last}} + + {{/-last}} +{{/headerParams}} +{{#queryParams}} + {{#-first}} + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + {{/-first}} + let param_{{{paramName}}} = query_params.iter().filter(|e| e.0 == "{{{baseName}}}").map(|e| e.1.clone()) + {{#isArray}} + {{^vendorExtensions.x-consumes-json}} + .filter_map(|param_{{{paramName}}}| param_{{{paramName}}}.parse().ok()) + .collect::>(); + {{^required}} + let param_{{{paramName}}} = if !param_{{{paramName}}}.is_empty() { + Some(param_{{{paramName}}}) + } else { + None + }; + {{/required}} + {{/vendorExtensions.x-consumes-json}} + {{#vendorExtensions.x-consumes-json}} + .next(); + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => { + let param_{{{paramName}}} = + serde_json::from_str::<{{{dataType}}}> + (¶m_{{{paramName}}}); + match param_{{{paramName}}} { + Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")), + } + }, + None => None, + }; + {{#required}} + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => param_{{{paramName}}}, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter {{{baseName}}}")) + .expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")), + }; + {{/required}} + {{/vendorExtensions.x-consumes-json}} + {{/isArray}} + {{^isArray}} + .next(); + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => { + let param_{{{paramName}}} = + {{#vendorExtensions.x-consumes-json}} + serde_json::from_str::<{{{dataType}}}> + {{/vendorExtensions.x-consumes-json}} + {{^vendorExtensions.x-consumes-json}} + <{{{dataType}}} as std::str::FromStr>::from_str + {{/vendorExtensions.x-consumes-json}} + (¶m_{{{paramName}}}); + match param_{{{paramName}}} { + Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")), + } + }, + None => None, + }; + {{#required}} + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => param_{{{paramName}}}, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter {{{baseName}}}")) + .expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")), + }; + {{/required}} + {{/isArray}} + {{#-last}} + + {{/-last}} +{{/queryParams}} +{{#vendorExtensions.x-has-request-body}} + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + {{^vendorExtensions.x-consumes-multipart-form}} + {{^vendorExtensions.x-consumes-form}} + {{^bodyParam.vendorExtensions.x-consumes-plain-text}} + let mut unused_elements : Vec = vec![]; + {{/bodyParam.vendorExtensions.x-consumes-plain-text}} + {{/vendorExtensions.x-consumes-form}} + {{/vendorExtensions.x-consumes-multipart-form}} +{{>server-request-body-instance}} +{{/vendorExtensions.x-has-request-body}} + let result = api_impl.{{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( + {{#vendorExtensions}} + {{#x-callback-params}} + callback_{{.}}, + {{/x-callback-params}} + {{/vendorExtensions}} + {{#allParams}} + param_{{{paramName}}}{{#isArray}}.as_ref(){{/isArray}}, + {{/allParams}} + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + +{{#vendorExtensions.x-has-request-body}} + {{^vendorExtensions.x-consumes-multipart-form}} + {{^vendorExtensions.x-consumes-form}} + {{^bodyParam.vendorExtensions.x-consumes-plain-text}} + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + {{/bodyParam.vendorExtensions.x-consumes-plain-text}} + {{/vendorExtensions.x-consumes-form}} + {{/vendorExtensions.x-consumes-multipart-form}} +{{/vendorExtensions.x-has-request-body}} + match result { + Ok(rsp) => match rsp { +{{#responses}} + {{{operationId}}}Response::{{#vendorExtensions}}{{x-response-id}}{{/vendorExtensions}} +{{#dataType}} +{{^headers}} + (body) +{{/headers}} +{{#headers}} +{{#-first}} + { + body, +{{/-first}} + {{{name}}}{{^-last}},{{/-last}} +{{#-last}} + } +{{/-last}} +{{/headers}} +{{/dataType}} +{{^dataType}} +{{#headers}} +{{#-first}} + { +{{/-first}} + {{{name}}}{{^-last}},{{/-last}} +{{#-last}} + } +{{/-last}} +{{/headers}} +{{/dataType}} + => { + *response.status_mut() = StatusCode::from_u16({{{code}}}).expect("Unable to turn {{{code}}} into a StatusCode"); +{{#headers}} + + {{^required}} + if let Some({{{name}}}) = {{{name}}} { + {{/required}} + let {{{name}}} = match header::IntoHeaderValue({{{name}}}).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling {{name}} header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("{{{nameInLowerCase}}}"), + {{name}} + ); + {{^required}} + } + {{/required}} +{{/headers}} +{{>server-response-body-instance}} + }, +{{/responses}} + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) +{{#vendorExtensions.x-has-request-body}} + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } +{{/vendorExtensions.x-has-request-body}} + }, diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-paths.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-paths.mustache new file mode 100644 index 000000000000..c5297d058d26 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-paths.mustache @@ -0,0 +1,23 @@ +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ +{{#pathSet}} + r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}"{{^-last}},{{/-last}} +{{/pathSet}} + ]) + .expect("Unable to create global regex set"); + } +{{#pathSet}} + pub(crate) static ID_{{{PATH_ID}}}: usize = {{{index}}}; +{{#hasPathParams}} + lazy_static! { + pub static ref REGEX_{{{PATH_ID}}}: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^{{{basePathWithoutHost}}}{{{pathRegEx}}}") + .expect("Unable to create regex for {{{PATH_ID}}}"); + } +{{/hasPathParams}} +{{/pathSet}} +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-basic.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-basic.mustache new file mode 100644 index 000000000000..acc6b5737343 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-basic.mustache @@ -0,0 +1,52 @@ + {{#vendorExtensions}} + let param_{{{paramName}}}: Option<{{{dataType}}}> = if !body.is_empty() { + {{#x-consumes-xml}} + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + {{/x-consumes-xml}} + {{#x-consumes-json}} + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + {{/x-consumes-json}} + {{^x-consumes-plain-text}} + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_{{{paramName}}}) => param_{{{paramName}}}, + {{#required}} + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema")), + {{/required}} + {{^required}} + Err(_) => None, + {{/required}} + } + {{/x-consumes-plain-text}} + {{#x-consumes-plain-text}} + {{#isByteArray}} + Some(swagger::ByteArray(body.to_vec())) + {{/isByteArray}} + {{#isString}} + match String::from_utf8(body.to_vec()) { + Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8")), + } + {{/isString}} + {{/x-consumes-plain-text}} + {{/vendorExtensions}} + } else { + None + }; + {{#required}} + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(param_{{{paramName}}}) => param_{{{paramName}}}, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter {{{baseName}}}")) + .expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}")), + }; + {{/required}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-form.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-form.mustache new file mode 100644 index 000000000000..24021a86b7f0 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-form.mustache @@ -0,0 +1,24 @@ +{{#vendorExtensions}} + {{#formParams}} + {{#-first}} + // Form parameters + {{/-first}} + let param_{{{paramName}}} = + {{^isContainer}} + {{#vendorExtensions}} + {{{x-example}}}; + {{/vendorExtensions}} + {{/isContainer}} + {{#isArray}} + {{#required}} + Vec::new(); + {{/required}} + {{^required}} + None; + {{/required}} + {{/isArray}} + {{#isMap}} + None; + {{/isMap}} + {{/formParams}} +{{/vendorExtensions}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-instance.mustache new file mode 100644 index 000000000000..4fea15ea52c3 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-instance.mustache @@ -0,0 +1,20 @@ +{{#vendorExtensions}} + {{#x-consumes-multipart}} + {{#x-consumes-multipart-related}} +{{>server-request-body-multipart-related}} + {{/x-consumes-multipart-related}} + {{^x-consumes-multipart-related}} + {{^bodyParams}} +{{>server-request-body-multipart-form}} + {{/bodyParams}} + {{/x-consumes-multipart-related}} + {{/x-consumes-multipart}} + {{^x-consumes-multipart}} + {{#bodyParams}} +{{>server-request-body-basic}} + {{/bodyParams}} + {{^bodyParams}} +{{>server-request-body-form}} + {{/bodyParams}} + {{/x-consumes-multipart}} +{{/vendorExtensions}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-form.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-form.mustache new file mode 100644 index 000000000000..e39b073a6bb1 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-form.mustache @@ -0,0 +1,98 @@ + let boundary = match swagger::multipart::form::boundary(&headers) { + Some(boundary) => boundary.to_string(), + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Couldn't find valid multipart body".to_string())) + .expect("Unable to create Bad Request response for incorrect boundary")), + }; + + use std::io::Read; + + // Read Form Parameters from body + let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary) + .save() + .size_limit(multipart_form_size_limit) + .temp() + { + SaveResult::Full(entries) => { + entries + }, + SaveResult::Partial(_, PartialReason::CountLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .expect("Unable to create Bad Request response due to excessive parts")) + }, + SaveResult::Partial(_, PartialReason::SizeLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive data".to_string())) + .expect("Unable to create Bad Request response due to excessive data")) + }, + SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to invalid data".to_string())) + .expect("Unable to create Bad Request response due to invalid data")) + }, + SaveResult::Partial(_, PartialReason::IoError(_)) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process message part due an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + SaveResult::Error(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + }; + {{#formParams}} + let field_{{{paramName}}} = entries.fields.remove("{{{paramName}}}"); + let param_{{{paramName}}} = match field_{{{paramName}}} { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for {{{paramName}}}"); + {{^required}} + Some({ + {{/required}} + {{#isByteArray}} + let mut data = vec![]; + reader.read_to_end(&mut data).expect("Reading saved binary data should never fail"); + swagger::ByteArray(data) + {{/isByteArray}} + {{^isByteArray}} + {{#jsonSchema}} + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let {{{paramName}}}_model: {{{dataType}}} = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("{{{paramName}}} data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) + } + }; + {{{paramName}}}_model + {{/jsonSchema}} + {{/isByteArray}} + {{^required}} + }) + {{/required}} + }, + None => { + {{#required}} + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required form parameter {{{paramName}}}".to_string())) + .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) + {{/required}} + {{^required}} + None + {{/required}} + } + }; + {{/formParams}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-related.mustache new file mode 100644 index 000000000000..ccc08f2f515b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-request-body-multipart-related.mustache @@ -0,0 +1,86 @@ + // Get multipart chunks. + + // Create headers from top-level content type header. + let multipart_headers = match swagger::multipart::related::create_multipart_headers(headers.get(CONTENT_TYPE)) { + Ok(headers) => headers, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(e)) + .expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}")); + } + }; + + // &*body expresses the body as a byteslice, &mut provides a + // mutable reference to that byteslice. + let nodes = match read_multipart_body(&mut&*body, &multipart_headers, false) { + Ok(nodes) => nodes, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Could not read multipart body for {{operationId}}: {e}"))) + .expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}")); + } + }; + +{{#formParams}} + let mut param_{{{paramName}}} = None; +{{/formParams}} + + for node in nodes { + if let Node::Part(part) = node { + let content_type = part.content_type().map(|x| format!("{x}")); + match content_type.as_deref() { +{{#formParams}} + {{^isBinary}} + Some("{{{contentType}}}") if param_{{{paramName}}}.is_none() => { + // Extract JSON part. + let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); + let json_data: {{dataType}} = match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in JSON part: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(json_data) => json_data, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema")) + }; + // Push JSON part to return object. + param_{{{paramName}}}.get_or_insert(json_data); + }, + {{/isBinary}} + {{#isBinary}} + Some("{{{contentType}}}") if param_{{{paramName}}}.is_none() => { + param_{{{paramName}}}.get_or_insert(swagger::ByteArray(part.body)); + }, + {{/isBinary}} +{{/formParams}} + Some(content_type) => { + warn!("Ignoring unexpected content type: {content_type}"); + unused_elements.push(content_type.to_string()); + }, + None => { + warn!("Missing content type"); + }, + } + } else { + unimplemented!("No support for handling unexpected parts"); + // unused_elements.push(); + } + } +{{#formParams}} + {{#-first}} + + // Check that the required multipart chunks are present. + {{/-first}} + {{#required}} + let param_{{{paramName}}} = match param_{{{paramName}}} { + Some(x) => x, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required multipart/related parameter {{{paramName}}}".to_string())) + .expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema")) + }; + {{/required}} +{{/formParams}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-response-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-response-body-instance.mustache new file mode 100644 index 000000000000..9bb648c525f7 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-response-body-instance.mustache @@ -0,0 +1,50 @@ +{{#dataType}} + {{#vendorExtensions}} + {{^x-produces-multipart-related}} + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("{{{x-mime-type}}}") + .expect("Unable to create Content-Type header for {{{x-mime-type}}}")); + {{/x-produces-multipart-related}} + {{#x-produces-xml}} + // XML Body + {{^x-has-namespace}} + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + {{/x-has-namespace}} + {{#x-has-namespace}} + let mut namespaces = std::collections::BTreeMap::new(); + + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), {{{dataType}}}::NAMESPACE.to_string()); + let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize"); + {{/x-has-namespace}} + {{/x-produces-xml}} + {{#x-produces-json}} + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + {{/x-produces-json}} + {{#x-produces-bytes}} + // Binary Body + let body = body.0; + {{/x-produces-bytes}} + {{#x-produces-plain-text}} + // Plain text Body + let body = body; + {{/x-produces-plain-text}} + {{#x-produces-multipart-related}} + // multipart/related Body + {{#formParams}} + let param_{{{paramName}}} = body.{{{paramName}}}; + {{/formParams}} + {{#formParams}} +{{>generate-multipart-related}} + let header = "multipart/related"; + response.headers_mut().insert(CONTENT_TYPE, + HeaderValue::from_bytes( + &["multipart/related; boundary=".as_bytes(), &boundary].concat()) + .expect("Unable to create Content-Type header for multipart/related")); + {{/formParams}} + {{/x-produces-multipart-related}} + {{/vendorExtensions}} + *response.body_mut() = Body::from(body); +{{/dataType}} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-server_auth.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-server_auth.mustache new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-server_auth.mustache @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-footer.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-footer.mustache new file mode 100644 index 000000000000..793cd99e5cca --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-footer.mustache @@ -0,0 +1,14 @@ + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, +{{#apiUsesMultipartFormData}} + self.multipart_form_size_limit, +{{/apiUsesMultipartFormData}} + )) + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-header.mustache b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-header.mustache new file mode 100644 index 000000000000..997b5b5c9f0e --- /dev/null +++ b/modules/openapi-generator/src/main/resources/rust-server-deprecated/server-service-header.mustache @@ -0,0 +1,94 @@ +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + api_impl: T, +{{#apiUsesMultipart}} + multipart_form_size_limit: Option, +{{/apiUsesMultipart}} + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, +{{#apiUsesMultipart}} + multipart_form_size_limit: Some(8 * 1024 * 1024), +{{/apiUsesMultipart}} + marker: PhantomData + } + } +{{#apiUsesMultipart}} + + /// Configure size limit when extracting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +{{/apiUsesMultipart}} +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), +{{#apiUsesMultipart}} + multipart_form_size_limit: Some(8 * 1024 * 1024), +{{/apiUsesMultipart}} + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), +{{#apiUsesMultipartFormData}} + multipart_form_size_limit: Option, +{{/apiUsesMultipartFormData}} + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + {{! + This match statement is duplicated below in `parse_operation_id()`. + Please update both places if changing how this code is autogenerated. + }} + match method { diff --git a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache index cec9e012796a..12fc2bebcb97 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache @@ -34,14 +34,11 @@ homepage = "{{.}}" [features] default = ["client", "server"] client = [ -{{#apiUsesMultipart}} - "mime_0_2", -{{/apiUsesMultipart}} {{#apiUsesMultipartFormData}} "multipart", "multipart/client", "swagger/multipart_form", {{/apiUsesMultipartFormData}} {{#apiUsesMultipartRelated}} - "hyper_0_10", "mime_multipart", "swagger/multipart_related", + "mime_multipart", "swagger/multipart_related", {{/apiUsesMultipartRelated}} {{#usesUrlEncodedForm}} "serde_urlencoded", @@ -50,17 +47,14 @@ client = [ "serde_ignored", "regex", "percent-encoding", "lazy_static", {{/hasCallbacks}} {{! Anything added to the list below, should probably be added to the callbacks list below }} - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ -{{#apiUsesMultipart}} - "mime_0_2", -{{/apiUsesMultipart}} {{#apiUsesMultipartFormData}} "multipart", "multipart/server", "swagger/multipart_form", {{/apiUsesMultipartFormData}} {{#apiUsesMultipartRelated}} - "hyper_0_10", "mime_multipart", "swagger/multipart_related", + "mime_multipart", "swagger/multipart_related", {{/apiUsesMultipartRelated}} {{#hasCallbacks}} "native-tls", "hyper-openssl", "hyper-tls", "openssl", @@ -72,30 +66,31 @@ cli = [ {{#apiHasDeleteMethods}} "dialoguer", {{/apiHasDeleteMethods}} - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition {{#usesXml}} @@ -103,60 +98,62 @@ validator = { version = "0.16", features = ["derive"] } # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} {{/usesXml}} -{{#apiUsesMultipart}} -mime_0_2 = { package = "mime", version = "0.2.6", optional = true } -{{/apiUsesMultipart}} {{#apiUsesMultipartFormData}} -multipart = { version = "0.16", default-features = false, optional = true } +multipart = { version = "0.18", default-features = false, optional = true } {{/apiUsesMultipartFormData}} {{#apiUsesUuid}} -uuid = {version = "1.3.1", features = ["serde", "v4"]} +uuid = { version = "1.17.0", features = ["serde", "v4"]} {{/apiUsesUuid}} # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } {{#apiUsesMultipartRelated}} -mime_multipart = {version = "0.5", optional = true} -hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} +mime_multipart = { version = "0.10", optional = true, package = "mime-multipart-hyper1" } {{/apiUsesMultipartRelated}} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific {{#usesUrlEncodedForm}} -serde_urlencoded = {version = "0.6.1", optional = true} +serde_urlencoded = { version = "0.6.1", optional = true } {{/usesUrlEncodedForm}} +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } {{#apiHasDeleteMethods}} dialoguer = { version = "0.8", optional = true } {{/apiHasDeleteMethods}} # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/modules/openapi-generator/src/main/resources/rust-server/auth.mustache b/modules/openapi-generator/src/main/resources/rust-server/auth.mustache index d2b1481eeb81..f363db66d495 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/auth.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/auth.mustache @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/modules/openapi-generator/src/main/resources/rust-server/bin-cli.mustache b/modules/openapi-generator/src/main/resources/rust-server/bin-cli.mustache index 0406c5c12e03..45d6ecc6c1e3 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/bin-cli.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/bin-cli.mustache @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; {{#apiHasDeleteMethods}} use dialoguer::Confirm; {{/apiHasDeleteMethods}} @@ -19,7 +20,6 @@ use {{{externCrateName}}}::{ {{/apiInfo}} }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -30,65 +30,65 @@ type ClientContext = swagger::make_context_ty!( ); {{! See code in RustServerCodegen if you are adding additional short option usage here. }} -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "{{appName}}", version = "{{version}}", about = "CLI access to {{appName}}" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, {{#apiHasDeleteMethods}} /// Don't ask for any confirmation prompts #[allow(dead_code)] - #[structopt(short, long)] + #[clap(short, long)] force: bool, {{/apiHasDeleteMethods}} {{#hasHttpBearerMethods}} /// Bearer token if used for authentication - #[structopt(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env_values = true)] + #[arg(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env = true)] bearer_token: Option, {{/hasHttpBearerMethods}} {{^hasHttpBearerMethods}} {{#hasOAuthMethods}} /// Bearer token if used for authentication - #[structopt(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env_values = true)] + #[arg(env = "{{#lambda.uppercase}}{{externCrateName}}{{/lambda.uppercase}}_BEARER_TOKEN", hide_env = true)] bearer_token: Option, {{/hasOAuthMethods}} {{/hasHttpBearerMethods}} } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { {{#apiInfo}} {{#apis}} @@ -103,21 +103,21 @@ enum Operation { /// {{{description}}} {{/description}} {{^isPrimitiveType}} - #[structopt(parse(try_from_str = parse_json){{#isArray}}, long{{/isArray}})] + #[clap(value_parser = parse_json::<{{{dataType}}}>{{#isArray}}, long{{/isArray}})] {{/isPrimitiveType}} {{#isByteArray}} - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::<{{{dataType}}}>)] {{/isByteArray}} {{#isBinary}} - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::<{{{dataType}}}>)] {{/isBinary}} {{#isBoolean}} {{#isPrimitiveType}} {{#vendorExtensions.x-provide-cli-short-opt}} - #[structopt(short, long)] + #[clap(short, long)] {{/vendorExtensions.x-provide-cli-short-opt}} {{^vendorExtensions.x-provide-cli-short-opt}} - #[structopt(long)] + #[clap(long)] {{/vendorExtensions.x-provide-cli-short-opt}} {{/isPrimitiveType}} {{/isBoolean}} @@ -165,7 +165,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -177,7 +177,7 @@ async fn main() -> Result<()> { if let Some(ref bearer_token) = args.bearer_token { debug!("Using bearer token"); - auth_data = Some(AuthData::bearer(bearer_token)); + auth_data = AuthData::bearer(bearer_token); } {{/hasHttpBearerMethods}} {{^hasHttpBearerMethods}} @@ -186,7 +186,7 @@ async fn main() -> Result<()> { if let Some(ref bearer_token) = args.bearer_token { debug!("Using bearer token"); - auth_data = Some(AuthData::bearer(bearer_token)); + auth_data = AuthData::bearer(bearer_token); } {{/hasOAuthMethods}} {{/hasHttpBearerMethods}} @@ -312,6 +312,6 @@ fn prompt(force: bool, text: &str) -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/modules/openapi-generator/src/main/resources/rust-server/cargo-config b/modules/openapi-generator/src/main/resources/rust-server/cargo-config index b8acc9c00c8c..df91f0f117f3 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/cargo-config +++ b/modules/openapi-generator/src/main/resources/rust-server/cargo-config @@ -6,7 +6,8 @@ rustflags = [ "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed - "-W", "unsafe_code", # usage of `unsafe` code + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code "-W", "unused_qualifications", # detects unnecessarily qualified names diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache index d2a4b3fcc252..649de2d79b39 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-imports.mustache @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; {{#apiUsesMultipartFormData}} use mime::Mime; @@ -25,7 +28,7 @@ use std::io::Cursor; use multipart::client::lazy::Multipart; {{/apiUsesMultipartFormData}} {{#apiUsesMultipartRelated}} -use hyper_0_10::header::{Headers, ContentType}; +use hyper::header::HeaderMap; use mime_multipart::{Node, Part, write_multipart}; {{/apiUsesMultipartRelated}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache index c49bdd656df7..0c409fdbf302 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-mod.mustache @@ -22,15 +22,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -47,8 +46,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -60,8 +58,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -75,8 +72,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -90,7 +98,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -99,8 +107,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -112,26 +120,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -142,7 +143,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -155,13 +156,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -178,13 +179,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -195,18 +207,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -219,7 +242,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -240,7 +263,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -268,8 +291,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -331,22 +353,23 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } {{#apiInfo}} {{#apis}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache index a5f96e3dbfaf..caf7261adb35 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-operation.mustache @@ -1,3 +1,4 @@ + #[allow(clippy::vec_init_then_push)] async fn {{#vendorExtensions}}{{{x-operation-id}}}{{/vendorExtensions}}( &self, {{#vendorExtensions}} @@ -11,6 +12,7 @@ context: &C) -> Result<{{{operationId}}}Response, ApiError> { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( {{#isCallbackRequest}} "{{vendorExtensions.x-path-format-string}}" @@ -41,7 +43,7 @@ {{#x-consumes-json}} &match serde_json::to_string(¶m_{{{paramName}}}) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {e}"))), }); {{/x-consumes-json}} {{^x-consumes-json}} @@ -75,65 +77,60 @@ let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("{{{vendorExtensions.x-http-method}}}") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; {{>client-request-body-instance}} let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); {{#hasAuthMethods}} #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; {{! Currently only authentication with Basic and Bearer are supported }} #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { {{#authMethods}} {{#isBasicBasic}} - AuthData::Basic(basic_header) => { - let auth = swagger::auth::Header(basic_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { - Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) - }; + AuthData::Basic(ref basic_user, ref basic_password) => { + let auth = headers::Authorization::basic(basic_user.as_str(), basic_password.as_str()); request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + auth.0.encode()); }, {{/isBasicBasic}} {{#isBasicBearer}} - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, {{/isBasicBearer}} {{#isOAuth}} {{^isBasicBearer}} - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, {{/isBasicBearer}} {{/isOAuth}} @@ -155,12 +152,12 @@ {{/required}} request.headers_mut().append( HeaderName::from_static("{{{nameInLowerCase}}}"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_{{{paramName}}}.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header {{{paramName}}} - {}", e))); + "Invalid header {{{paramName}}} - {e}"))); }, }); {{^required}} @@ -175,7 +172,7 @@ {{/headerParams}} let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { {{#responses}} @@ -187,7 +184,7 @@ let response_{{{name}}} = match TryInto::>::try_into(response_{{{name}}}) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header {{baseName}} for response {{code}} - {}", e))); + return Err(ApiError(format!("Invalid response header {{baseName}} for response {{code}} - {e}"))); }, }; {{#required}} @@ -208,9 +205,10 @@ {{/headers}} {{#dataType}} let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; {{>client-response-body-instance}} @@ -248,18 +246,16 @@ {{/responses}} code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-request-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-request-body-instance.mustache index f0f265a29d1d..884b05bbde3e 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-request-body-instance.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-request-body-instance.mustache @@ -17,11 +17,11 @@ &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); // Add the message body to the request object. - *request.body_mut() = Body::from(body); + *request.body_mut() = BoxBody::new(Full::new(Bytes::from(body))); {{/x-consumes-multipart-related}} {{#x-consumes-form}} @@ -37,6 +37,7 @@ // style=form,explode=true for param_{{{paramName}}} in param_{{{paramName}}} { {{/isArray}} + #[allow(clippy::uninlined_format_args)] params.push(("{{{baseName}}}", {{^isString}} format!("{{{vendorExtensions.x-format-string}}}", param_{{{paramName}}}) @@ -60,12 +61,12 @@ let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); {{/-last}} {{/formParams}} @@ -81,7 +82,7 @@ {{#vendorExtensions}} {{#x-consumes-plain-text}} {{#isByteArray}} - let body = param_{{{paramName}}}.0; + let body = String::from_utf8(param_body.0).expect("Body was not valid UTF8"); {{/isByteArray}} {{^isByteArray}} let body = param_{{{paramName}}}; @@ -94,7 +95,7 @@ let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize"); {{/x-consumes-json}} {{/vendorExtensions}} - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); {{^required}} } {{/required}} @@ -102,7 +103,7 @@ let header = "{{#consumes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/consumes}}{{^consumes}}application/json{{/consumes}}"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); {{/bodyParam}} {{/x-consumes-basic}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-request-body-multipart-form.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-request-body-multipart-form.mustache index ce8869195f77..f6e1c6fea3e7 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-request-body-multipart-form.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-request-body-multipart-form.mustache @@ -11,11 +11,11 @@ {{#jsonSchema}} let {{{paramName}}}_str = match serde_json::to_string(¶m_{{{paramName}}}) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize {{{paramName}}} to string: {e}"))), }; let {{{paramName}}}_vec = {{{paramName}}}_str.as_bytes().to_vec(); - let {{{paramName}}}_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let {{{paramName}}}_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); multipart.add_stream("{{{paramName}}}", {{{paramName}}}_cursor, None as Option<&str>, Some({{{paramName}}}_mime)); @@ -25,9 +25,9 @@ {{#isByteArray}} let {{{paramName}}}_vec = param_{{{paramName}}}.to_vec(); - let {{{paramName}}}_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + let {{{paramName}}}_mime = match mime::Mime::from_str("application/octet-stream") { Ok(mime) => mime, - Err(err) => return Err(ApiError(format!("Unable to get mime type: {:?}", err))), + Err(err) => return Err(ApiError(format!("Unable to get mime type: {err:?}"))), }; let {{{paramName}}}_cursor = Cursor::new({{{paramName}}}_vec); @@ -40,26 +40,26 @@ let mut fields = match multipart.prepare() { Ok(fields) => fields, - Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), }; let mut body_string = String::new(); match fields.read_to_string(&mut body_string) { Ok(_) => (), - Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), } let boundary = fields.boundary(); - let multipart_header = format!("multipart/form-data;boundary={}", boundary); + let multipart_header = format!("multipart/form-data;boundary={boundary}"); (body_string, multipart_header) }; - *request.body_mut() = Body::from(body_string); + *request.body_mut() = body_from_string(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) }); diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-response-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-response-body-instance.mustache index 3ff6dfb0c7a9..6ff1719ca0e0 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-response-body-instance.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-response-body-instance.mustache @@ -4,16 +4,16 @@ {{/x-produces-bytes}} {{^x-produces-bytes}} let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; {{#x-produces-xml}} // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::<{{{dataType}}}>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; {{/x-produces-xml}} {{#x-produces-json}} let body = serde_json::from_str::<{{{dataType}}}>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; {{/x-produces-json}} {{#x-produces-plain-text}} let body = body.to_string(); diff --git a/modules/openapi-generator/src/main/resources/rust-server/client-response-body-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server/client-response-body-multipart-related.mustache index 0c6aeaacc490..3e4df32f66ef 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/client-response-body-multipart-related.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/client-response-body-multipart-related.mustache @@ -11,7 +11,7 @@ let multipart_headers = match swagger::multipart::related::create_multipart_head let nodes = match read_multipart_body(&mut&*body, &multipart_headers, false) { Ok(nodes) => nodes, Err(e) => { - return Err(ApiError(format!("Could not read multipart body for {{operationId}}: {}", e))); + return Err(ApiError(format!("Could not read multipart body for {{operationId}}: {e}"))); } }; @@ -21,7 +21,7 @@ let mut param_{{{paramName}}} = None; for node in nodes { if let Node::Part(part) = node { - let content_type = part.content_type().map(|x| format!("{}",x)); + let content_type = part.content_type().map(|x| format!("{x}")); match content_type.as_ref().map(|x| x.as_str()) { {{#formParams}} {{^isBinary}} @@ -29,10 +29,10 @@ for node in nodes { // Extract JSON part. let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); let json_data: {{{dataType}}} = match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in JSON part: {}", path); + warn!("Ignoring unknown field in JSON part: {path}"); }) { Ok(json_data) => json_data, - Err(e) => return Err(ApiError(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {}", e))) + Err(e) => return Err(ApiError(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {e}"))) }; // Push JSON part to return object. param_{{{paramName}}}.get_or_insert(json_data); @@ -45,14 +45,14 @@ for node in nodes { {{/isBinary}} {{/formParams}} Some(content_type) => { - warn!("Ignoring unexpected content type: {}", content_type); + warn!("Ignoring unexpected content type: {content_type}"); }, None => { warn!("Missing content type"); }, } } else { - return Err(ApiError(format!("Unexpected part in multipart body for {{operationId}}: {:?}", node))); + return Err(ApiError(format!("Unexpected part in multipart body for {{operationId}}: {node:?}"))); } } {{#formParams}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/context.mustache b/modules/openapi-generator/src/main/resources/rust-server/context.mustache index 061bd4fbf2d8..2b9fc385ac4b 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/context.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/context.mustache @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,24 +87,18 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); @@ -109,20 +106,9 @@ impl Service> for AddContext(headers) { - let authorization = self.inner.basic_authorization(&basic); - let auth_data = AuthData::Basic(basic); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(auth) = swagger::auth::from_headers(headers) { + let context = context.push(Some(auth)); return self.inner.call((request, context)) } @@ -130,20 +116,10 @@ impl Service> for AddContext(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } @@ -152,20 +128,10 @@ impl Service> for AddContext(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } @@ -176,18 +142,9 @@ impl Service> for AddContext context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; return self.inner.call((request, context)) } @@ -200,18 +157,9 @@ impl Service> for AddContext context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; - return self.inner.call((request, context)) } } @@ -220,7 +168,6 @@ impl Service> for AddContext); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache index 511739d707d1..16a6a9847adc 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-client-main.mustache @@ -18,7 +18,7 @@ use {{{externCrateName}}}::{Api, ApiNoContext, Claims, Client, ContextWrapperExt {{/apis}} {{/apiInfo}} }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -41,19 +41,15 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ {{#apiInfo}} {{#apis}} {{#operations}} {{#operation}} - {{#vendorExtensions}} - {{^x-no-client-example}} "{{{operationId}}}", - {{/x-no-client-example}} - {{/vendorExtensions}} {{/operation}} {{/operations}} {{/apis}} @@ -61,17 +57,15 @@ fn main() { ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("{{{serverHost}}}") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("{{{serverPort}}}") .help("Port to contact")) .get_matches(); @@ -106,22 +100,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -141,7 +135,7 @@ fn main() { rt.spawn(server::create("127.0.0.1:8081", false)); {{/hasCallbacks}} - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { {{#apiInfo}} {{#apis}} {{#operations}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-auth.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-auth.mustache index 7e0eac398fe9..378d5b1a9a9a 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-auth.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-auth.mustache @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use {{{externCrateName}}}::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -98,7 +98,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -135,4 +135,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache index ee1167be8dcb..a54fe26e8a96 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-common.mustache @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use {{{externCrateName}}}::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -92,3 +121,11 @@ impl Server { Server{marker: PhantomData} } } + +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} diff --git a/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache b/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache index 58d6f9e2a65f..5e52ab4ffa2b 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/example-server-main.mustache @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); - let addr = "127.0.0.1:{{{serverPort}}}"; + let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/modules/openapi-generator/src/main/resources/rust-server/generate-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server/generate-multipart-related.mustache index 59b647a4130c..9678b5d32da8 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/generate-multipart-related.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/generate-multipart-related.mustache @@ -11,9 +11,9 @@ {{/required}} let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("{{{contentType}}}".parse().unwrap())); - h.set_raw("Content-ID", vec![b"{{{baseName}}}".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("{{{contentType}}}")); + h.insert("Content-ID", HeaderValue::from_static("{{{baseName}}}")); h }, {{#isBinary}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/header.mustache b/modules/openapi-generator/src/main/resources/rust-server/header.mustache index 5bc6ebe929b9..823d2779b31f 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/header.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/header.mustache @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache index e6d2bf190130..c54415329b8f 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/lib.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/lib.mustache @@ -35,10 +35,6 @@ pub use auth::{AuthenticationApi, Claims}; #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - {{#apiInfo}} {{#apis}} {{#operations}} @@ -64,8 +60,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; {{#apiInfo}} @@ -103,10 +97,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } @@ -156,9 +146,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for Contex /// Callback API #[async_trait] pub trait CallbackApi { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } {{#apiInfo}} {{#apis}} @@ -194,7 +181,6 @@ pub trait CallbackApi { /// Callback API without a `Context` #[async_trait] pub trait CallbackApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; fn context(&self) -> &C; @@ -243,9 +229,6 @@ impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWra #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } fn context(&self) -> &C { ContextWrapper::context(self) diff --git a/modules/openapi-generator/src/main/resources/rust-server/models.mustache b/modules/openapi-generator/src/main/resources/rust-server/models.mustache index 9cdd4a1a580b..8f2339c2cb6f 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/models.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/models.mustache @@ -52,7 +52,7 @@ impl std::str::FromStr for {{{classname}}} { {{{value}}} => std::result::Result::Ok({{{classname}}}::{{{name}}}), {{/enumVars}} {{/allowableValues}} - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -93,9 +93,9 @@ impl std::ops::DerefMut for {{{classname}}} { {{#vendorExtensions.x-to-string-support}} {{#vendorExtensions.x-is-string}} -impl std::string::ToString for {{{classname}}} { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for {{{classname}}} { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -108,16 +108,16 @@ impl std::str::FromStr for {{{classname}}} { {{/vendorExtensions.x-is-string}} {{^vendorExtensions.x-is-string}} /// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for {{{classname}}} { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for {{{classname}}} { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for {{{classname}}} { type Err = String; @@ -125,7 +125,7 @@ impl ::std::str::FromStr for {{{classname}}} { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok({{{classname}}}(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to {{{classname}}}: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to {{{classname}}}: {e:?}")), } } } @@ -133,17 +133,17 @@ impl ::std::str::FromStr for {{{classname}}} { {{/vendorExtensions.x-to-string-support}} {{^vendorExtensions.x-to-string-support}} /// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for {{{classname}}} { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for {{{classname}}} { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for {{{classname}}} { type Err = &'static str; @@ -238,16 +238,16 @@ impl std::ops::DerefMut for {{{classname}}} { } /// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for {{{classname}}} { - fn to_string(&self) -> String { - self.iter().map(|x| x.to_string()).collect::>().join(",") +impl std::fmt::Display for {{{classname}}} { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.iter().map(|x| x.to_string()).collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for {{{classname}}} { type Err = <{{{arrayModelType}}} as std::str::FromStr>::Err; @@ -297,10 +297,10 @@ pub struct {{{classname}}} { {{/maxLength}} {{#pattern}} {{^isByteArray}} - regex = "RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}", + regex(path = *RE_{{#lambda.uppercase}}{{{classname}}}_{{{name}}}{{/lambda.uppercase}}), {{/isByteArray}} {{#isByteArray}} - custom ="validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowercase}}" + custom(function = "validate_byte_{{#lambda.lowercase}}{{{classname}}}_{{{name}}}{{/lambda.lowercase}}") {{/isByteArray}} {{/pattern}} {{#maximum}} @@ -382,10 +382,10 @@ impl {{{classname}}} { } /// Converts the {{{classname}}} value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for {{{classname}}} { - fn to_string(&self) -> String { +impl std::fmt::Display for {{{classname}}} { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ {{#vars}} {{#isByteArray}} @@ -453,12 +453,12 @@ impl std::string::ToString for {{{classname}}} { {{/vars}} ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a {{{classname}}} value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for {{{classname}}} { type Err = String; @@ -548,8 +548,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for {{classname}} - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for {{classname}} - value: {hdr_value} is invalid {e}")) } } } @@ -564,13 +563,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match <{{{classname}}} as std::str::FromStr>::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into {{classname}} - {}", - value, err)) + format!("Unable to convert header value '{value}' into {{classname}} - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -586,8 +583,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -607,16 +603,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match <{{{classname}}} as std::str::FromStr>::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into {{classname}} - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into {{classname}} - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache index 2c95e530895d..b565bf430050 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-callbacks.mustache @@ -19,9 +19,8 @@ use crate::{{{operationId}}}Response; /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -34,9 +33,8 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -47,9 +45,8 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -61,8 +58,8 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client>>, C>, C> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. @@ -76,10 +73,11 @@ impl Client Self { - let client_service = hyper::client::Client::builder().build(connector); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = hyper_util::service::TowerToHyperService::new(client_service); let client_service = DropContextService::new(client_service); Self { @@ -89,7 +87,7 @@ impl Client Client, C>, C> where +impl Client>>, C>, C> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. @@ -100,12 +98,12 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; -impl Client, C>, C> where +impl Client>>, C>, C> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server. @@ -169,9 +167,8 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -191,20 +188,12 @@ impl Client where #[async_trait] impl CallbackApi for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Clone + Send + Sync, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } {{#apiInfo}} {{#apis}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache index 1b39e6808be0..15932c468d26 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-imports.mustache @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -13,8 +15,6 @@ pub use swagger::auth::Authorization; use swagger::auth::Scopes; use url::form_urlencoded; {{#apiUsesMultipartRelated}} -use hyper_0_10::header::{Headers, ContentType}; -use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; use mime_multipart::{read_multipart_body, Node, Part}; {{/apiUsesMultipartRelated}} {{#apiUsesMultipartFormData}} @@ -27,4 +27,4 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache index 7471c9c2278c..fd20d96c648e 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-make-service.mustache @@ -1,5 +1,6 @@ -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { @@ -10,7 +11,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { @@ -37,7 +39,24 @@ impl MakeService where {{/apiUsesMultipartFormData}} } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), +{{#apiUsesMultipartFormData}} + multipart_form_size_limit: Some(8 * 1024 * 1024), +{{/apiUsesMultipartFormData}} + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static { @@ -45,11 +64,7 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()){{^apiUsesMultipartFormData}};{{/apiUsesMultipartFormData}} {{#apiUsesMultipartFormData}} .multipart_form_size_limit(self.multipart_form_size_limit); diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache index 4957b65c4dc5..f651a6409b7d 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-operation.mustache @@ -6,7 +6,7 @@ Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; {{#authMethods}} @@ -24,9 +24,9 @@ let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -56,12 +56,12 @@ Ok(param_{{{paramName}}}) => param_{{{paramName}}}, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter {{{baseName}}}: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter {{{baseName}}}: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["{{{baseName}}}"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -89,7 +89,7 @@ Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header {{{baseName}}} - {}", err))) + .body(body_from_string(format!("Invalid header {{{baseName}}} - {err}"))) .expect("Unable to create Bad Request response for invalid header {{{baseName}}}")); }, @@ -98,7 +98,7 @@ {{#required}} return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required header {{{baseName}}}")) + .body(body_from_str("Missing required header {{{baseName}}}")) .expect("Unable to create Bad Request response for missing required header {{{baseName}}}")); {{/required}} {{^required}} @@ -139,7 +139,7 @@ Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")), } }, @@ -150,7 +150,7 @@ Some(param_{{{paramName}}}) => param_{{{paramName}}}, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter {{{baseName}}}")) + .body(body_from_str("Missing required query parameter {{{baseName}}}")) .expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")), }; {{/required}} @@ -172,7 +172,7 @@ Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter {{{baseName}}} - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter {{{baseName}}}")), } }, @@ -183,7 +183,7 @@ Some(param_{{{paramName}}}) => param_{{{paramName}}}, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter {{{baseName}}}")) + .body(body_from_str("Missing required query parameter {{{baseName}}}")) .expect("Unable to create Bad Request response for missing query parameter {{{baseName}}}")), }; {{/required}} @@ -196,7 +196,7 @@ // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { {{^vendorExtensions.x-consumes-multipart-form}} @@ -219,7 +219,7 @@ {{/allParams}} &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -232,7 +232,7 @@ if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } {{/bodyParam.vendorExtensions.x-consumes-plain-text}} @@ -281,7 +281,7 @@ Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling {{name}} header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling {{name}} header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -302,7 +302,7 @@ // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -311,7 +311,7 @@ }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } {{/vendorExtensions.x-has-request-body}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-basic.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-basic.mustache index 97422852ca75..d35f311a2315 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-basic.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-basic.mustache @@ -4,24 +4,28 @@ let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); {{/x-consumes-xml}} {{#x-consumes-json}} - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); {{/x-consumes-json}} {{^x-consumes-plain-text}} + {{#required}} match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_{{{paramName}}}) => param_{{{paramName}}}, - {{#required}} Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter {{{baseName}}} - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to schema")), + } {{/required}} {{^required}} - Err(_) => None, + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() {{/required}} - } + {{/x-consumes-plain-text}} {{#x-consumes-plain-text}} {{#isByteArray}} @@ -32,7 +36,7 @@ Ok(param_{{{paramName}}}) => Some(param_{{{paramName}}}), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter {{{baseName}}} - not valid UTF-8: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter {{{baseName}}} due to UTF-8")), } {{/isString}} @@ -46,7 +50,7 @@ Some(param_{{{paramName}}}) => param_{{{paramName}}}, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter {{{baseName}}}")) + .body(BoxBody::new("Missing required body parameter {{{baseName}}}".to_string())) .expect("Unable to create Bad Request response for missing body parameter {{{baseName}}}")), }; {{/required}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-form.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-form.mustache index f563459396a8..79ba09b5ac42 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-form.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-form.mustache @@ -2,7 +2,7 @@ Some(boundary) => boundary.to_string(), None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Couldn't find valid multipart body".to_string())) + .body(BoxBody::new("Couldn't find valid multipart body".to_string())) .expect("Unable to create Bad Request response for incorrect boundary")), }; @@ -20,31 +20,31 @@ SaveResult::Partial(_, PartialReason::CountLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive parts".to_string())) .expect("Unable to create Bad Request response due to excessive parts")) }, SaveResult::Partial(_, PartialReason::SizeLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive data".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive data".to_string())) .expect("Unable to create Bad Request response due to excessive data")) }, SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to invalid data".to_string())) + .body(BoxBody::new("Unable to process message part due to invalid data".to_string())) .expect("Unable to create Bad Request response due to invalid data")) }, SaveResult::Partial(_, PartialReason::IoError(_)) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process message part due an internal error".to_string())) + .body(BoxBody::new("Failed to process message part due an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, SaveResult::Error(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .body(BoxBody::new("Failed to process all message parts due to an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, }; @@ -71,7 +71,7 @@ return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("{{{paramName}}} data does not match API definition : {}", e))) + .body(BoxBody::new(format!("{{{paramName}}} data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) } }; @@ -87,7 +87,7 @@ return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required form parameter {{{paramName}}}".to_string())) + .body(BoxBody::new("Missing required form parameter {{{paramName}}}".to_string())) .expect("Unable to create Bad Request due to missing required form parameter {{{paramName}}}")) {{/required}} {{^required}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-related.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-related.mustache index b9dc330ef3f8..9d72305b32dd 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-related.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-request-body-multipart-related.mustache @@ -6,7 +6,7 @@ Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(e)) + .body(BoxBody::new(e.to_string())) .expect("Unable to create Bad Request response due to unable to read content-type header for {{operationId}}")); } }; @@ -18,7 +18,7 @@ Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Could not read multipart body for {{operationId}}: {}", e))) + .body(BoxBody::new(format!("Could not read multipart body for {{operationId}}: {e}"))) .expect("Unable to create Bad Request response due to unable to read multipart body for {{operationId}}")); } }; @@ -29,7 +29,7 @@ for node in nodes { if let Node::Part(part) = node { - let content_type = part.content_type().map(|x| format!("{}",x)); + let content_type = part.content_type().map(|x| format!("{x}")); match content_type.as_deref() { {{#formParams}} {{^isBinary}} @@ -37,13 +37,13 @@ // Extract JSON part. let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); let json_data: {{dataType}} = match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in JSON part: {}", path); + warn!("Ignoring unknown field in JSON part: {path}"); unused_elements.push(path.to_string()); }) { Ok(json_data) => json_data, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter {{dataType}} - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter {{dataType}} due to schema")) }; // Push JSON part to return object. @@ -57,7 +57,7 @@ {{/isBinary}} {{/formParams}} Some(content_type) => { - warn!("Ignoring unexpected content type: {}", content_type); + warn!("Ignoring unexpected content type: {content_type}"); unused_elements.push(content_type.to_string()); }, None => { @@ -79,7 +79,7 @@ Some(x) => x, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required multipart/related parameter {{{paramName}}}".to_string())) + .body(BoxBody::new("Missing required multipart/related parameter {{{paramName}}}".to_string())) .expect("Unable to create Bad Request response for missing multipart/related parameter {{{paramName}}} due to schema")) }; {{/required}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-response-body-instance.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-response-body-instance.mustache index 9bb648c525f7..2e4ca46e1ba4 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-response-body-instance.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-response-body-instance.mustache @@ -25,11 +25,10 @@ {{/x-produces-json}} {{#x-produces-bytes}} // Binary Body - let body = body.0; + let body = String::from_utf8(body.0).expect("Error converting octet stream to string"); {{/x-produces-bytes}} {{#x-produces-plain-text}} // Plain text Body - let body = body; {{/x-produces-plain-text}} {{#x-produces-multipart-related}} // multipart/related Body @@ -46,5 +45,5 @@ {{/formParams}} {{/x-produces-multipart-related}} {{/vendorExtensions}} - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); {{/dataType}} diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-server_auth.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-server_auth.mustache index ba78eb2f3f5d..21b1d7babd03 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-server_auth.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-server_auth.mustache @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache index 793cd99e5cca..5f9a8f23e7c1 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-service-footer.mustache @@ -1,5 +1,5 @@ _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache b/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache index 997b5b5c9f0e..99a93fcf7b68 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/server-service-header.mustache @@ -1,7 +1,7 @@ -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -59,28 +59,40 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), + req: (Request, C), {{#apiUsesMultipartFormData}} multipart_form_size_limit: Option, {{/apiUsesMultipartFormData}} - ) -> Result, crate::ServiceError> where + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static + C: Has {{#hasAuthMethods}}+ Has>{{/hasAuthMethods}} + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml index b96289ea6803..a785ca8bb030 100644 --- a/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/openapi-v3.yaml @@ -513,6 +513,20 @@ paths: responses: '200': description: OK + /examples-test: + get: + operationId : ExamplesTest + summary: Test examples + description: Test examples in OpenAPI + parameters: + - $ref: "#/components/parameters/ids" + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/AdditionalPropertiesReferencedAnyOfObject' components: securitySchemes: @@ -764,3 +778,20 @@ components: type: string Result: type: string + parameters: + ids: + name: ids + in: query + description: A list of IDs to get + required: false + schema: + type: array + items: + type: string + style: form + explode: false + examples: + oneId: + value: ["foo"] + multipleIds: + value: ["foo", "bar"] diff --git a/samples/server/petstore/rust-server-deprecated/.cargo/config.toml b/samples/server/petstore/rust-server-deprecated/.cargo/config.toml new file mode 100644 index 000000000000..d4b77f0bee56 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/.cargo/config.toml @@ -0,0 +1,16 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server-deprecated/.gitignore b/samples/server/petstore/rust-server-deprecated/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/Cargo.toml b/samples/server/petstore/rust-server-deprecated/Cargo.toml new file mode 100644 index 000000000000..c086d1f01388 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/Cargo.toml @@ -0,0 +1,3 @@ +[workspace] +members = ["output/*"] +resolver = "2" diff --git a/samples/server/petstore/rust-server/output/multipart-v3/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/multipart-v3/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/multipart-v3/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.gitignore b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/FILES new file mode 100644 index 000000000000..3f051cfa5e44 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/FILES @@ -0,0 +1,26 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/MultipartRelatedRequest.md +docs/MultipartRequestObjectField.md +docs/MultipleIdenticalMimeTypesPostRequest.md +docs/default_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/Cargo.toml new file mode 100644 index 000000000000..c17bc7e481fd --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/Cargo.toml @@ -0,0 +1,106 @@ +[package] +name = "multipart-v3" +version = "1.0.7" +authors = ["OpenAPI Generator team and contributors"] +description = "API under test" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "mime_0_2", + "multipart", "multipart/client", "swagger/multipart_form", + "hyper_0_10", "mime_multipart", "swagger/multipart_related", + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "mime_0_2", + "multipart", "multipart/server", "swagger/multipart_form", + "hyper_0_10", "mime_multipart", "swagger/multipart_related", + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition +mime_0_2 = { package = "mime", version = "0.2.6", optional = true } +multipart = { version = "0.16", default-features = false, optional = true } + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +mime_multipart = {version = "0.5", optional = true} +hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "multipart-v3" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/README.md b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/README.md new file mode 100644 index 000000000000..deb18ebdba2d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/README.md @@ -0,0 +1,146 @@ +# Rust API for multipart-v3 + +API under test + +## Overview + +This client/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: 1.0.7 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `multipart-v3` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `multipart-v3`: + +* The example server starts up a web server using the `multipart-v3` + router, and supplies a trivial implementation of `Api` which returns failure + for every operation. +* The example client provides a CLI which lets you invoke + any single operation on the `multipart-v3` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client MultipartRelatedRequestPost +cargo run --example client MultipartRequestPost +cargo run --example client MultipleIdenticalMimeTypesPost +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[****](docs/default_api.md#) | **POST** /multipart_related_request | +[****](docs/default_api.md#) | **POST** /multipart_request | +[****](docs/default_api.md#) | **POST** /multiple-identical-mime-types | + + +## Documentation For Models + + - [MultipartRelatedRequest](docs/MultipartRelatedRequest.md) + - [MultipartRequestObjectField](docs/MultipartRequestObjectField.md) + - [MultipleIdenticalMimeTypesPostRequest](docs/MultipleIdenticalMimeTypesPostRequest.md) + + +## Documentation For Authorization +Endpoints do not require authorization. + + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/api/openapi.yaml new file mode 100644 index 000000000000..07e72037ff58 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/api/openapi.yaml @@ -0,0 +1,121 @@ +openapi: 3.0.1 +info: + description: API under test + title: Multipart OpenAPI V3 Rust Server Test + version: 1.0.7 +servers: +- url: / +paths: + /multipart_request: + post: + requestBody: + content: + multipart/form-data: + schema: + $ref: "#/components/schemas/multipart_request" + required: true + responses: + "201": + description: OK + /multipart_related_request: + post: + requestBody: + content: + multipart/related: + encoding: + object_field: + contentType: application/json + style: form + optional_binary_field: + contentType: application/zip + headers: + Content-Id: + explode: false + schema: + type: string + style: simple + style: form + required_binary_field: + contentType: image/png + headers: + Content-Id: + explode: false + schema: + type: string + style: simple + style: form + schema: + $ref: "#/components/schemas/multipart_related_request" + required: true + responses: + "201": + description: OK + /multiple-identical-mime-types: + post: + requestBody: + content: + multipart/related: + encoding: + binary1: + contentType: application/octet-stream + style: form + binary2: + contentType: application/octet-stream + style: form + schema: + $ref: "#/components/schemas/_multiple_identical_mime_types_post_request" + required: true + responses: + "200": + description: OK +components: + schemas: + multipart_request: + properties: + string_field: + type: string + optional_string_field: + type: string + object_field: + $ref: "#/components/schemas/multipart_request_object_field" + binary_field: + format: byte + type: string + required: + - binary_field + - string_field + type: object + multipart_related_request: + properties: + object_field: + $ref: "#/components/schemas/multipart_request_object_field" + optional_binary_field: + format: binary + type: string + required_binary_field: + format: binary + type: string + required: + - required_binary_field + type: object + _multiple_identical_mime_types_post_request: + properties: + binary1: + format: binary + type: string + binary2: + format: binary + type: string + type: object + multipart_request_object_field: + properties: + field_a: + type: string + field_b: + items: + type: string + type: array + required: + - field_a + type: object + diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/bin/cli.rs new file mode 100644 index 000000000000..cc14190181fb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/bin/cli.rs @@ -0,0 +1,215 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use multipart_v3::{ + models, ApiNoContext, Client, ContextWrapperExt, + MultipartRelatedRequestPostResponse, + MultipartRequestPostResponse, + MultipleIdenticalMimeTypesPostResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "Multipart OpenAPI V3 Rust Server Test", + version = "1.0.7", + about = "CLI access to Multipart OpenAPI V3 Rust Server Test" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, +} + +#[derive(StructOpt, Debug)] +enum Operation { + MultipartRelatedRequestPost { + #[structopt(parse(try_from_str = parse_json))] + required_binary_field: swagger::ByteArray, + #[structopt(parse(try_from_str = parse_json))] + object_field: Option, + #[structopt(parse(try_from_str = parse_json))] + optional_binary_field: Option, + }, + MultipartRequestPost { + string_field: String, + #[structopt(parse(try_from_str = parse_json))] + binary_field: swagger::ByteArray, + optional_string_field: Option, + #[structopt(parse(try_from_str = parse_json))] + object_field: Option, + }, + MultipleIdenticalMimeTypesPost { + #[structopt(parse(try_from_str = parse_json))] + binary1: Option, + #[structopt(parse(try_from_str = parse_json))] + binary2: Option, + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let auth_data: Option = None; + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::MultipartRelatedRequestPost { + required_binary_field, + object_field, + optional_binary_field, + } => { + info!("Performing a MultipartRelatedRequestPost request"); + + let result = client.multipart_related_request_post( + required_binary_field, + object_field, + optional_binary_field, + ).await?; + debug!("Result: {:?}", result); + + match result { + MultipartRelatedRequestPostResponse::OK + => "OK\n".to_string() + , + } + } + Operation::MultipartRequestPost { + string_field, + binary_field, + optional_string_field, + object_field, + } => { + info!("Performing a MultipartRequestPost request"); + + let result = client.multipart_request_post( + string_field, + binary_field, + optional_string_field, + object_field, + ).await?; + debug!("Result: {:?}", result); + + match result { + MultipartRequestPostResponse::OK + => "OK\n".to_string() + , + } + } + Operation::MultipleIdenticalMimeTypesPost { + binary1, + binary2, + } => { + info!("Performing a MultipleIdenticalMimeTypesPost request"); + + let result = client.multiple_identical_mime_types_post( + binary1, + binary2, + ).await?; + debug!("Result: {:?}", result); + + match result { + MultipleIdenticalMimeTypesPostResponse::OK + => "OK\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRelatedRequest.md b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRelatedRequest.md new file mode 100644 index 000000000000..0180168d1ec6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRelatedRequest.md @@ -0,0 +1,12 @@ +# MultipartRelatedRequest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**object_field** | [***models::MultipartRequestObjectField**](multipart_request_object_field.md) | | [optional] [default to None] +**optional_binary_field** | [***swagger::ByteArray**](file.md) | | [optional] [default to None] +**required_binary_field** | [***swagger::ByteArray**](file.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRequestObjectField.md b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRequestObjectField.md new file mode 100644 index 000000000000..bfbf176ad75e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipartRequestObjectField.md @@ -0,0 +1,11 @@ +# MultipartRequestObjectField + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**field_a** | **String** | | +**field_b** | **Vec** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/multipart-v3/docs/InlineObject.md b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipleIdenticalMimeTypesPostRequest.md similarity index 91% rename from samples/server/petstore/rust-server/output/multipart-v3/docs/InlineObject.md rename to samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipleIdenticalMimeTypesPostRequest.md index 735ca915ec11..00f8d496e461 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/docs/InlineObject.md +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/MultipleIdenticalMimeTypesPostRequest.md @@ -1,4 +1,4 @@ -# InlineObject +# MultipleIdenticalMimeTypesPostRequest ## Properties Name | Type | Description | Notes diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/default_api.md new file mode 100644 index 000000000000..1e80b51a075c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/docs/default_api.md @@ -0,0 +1,116 @@ +# default_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +****](default_api.md#) | **POST** /multipart_related_request | +****](default_api.md#) | **POST** /multipart_request | +****](default_api.md#) | **POST** /multiple-identical-mime-types | + + +# **** +> (required_binary_field, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **required_binary_field** | **swagger::ByteArray**| | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **required_binary_field** | **swagger::ByteArray**| | + **object_field** | [**multipart_request_object_field**](multipart_request_object_field.md)| | + **optional_binary_field** | **swagger::ByteArray**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: multipart/related + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (string_field, binary_field, optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **string_field** | **String**| | + **binary_field** | **swagger::ByteArray**| | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **string_field** | **String**| | + **binary_field** | **swagger::ByteArray**| | + **optional_string_field** | **String**| | + **object_field** | [**multipart_request_object_field**](multipart_request_object_field.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: multipart/form-data + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **binary1** | **swagger::ByteArray**| | + **binary2** | **swagger::ByteArray**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: multipart/related + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/client_auth.rs new file mode 100644 index 000000000000..ed71c3056f8c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use multipart_v3::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/main.rs new file mode 100644 index 000000000000..f679dbf950f6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/client/main.rs @@ -0,0 +1,138 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use multipart_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + MultipartRelatedRequestPostResponse, + MultipartRequestPostResponse, + MultipleIdenticalMimeTypesPostResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "MultipartRelatedRequestPost", + "MultipartRequestPost", + "MultipleIdenticalMimeTypesPost", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + "".to_owned() + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + Some("MultipartRelatedRequestPost") => { + let result = rt.block_on(client.multipart_related_request_post( + swagger::ByteArray(Vec::from("BINARY_DATA_HERE")), + None, + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MultipartRequestPost") => { + let result = rt.block_on(client.multipart_request_post( + "string_field_example".to_string(), + swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")), + Some("optional_string_field_example".to_string()), + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MultipleIdenticalMimeTypesPost") => { + let result = rt.block_on(client.multiple_identical_mime_types_post( + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))), + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/main.rs new file mode 100644 index 000000000000..a0b4755e80c1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for multipart_v3 implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server.rs new file mode 100644 index 000000000000..5b2d8a75d03d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server.rs @@ -0,0 +1,149 @@ +//! Main library entry point for multipart_v3 implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use multipart_v3::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + multipart_v3::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use multipart_v3::{ + Api, + MultipartRelatedRequestPostResponse, + MultipartRequestPostResponse, + MultipleIdenticalMimeTypesPostResponse, +}; +use multipart_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn multipart_related_request_post( + &self, + required_binary_field: swagger::ByteArray, + object_field: Option, + optional_binary_field: Option, + context: &C) -> Result + { + info!("multipart_related_request_post({:?}, {:?}, {:?}) - X-Span-ID: {:?}", required_binary_field, object_field, optional_binary_field, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn multipart_request_post( + &self, + string_field: String, + binary_field: swagger::ByteArray, + optional_string_field: Option, + object_field: Option, + context: &C) -> Result + { + info!("multipart_request_post(\"{}\", {:?}, {:?}, {:?}) - X-Span-ID: {:?}", string_field, binary_field, optional_string_field, object_field, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn multiple_identical_mime_types_post( + &self, + binary1: Option, + binary2: Option, + context: &C) -> Result + { + info!("multiple_identical_mime_types_post({:?}, {:?}) - X-Span-ID: {:?}", binary1, binary2, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server_auth.rs new file mode 100644 index 000000000000..bf48130e2941 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/examples/server/server_auth.rs @@ -0,0 +1,127 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use multipart_v3::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + "".to_owned() + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/client/mod.rs new file mode 100644 index 000000000000..8ccd2f068dd4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/client/mod.rs @@ -0,0 +1,801 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + +use mime::Mime; +use std::io::Cursor; +use multipart::client::lazy::Multipart; +use hyper_0_10::header::{Headers, ContentType}; +use mime_multipart::{Node, Part, write_multipart}; + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + MultipartRelatedRequestPostResponse, + MultipartRequestPostResponse, + MultipleIdenticalMimeTypesPostResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn multipart_related_request_post( + &self, + param_required_binary_field: swagger::ByteArray, + param_object_field: Option, + param_optional_binary_field: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multipart_related_request", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes multipart/related body + let boundary = swagger::multipart::related::generate_boundary(); + let mut body_parts = vec![]; + + if let Some(object_field) = param_object_field { + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("application/json".parse().unwrap())); + h.set_raw("Content-ID", vec![b"object_field".to_vec()]); + h + }, + body: serde_json::to_string(&object_field) + .expect("Impossible to fail to serialize") + .into_bytes(), + }); + body_parts.push(part); + } + + if let Some(optional_binary_field) = param_optional_binary_field { + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("application/zip".parse().unwrap())); + h.set_raw("Content-ID", vec![b"optional_binary_field".to_vec()]); + h + }, + body: optional_binary_field.0, + }); + body_parts.push(part); + } + + { + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("image/png".parse().unwrap())); + h.set_raw("Content-ID", vec![b"required_binary_field".to_vec()]); + h + }, + body: param_required_binary_field.0, + }); + body_parts.push(part); + } + + // Write the body into a vec. + // RFC 13341 Section 7.2.1 suggests that the body should begin with a + // CRLF prior to the first boundary. The mime_multipart library doesn't + // do this, so we do it instead. + let mut body: Vec = vec![b'\r', b'\n']; + write_multipart(&mut body, &boundary, &body_parts) + .expect("Failed to write multipart body"); + + + let header = "multipart/related"; + request.headers_mut().insert(CONTENT_TYPE, + match HeaderValue::from_bytes( + &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() + ) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + // Add the message body to the request object. + *request.body_mut() = Body::from(body); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + MultipartRelatedRequestPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn multipart_request_post( + &self, + param_string_field: String, + param_binary_field: swagger::ByteArray, + param_optional_string_field: Option, + param_object_field: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multipart_request", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes multipart/form body + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); + + // For each parameter, encode as appropriate and add to the multipart body as a stream. + + let string_field_str = match serde_json::to_string(¶m_string_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize string_field to string: {e}"))), + }; + + let string_field_vec = string_field_str.as_bytes().to_vec(); + let string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let string_field_cursor = Cursor::new(string_field_vec); + + multipart.add_stream("string_field", string_field_cursor, None as Option<&str>, Some(string_field_mime)); + + + let optional_string_field_str = match serde_json::to_string(¶m_optional_string_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize optional_string_field to string: {e}"))), + }; + + let optional_string_field_vec = optional_string_field_str.as_bytes().to_vec(); + let optional_string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let optional_string_field_cursor = Cursor::new(optional_string_field_vec); + + multipart.add_stream("optional_string_field", optional_string_field_cursor, None as Option<&str>, Some(optional_string_field_mime)); + + + let object_field_str = match serde_json::to_string(¶m_object_field) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize object_field to string: {e}"))), + }; + + let object_field_vec = object_field_str.as_bytes().to_vec(); + let object_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let object_field_cursor = Cursor::new(object_field_vec); + + multipart.add_stream("object_field", object_field_cursor, None as Option<&str>, Some(object_field_mime)); + + + + let binary_field_vec = param_binary_field.to_vec(); + + let binary_field_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + Ok(mime) => mime, + Err(err) => return Err(ApiError(format!("Unable to get mime type: {err:?}"))), + }; + + let binary_field_cursor = Cursor::new(binary_field_vec); + + let filename = None as Option<&str> ; + multipart.add_stream("binary_field", binary_field_cursor, filename, Some(binary_field_mime)); + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;{boundary}"); + + (body_string, multipart_header) + }; + + *request.body_mut() = Body::from(body_string); + + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) + }); + + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + MultipartRequestPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn multiple_identical_mime_types_post( + &self, + param_binary1: Option, + param_binary2: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multiple-identical-mime-types", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes multipart/related body + let boundary = swagger::multipart::related::generate_boundary(); + let mut body_parts = vec![]; + + if let Some(binary1) = param_binary1 { + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("application/octet-stream".parse().unwrap())); + h.set_raw("Content-ID", vec![b"binary1".to_vec()]); + h + }, + body: binary1.0, + }); + body_parts.push(part); + } + + if let Some(binary2) = param_binary2 { + let part = Node::Part(Part { + headers: { + let mut h = Headers::new(); + h.set(ContentType("application/octet-stream".parse().unwrap())); + h.set_raw("Content-ID", vec![b"binary2".to_vec()]); + h + }, + body: binary2.0, + }); + body_parts.push(part); + } + + // Write the body into a vec. + // RFC 13341 Section 7.2.1 suggests that the body should begin with a + // CRLF prior to the first boundary. The mime_multipart library doesn't + // do this, so we do it instead. + let mut body: Vec = vec![b'\r', b'\n']; + write_multipart(&mut body, &boundary, &body_parts) + .expect("Failed to write multipart body"); + + + let header = "multipart/related"; + request.headers_mut().insert(CONTENT_TYPE, + match HeaderValue::from_bytes( + &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() + ) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + // Add the message body to the request object. + *request.body_mut() = Body::from(body); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + MultipleIdenticalMimeTypesPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/context.rs new file mode 100644 index 000000000000..ee8e118587bb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/context.rs @@ -0,0 +1,114 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/lib.rs new file mode 100644 index 000000000000..8c41db6313c6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/lib.rs @@ -0,0 +1,183 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "1.0.7"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MultipartRelatedRequestPostResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MultipartRequestPostResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MultipleIdenticalMimeTypesPostResponse { + /// OK + OK +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn multipart_related_request_post( + &self, + required_binary_field: swagger::ByteArray, + object_field: Option, + optional_binary_field: Option, + context: &C) -> Result; + + async fn multipart_request_post( + &self, + string_field: String, + binary_field: swagger::ByteArray, + optional_string_field: Option, + object_field: Option, + context: &C) -> Result; + + async fn multiple_identical_mime_types_post( + &self, + binary1: Option, + binary2: Option, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn multipart_related_request_post( + &self, + required_binary_field: swagger::ByteArray, + object_field: Option, + optional_binary_field: Option, + ) -> Result; + + async fn multipart_request_post( + &self, + string_field: String, + binary_field: swagger::ByteArray, + optional_string_field: Option, + object_field: Option, + ) -> Result; + + async fn multiple_identical_mime_types_post( + &self, + binary1: Option, + binary2: Option, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn multipart_related_request_post( + &self, + required_binary_field: swagger::ByteArray, + object_field: Option, + optional_binary_field: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().multipart_related_request_post(required_binary_field, object_field, optional_binary_field, &context).await + } + + async fn multipart_request_post( + &self, + string_field: String, + binary_field: swagger::ByteArray, + optional_string_field: Option, + object_field: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().multipart_request_post(string_field, binary_field, optional_string_field, object_field, &context).await + } + + async fn multiple_identical_mime_types_post( + &self, + binary1: Option, + binary2: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().multiple_identical_mime_types_post(binary1, binary2, &context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/models.rs new file mode 100644 index 000000000000..c62579b5433a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/models.rs @@ -0,0 +1,515 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MultipartRelatedRequest { + #[serde(rename = "object_field")] + #[serde(skip_serializing_if="Option::is_none")] + pub object_field: Option, + + #[serde(rename = "optional_binary_field")] + #[serde(skip_serializing_if="Option::is_none")] + pub optional_binary_field: Option, + + #[serde(rename = "required_binary_field")] + pub required_binary_field: swagger::ByteArray, + +} + + +impl MultipartRelatedRequest { + #[allow(clippy::new_without_default)] + pub fn new(required_binary_field: swagger::ByteArray, ) -> MultipartRelatedRequest { + MultipartRelatedRequest { + object_field: None, + optional_binary_field: None, + required_binary_field, + } + } +} + +/// Converts the MultipartRelatedRequest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MultipartRelatedRequest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type object_field in query parameter serialization + // Skipping binary data optional_binary_field in query parameter serialization + // Skipping binary data required_binary_field in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MultipartRelatedRequest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MultipartRelatedRequest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub object_field: Vec, + pub optional_binary_field: Vec, + pub required_binary_field: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MultipartRelatedRequest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "object_field" => intermediate_rep.object_field.push(::from_str(val).map_err(|x| x.to_string())?), + "optional_binary_field" => return std::result::Result::Err("Parsing binary data in this style is not supported in MultipartRelatedRequest".to_string()), + "required_binary_field" => return std::result::Result::Err("Parsing binary data in this style is not supported in MultipartRelatedRequest".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing MultipartRelatedRequest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MultipartRelatedRequest { + object_field: intermediate_rep.object_field.into_iter().next(), + optional_binary_field: intermediate_rep.optional_binary_field.into_iter().next(), + required_binary_field: intermediate_rep.required_binary_field.into_iter().next().ok_or_else(|| "required_binary_field missing in MultipartRelatedRequest".to_string())?, + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MultipartRelatedRequest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MultipartRelatedRequest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MultipartRelatedRequest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MultipartRequestObjectField { + #[serde(rename = "field_a")] + pub field_a: String, + + #[serde(rename = "field_b")] + #[serde(skip_serializing_if="Option::is_none")] + pub field_b: Option>, + +} + + +impl MultipartRequestObjectField { + #[allow(clippy::new_without_default)] + pub fn new(field_a: String, ) -> MultipartRequestObjectField { + MultipartRequestObjectField { + field_a, + field_b: None, + } + } +} + +/// Converts the MultipartRequestObjectField value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MultipartRequestObjectField { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("field_a".to_string()), + Some(self.field_a.to_string()), + self.field_b.as_ref().map(|field_b| { + [ + "field_b".to_string(), + field_b.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MultipartRequestObjectField value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MultipartRequestObjectField { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub field_a: Vec, + pub field_b: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MultipartRequestObjectField".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "field_a" => intermediate_rep.field_a.push(::from_str(val).map_err(|x| x.to_string())?), + "field_b" => return std::result::Result::Err("Parsing a container in this style is not supported in MultipartRequestObjectField".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing MultipartRequestObjectField".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MultipartRequestObjectField { + field_a: intermediate_rep.field_a.into_iter().next().ok_or_else(|| "field_a missing in MultipartRequestObjectField".to_string())?, + field_b: intermediate_rep.field_b.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MultipartRequestObjectField - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MultipartRequestObjectField - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MultipartRequestObjectField - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MultipleIdenticalMimeTypesPostRequest { + #[serde(rename = "binary1")] + #[serde(skip_serializing_if="Option::is_none")] + pub binary1: Option, + + #[serde(rename = "binary2")] + #[serde(skip_serializing_if="Option::is_none")] + pub binary2: Option, + +} + + +impl MultipleIdenticalMimeTypesPostRequest { + #[allow(clippy::new_without_default)] + pub fn new() -> MultipleIdenticalMimeTypesPostRequest { + MultipleIdenticalMimeTypesPostRequest { + binary1: None, + binary2: None, + } + } +} + +/// Converts the MultipleIdenticalMimeTypesPostRequest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MultipleIdenticalMimeTypesPostRequest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping binary data binary1 in query parameter serialization + // Skipping binary data binary2 in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MultipleIdenticalMimeTypesPostRequest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MultipleIdenticalMimeTypesPostRequest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub binary1: Vec, + pub binary2: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MultipleIdenticalMimeTypesPostRequest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "binary1" => return std::result::Result::Err("Parsing binary data in this style is not supported in MultipleIdenticalMimeTypesPostRequest".to_string()), + "binary2" => return std::result::Result::Err("Parsing binary data in this style is not supported in MultipleIdenticalMimeTypesPostRequest".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing MultipleIdenticalMimeTypesPostRequest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MultipleIdenticalMimeTypesPostRequest { + binary1: intermediate_rep.binary1.into_iter().next(), + binary2: intermediate_rep.binary2.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MultipleIdenticalMimeTypesPostRequest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MultipleIdenticalMimeTypesPostRequest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MultipleIdenticalMimeTypesPostRequest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/mod.rs new file mode 100644 index 000000000000..27481467e75f --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/mod.rs @@ -0,0 +1,645 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; +use hyper_0_10::header::{Headers, ContentType}; +use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; +use mime_multipart::{read_multipart_body, Node, Part}; +use multipart::server::Multipart; +use multipart::server::save::{PartialReason, SaveResult}; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + MultipartRelatedRequestPostResponse, + MultipartRequestPostResponse, + MultipleIdenticalMimeTypesPostResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/multipart_related_request$", + r"^/multipart_request$", + r"^/multiple-identical-mime-types$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_MULTIPART_RELATED_REQUEST: usize = 0; + pub(crate) static ID_MULTIPART_REQUEST: usize = 1; + pub(crate) static ID_MULTIPLE_IDENTICAL_MIME_TYPES: usize = 2; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + multipart_form_size_limit: Option, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData + } + } + + /// Configure size limit when inspecting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()) + .multipart_form_size_limit(self.multipart_form_size_limit); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + multipart_form_size_limit: Option, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData + } + } + + /// Configure size limit when extracting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + multipart_form_size_limit: Option, + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // MultipartRelatedRequestPost - POST /multipart_related_request + hyper::Method::POST if path.matched(paths::ID_MULTIPART_RELATED_REQUEST) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + // Get multipart chunks. + + // Create headers from top-level content type header. + let multipart_headers = match swagger::multipart::related::create_multipart_headers(headers.get(CONTENT_TYPE)) { + Ok(headers) => headers, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(e)) + .expect("Unable to create Bad Request response due to unable to read content-type header for MultipartRelatedRequestPost")); + } + }; + + // &*body expresses the body as a byteslice, &mut provides a + // mutable reference to that byteslice. + let nodes = match read_multipart_body(&mut&*body, &multipart_headers, false) { + Ok(nodes) => nodes, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Could not read multipart body for MultipartRelatedRequestPost: {e}"))) + .expect("Unable to create Bad Request response due to unable to read multipart body for MultipartRelatedRequestPost")); + } + }; + + let mut param_object_field = None; + let mut param_optional_binary_field = None; + let mut param_required_binary_field = None; + + for node in nodes { + if let Node::Part(part) = node { + let content_type = part.content_type().map(|x| format!("{x}")); + match content_type.as_deref() { + Some("application/json") if param_object_field.is_none() => { + // Extract JSON part. + let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); + let json_data: models::MultipartRequestObjectField = match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in JSON part: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(json_data) => json_data, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter models::MultipartRequestObjectField - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter models::MultipartRequestObjectField due to schema")) + }; + // Push JSON part to return object. + param_object_field.get_or_insert(json_data); + }, + Some("application/zip") if param_optional_binary_field.is_none() => { + param_optional_binary_field.get_or_insert(swagger::ByteArray(part.body)); + }, + Some("image/png") if param_required_binary_field.is_none() => { + param_required_binary_field.get_or_insert(swagger::ByteArray(part.body)); + }, + Some(content_type) => { + warn!("Ignoring unexpected content type: {content_type}"); + unused_elements.push(content_type.to_string()); + }, + None => { + warn!("Missing content type"); + }, + } + } else { + unimplemented!("No support for handling unexpected parts"); + // unused_elements.push(); + } + } + + // Check that the required multipart chunks are present. + let param_required_binary_field = match param_required_binary_field { + Some(x) => x, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required multipart/related parameter required_binary_field".to_string())) + .expect("Unable to create Bad Request response for missing multipart/related parameter required_binary_field due to schema")) + }; + + + let result = api_impl.multipart_related_request_post( + param_required_binary_field, + param_object_field, + param_optional_binary_field, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + MultipartRelatedRequestPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // MultipartRequestPost - POST /multipart_request + hyper::Method::POST if path.matched(paths::ID_MULTIPART_REQUEST) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let boundary = match swagger::multipart::form::boundary(&headers) { + Some(boundary) => boundary.to_string(), + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Couldn't find valid multipart body".to_string())) + .expect("Unable to create Bad Request response for incorrect boundary")), + }; + + use std::io::Read; + + // Read Form Parameters from body + let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary) + .save() + .size_limit(multipart_form_size_limit) + .temp() + { + SaveResult::Full(entries) => { + entries + }, + SaveResult::Partial(_, PartialReason::CountLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .expect("Unable to create Bad Request response due to excessive parts")) + }, + SaveResult::Partial(_, PartialReason::SizeLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive data".to_string())) + .expect("Unable to create Bad Request response due to excessive data")) + }, + SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to invalid data".to_string())) + .expect("Unable to create Bad Request response due to invalid data")) + }, + SaveResult::Partial(_, PartialReason::IoError(_)) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process message part due an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + SaveResult::Error(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + }; + let field_string_field = entries.fields.remove("string_field"); + let param_string_field = match field_string_field { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for string_field"); + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let string_field_model: String = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("string_field data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter string_field")) + } + }; + string_field_model + }, + None => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required form parameter string_field".to_string())) + .expect("Unable to create Bad Request due to missing required form parameter string_field")) + } + }; + let field_optional_string_field = entries.fields.remove("optional_string_field"); + let param_optional_string_field = match field_optional_string_field { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for optional_string_field"); + Some({ + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let optional_string_field_model: String = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("optional_string_field data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter optional_string_field")) + } + }; + optional_string_field_model + }) + }, + None => { + None + } + }; + let field_object_field = entries.fields.remove("object_field"); + let param_object_field = match field_object_field { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for object_field"); + Some({ + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let object_field_model: models::MultipartRequestObjectField = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("object_field data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter object_field")) + } + }; + object_field_model + }) + }, + None => { + None + } + }; + let field_binary_field = entries.fields.remove("binary_field"); + let param_binary_field = match field_binary_field { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for binary_field"); + let mut data = vec![]; + reader.read_to_end(&mut data).expect("Reading saved binary data should never fail"); + swagger::ByteArray(data) + }, + None => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required form parameter binary_field".to_string())) + .expect("Unable to create Bad Request due to missing required form parameter binary_field")) + } + }; + + + let result = api_impl.multipart_request_post( + param_string_field, + param_binary_field, + param_optional_string_field, + param_object_field, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MultipartRequestPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types + hyper::Method::POST if path.matched(paths::ID_MULTIPLE_IDENTICAL_MIME_TYPES) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + // Get multipart chunks. + + // Create headers from top-level content type header. + let multipart_headers = match swagger::multipart::related::create_multipart_headers(headers.get(CONTENT_TYPE)) { + Ok(headers) => headers, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(e)) + .expect("Unable to create Bad Request response due to unable to read content-type header for MultipleIdenticalMimeTypesPost")); + } + }; + + // &*body expresses the body as a byteslice, &mut provides a + // mutable reference to that byteslice. + let nodes = match read_multipart_body(&mut&*body, &multipart_headers, false) { + Ok(nodes) => nodes, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Could not read multipart body for MultipleIdenticalMimeTypesPost: {e}"))) + .expect("Unable to create Bad Request response due to unable to read multipart body for MultipleIdenticalMimeTypesPost")); + } + }; + + let mut param_binary1 = None; + let mut param_binary2 = None; + + for node in nodes { + if let Node::Part(part) = node { + let content_type = part.content_type().map(|x| format!("{x}")); + match content_type.as_deref() { + Some("application/octet-stream") if param_binary1.is_none() => { + param_binary1.get_or_insert(swagger::ByteArray(part.body)); + }, + Some("application/octet-stream") if param_binary2.is_none() => { + param_binary2.get_or_insert(swagger::ByteArray(part.body)); + }, + Some(content_type) => { + warn!("Ignoring unexpected content type: {content_type}"); + unused_elements.push(content_type.to_string()); + }, + None => { + warn!("Missing content type"); + }, + } + } else { + unimplemented!("No support for handling unexpected parts"); + // unused_elements.push(); + } + } + + // Check that the required multipart chunks are present. + + + let result = api_impl.multiple_identical_mime_types_post( + param_binary1, + param_binary2, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + MultipleIdenticalMimeTypesPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + _ if path.matched(paths::ID_MULTIPART_RELATED_REQUEST) => method_not_allowed(), + _ if path.matched(paths::ID_MULTIPART_REQUEST) => method_not_allowed(), + _ if path.matched(paths::ID_MULTIPLE_IDENTICAL_MIME_TYPES) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + self.multipart_form_size_limit, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // MultipartRelatedRequestPost - POST /multipart_related_request + hyper::Method::POST if path.matched(paths::ID_MULTIPART_RELATED_REQUEST) => Some("MultipartRelatedRequestPost"), + // MultipartRequestPost - POST /multipart_request + hyper::Method::POST if path.matched(paths::ID_MULTIPART_REQUEST) => Some("MultipartRequestPost"), + // MultipleIdenticalMimeTypesPost - POST /multiple-identical-mime-types + hyper::Method::POST if path.matched(paths::ID_MULTIPLE_IDENTICAL_MIME_TYPES) => Some("MultipleIdenticalMimeTypesPost"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/multipart-v3/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/no-example-v3/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/no-example-v3/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/no-example-v3/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.gitignore b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/FILES new file mode 100644 index 000000000000..7c4254323479 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/FILES @@ -0,0 +1,24 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/OpGetRequest.md +docs/default_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/Cargo.toml new file mode 100644 index 000000000000..4315116e7edf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/Cargo.toml @@ -0,0 +1,96 @@ +[package] +name = "no-example-v3" +version = "0.0.1" +authors = ["OpenAPI Generator team and contributors"] +description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "no-example-v3" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/README.md b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/README.md new file mode 100644 index 000000000000..c907663f2626 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/README.md @@ -0,0 +1,139 @@ +# Rust API for no-example-v3 + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +## Overview + +This client/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: 0.0.1 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `no-example-v3` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `no-example-v3`: + +* The example server starts up a web server using the `no-example-v3` + 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 `no-example-v3` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[****](docs/default_api.md#) | **GET** /op | + + +## Documentation For Models + + - [OpGetRequest](docs/OpGetRequest.md) + + +## Documentation For Authorization +Endpoints do not require authorization. + + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/api/openapi.yaml new file mode 100644 index 000000000000..c031c1bb6a16 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/api/openapi.yaml @@ -0,0 +1,28 @@ +openapi: 3.0.1 +info: + title: Regression test for an API which doesn't have any example + version: 0.0.1 +servers: +- url: / +paths: + /op: + get: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/_op_get_request" + required: true + responses: + "200": + description: OK +components: + schemas: + _op_get_request: + properties: + property: + type: string + required: + - property + type: object + diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/bin/cli.rs new file mode 100644 index 000000000000..1f77caa4a8f6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/bin/cli.rs @@ -0,0 +1,151 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use no_example_v3::{ + models, ApiNoContext, Client, ContextWrapperExt, + OpGetResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "Regression test for an API which doesn't have any example", + version = "0.0.1", + about = "CLI access to Regression test for an API which doesn't have any example" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, +} + +#[derive(StructOpt, Debug)] +enum Operation { + OpGet { + #[structopt(parse(try_from_str = parse_json))] + op_get_request: models::OpGetRequest, + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let auth_data: Option = None; + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::OpGet { + op_get_request, + } => { + info!("Performing a OpGet request"); + + let result = client.op_get( + op_get_request, + ).await?; + debug!("Result: {:?}", result); + + match result { + OpGetResponse::OK + => "OK\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/DogAllOf.md b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/OpGetRequest.md similarity index 80% rename from samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/DogAllOf.md rename to samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/OpGetRequest.md index 78789d647dbf..70c884fc7b06 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/DogAllOf.md +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/OpGetRequest.md @@ -1,9 +1,9 @@ -# DogAllOf +# OpGetRequest ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**breed** | **String** | | [optional] [default to None] +**property** | **String** | | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/default_api.md new file mode 100644 index 000000000000..638f9f80314c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/docs/default_api.md @@ -0,0 +1,34 @@ +# default_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +****](default_api.md#) | **GET** /op | + + +# **** +> (op_get_request) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **op_get_request** | [**OpGetRequest**](OpGetRequest.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/client_auth.rs new file mode 100644 index 000000000000..415b7b829981 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use no_example_v3::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/main.rs new file mode 100644 index 000000000000..79405fc5d227 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/client/main.rs @@ -0,0 +1,117 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use no_example_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + OpGetResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + "".to_owned() + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + /* Disabled because there's no example. + Some("OpGet") => { + let result = rt.block_on(client.op_get( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/main.rs new file mode 100644 index 000000000000..ae01015501e5 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for no_example_v3 implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server.rs new file mode 100644 index 000000000000..c4e6006fb34e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server.rs @@ -0,0 +1,123 @@ +//! Main library entry point for no_example_v3 implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use no_example_v3::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + no_example_v3::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use no_example_v3::{ + Api, + OpGetResponse, +}; +use no_example_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn op_get( + &self, + op_get_request: models::OpGetRequest, + context: &C) -> Result + { + info!("op_get({:?}) - X-Span-ID: {:?}", op_get_request, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server_auth.rs new file mode 100644 index 000000000000..a807460bd9a1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/examples/server/server_auth.rs @@ -0,0 +1,127 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use no_example_v3::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + "".to_owned() + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/client/mod.rs new file mode 100644 index 000000000000..9cd608f8c3c7 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/client/mod.rs @@ -0,0 +1,464 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + OpGetResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn op_get( + &self, + param_op_get_request: models::OpGetRequest, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_op_get_request).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + OpGetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/context.rs new file mode 100644 index 000000000000..ee8e118587bb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/context.rs @@ -0,0 +1,114 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/lib.rs new file mode 100644 index 000000000000..009a31837355 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/lib.rs @@ -0,0 +1,115 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "0.0.1"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum OpGetResponse { + /// OK + OK +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn op_get( + &self, + op_get_request: models::OpGetRequest, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn op_get( + &self, + op_get_request: models::OpGetRequest, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn op_get( + &self, + op_get_request: models::OpGetRequest, + ) -> Result + { + let context = self.context().clone(); + self.api().op_get(op_get_request, &context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/models.rs new file mode 100644 index 000000000000..06440d8071b0 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/models.rs @@ -0,0 +1,164 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OpGetRequest { + #[serde(rename = "property")] + pub property: String, + +} + + +impl OpGetRequest { + #[allow(clippy::new_without_default)] + pub fn new(property: String, ) -> OpGetRequest { + OpGetRequest { + property, + } + } +} + +/// Converts the OpGetRequest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for OpGetRequest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("property".to_string()), + Some(self.property.to_string()), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OpGetRequest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for OpGetRequest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub property: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing OpGetRequest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "property" => intermediate_rep.property.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing OpGetRequest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(OpGetRequest { + property: intermediate_rep.property.into_iter().next().ok_or_else(|| "property missing in OpGetRequest".to_string())?, + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OpGetRequest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OpGetRequest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OpGetRequest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/mod.rs new file mode 100644 index 000000000000..a57271576376 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/mod.rs @@ -0,0 +1,249 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + OpGetResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/op$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_OP: usize = 0; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // OpGet - GET /op + hyper::Method::GET if path.matched(paths::ID_OP) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_op_get_request: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_op_get_request) => param_op_get_request, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter OpGetRequest - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter OpGetRequest due to schema")), + } + } else { + None + }; + let param_op_get_request = match param_op_get_request { + Some(param_op_get_request) => param_op_get_request, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter OpGetRequest")) + .expect("Unable to create Bad Request response for missing body parameter OpGetRequest")), + }; + + + let result = api_impl.op_get( + param_op_get_request, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + OpGetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + _ if path.matched(paths::ID_OP) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // OpGet - GET /op + hyper::Method::GET if path.matched(paths::ID_OP) => Some("OpGet"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/no-example-v3/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/openapi-v3/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/openapi-v3/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/openapi-v3/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.gitignore b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/FILES new file mode 100644 index 000000000000..5f799d4f657d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/FILES @@ -0,0 +1,64 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/AdditionalPropertiesReferencedAnyOfObject.md +docs/AdditionalPropertiesWithList.md +docs/AdditionalPropertiesWithNullable.md +docs/AnotherXmlArray.md +docs/AnotherXmlInner.md +docs/AnotherXmlObject.md +docs/AnyOfGet202Response.md +docs/AnyOfHashMapObject.md +docs/AnyOfObject.md +docs/AnyOfObjectAnyOf.md +docs/AnyOfProperty.md +docs/DuplicateXmlObject.md +docs/EnumWithStarObject.md +docs/Err.md +docs/Error.md +docs/Model12345AnyOfObject.md +docs/Model12345AnyOfObjectAnyOf.md +docs/MultigetGet201Response.md +docs/MyId.md +docs/MyIdList.md +docs/NullableObject.md +docs/NullableTest.md +docs/ObjectHeader.md +docs/ObjectParam.md +docs/ObjectUntypedProps.md +docs/ObjectWithArrayOfObjects.md +docs/Ok.md +docs/OneOfGet200Response.md +docs/OptionalObjectHeader.md +docs/RequiredObjectHeader.md +docs/Result.md +docs/StringEnum.md +docs/StringObject.md +docs/UuidObject.md +docs/XmlArray.md +docs/XmlInner.md +docs/XmlObject.md +docs/default_api.md +docs/repo_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/client/server.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/callbacks.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/callbacks.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/Cargo.toml new file mode 100644 index 000000000000..4f8d249eb265 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/Cargo.toml @@ -0,0 +1,104 @@ +[package] +name = "openapi-v3" +version = "1.0.7" +authors = ["OpenAPI Generator team and contributors"] +description = "API under test" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "serde_urlencoded", + "serde_ignored", "regex", "percent-encoding", "lazy_static", + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "native-tls", "hyper-openssl", "hyper-tls", "openssl", + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition +# TODO: this should be updated to point at the official crate once +# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream +serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} +uuid = {version = "1.3.1", features = ["serde", "v4"]} + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific +serde_urlencoded = {version = "0.6.1", optional = true} + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "openapi-v3" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/README.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/README.md new file mode 100644 index 000000000000..674a864139d1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/README.md @@ -0,0 +1,265 @@ +# Rust API for openapi-v3 + +API under test + +## Overview + +This client/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: 1.0.7 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `openapi-v3` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `openapi-v3`: + +* The example server starts up a web server using the `openapi-v3` + router, and supplies a trivial implementation of `Api` which returns failure + for every operation. +* The example client provides a CLI which lets you invoke + any single operation on the `openapi-v3` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client AnyOfGet +cargo run --example client CallbackWithHeaderPost +cargo run --example client ComplexQueryParamGet +cargo run --example client ExamplesTest +cargo run --example client FormTest +cargo run --example client GetWithBooleanParameter +cargo run --example client JsonComplexQueryParamGet +cargo run --example client MandatoryRequestHeaderGet +cargo run --example client MergePatchJsonGet +cargo run --example client MultigetGet +cargo run --example client MultipleAuthSchemeGet +cargo run --example client OneOfGet +cargo run --example client OverrideServerGet +cargo run --example client ParamgetGet +cargo run --example client ReadonlyAuthSchemeGet +cargo run --example client RegisterCallbackPost +cargo run --example client RequiredOctetStreamPut +cargo run --example client ResponsesWithHeadersGet +cargo run --example client Rfc7807Get +cargo run --example client TwoFirstLetterHeaders +cargo run --example client UntypedPropertyGet +cargo run --example client UuidGet +cargo run --example client XmlExtraPost +cargo run --example client XmlOtherPost +cargo run --example client XmlOtherPut +cargo run --example client XmlPost +cargo run --example client XmlPut +cargo run --example client MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet +cargo run --example client CreateRepo +cargo run --example client GetRepoInfo +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[****](docs/default_api.md#) | **GET** /any-of | +[****](docs/default_api.md#) | **POST** /callback-with-header | +[****](docs/default_api.md#) | **GET** /complex-query-param | +[**ExamplesTest**](docs/default_api.md#ExamplesTest) | **GET** /examples-test | Test examples +[**FormTest**](docs/default_api.md#FormTest) | **POST** /form-test | Test a Form Post +[**GetWithBooleanParameter**](docs/default_api.md#GetWithBooleanParameter) | **GET** /get-with-bool | +[****](docs/default_api.md#) | **GET** /json-complex-query-param | +[****](docs/default_api.md#) | **GET** /mandatory-request-header | +[****](docs/default_api.md#) | **GET** /merge-patch-json | +[****](docs/default_api.md#) | **GET** /multiget | Get some stuff. +[****](docs/default_api.md#) | **GET** /multiple_auth_scheme | +[****](docs/default_api.md#) | **GET** /one-of | +[****](docs/default_api.md#) | **GET** /override-server | +[****](docs/default_api.md#) | **GET** /paramget | Get some stuff with parameters. +[****](docs/default_api.md#) | **GET** /readonly_auth_scheme | +[****](docs/default_api.md#) | **POST** /register-callback | +[****](docs/default_api.md#) | **PUT** /required_octet_stream | +[****](docs/default_api.md#) | **GET** /responses_with_headers | +[****](docs/default_api.md#) | **GET** /rfc7807 | +[**TwoFirstLetterHeaders**](docs/default_api.md#TwoFirstLetterHeaders) | **POST** /operation-two-first-letter-headers | +[****](docs/default_api.md#) | **GET** /untyped_property | +[****](docs/default_api.md#) | **GET** /uuid | +[****](docs/default_api.md#) | **POST** /xml_extra | +[****](docs/default_api.md#) | **POST** /xml_other | +[****](docs/default_api.md#) | **PUT** /xml_other | +[****](docs/default_api.md#) | **POST** /xml | Post an array. It's important we test apostrophes, so include one here. +[****](docs/default_api.md#) | **PUT** /xml | +[****](docs/default_api.md#) | **GET** /enum_in_path/{path_param} | +[****](docs/default_api.md#) | **GET** /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b} | +[**CreateRepo**](docs/repo_api.md#CreateRepo) | **POST** /repos | +[**GetRepoInfo**](docs/repo_api.md#GetRepoInfo) | **GET** /repos/{repoId} | + + +## Documentation For Models + + - [AdditionalPropertiesReferencedAnyOfObject](docs/AdditionalPropertiesReferencedAnyOfObject.md) + - [AdditionalPropertiesWithList](docs/AdditionalPropertiesWithList.md) + - [AdditionalPropertiesWithNullable](docs/AdditionalPropertiesWithNullable.md) + - [AnotherXmlArray](docs/AnotherXmlArray.md) + - [AnotherXmlInner](docs/AnotherXmlInner.md) + - [AnotherXmlObject](docs/AnotherXmlObject.md) + - [AnyOfGet202Response](docs/AnyOfGet202Response.md) + - [AnyOfHashMapObject](docs/AnyOfHashMapObject.md) + - [AnyOfObject](docs/AnyOfObject.md) + - [AnyOfObjectAnyOf](docs/AnyOfObjectAnyOf.md) + - [AnyOfProperty](docs/AnyOfProperty.md) + - [DuplicateXmlObject](docs/DuplicateXmlObject.md) + - [EnumWithStarObject](docs/EnumWithStarObject.md) + - [Err](docs/Err.md) + - [Error](docs/Error.md) + - [Model12345AnyOfObject](docs/Model12345AnyOfObject.md) + - [Model12345AnyOfObjectAnyOf](docs/Model12345AnyOfObjectAnyOf.md) + - [MultigetGet201Response](docs/MultigetGet201Response.md) + - [MyId](docs/MyId.md) + - [MyIdList](docs/MyIdList.md) + - [NullableObject](docs/NullableObject.md) + - [NullableTest](docs/NullableTest.md) + - [ObjectHeader](docs/ObjectHeader.md) + - [ObjectParam](docs/ObjectParam.md) + - [ObjectUntypedProps](docs/ObjectUntypedProps.md) + - [ObjectWithArrayOfObjects](docs/ObjectWithArrayOfObjects.md) + - [Ok](docs/Ok.md) + - [OneOfGet200Response](docs/OneOfGet200Response.md) + - [OptionalObjectHeader](docs/OptionalObjectHeader.md) + - [RequiredObjectHeader](docs/RequiredObjectHeader.md) + - [Result](docs/Result.md) + - [StringEnum](docs/StringEnum.md) + - [StringObject](docs/StringObject.md) + - [UuidObject](docs/UuidObject.md) + - [XmlArray](docs/XmlArray.md) + - [XmlInner](docs/XmlInner.md) + - [XmlObject](docs/XmlObject.md) + + +## Documentation For Authorization + +Authentication schemes defined for the API: +### authScheme +- **Type**: OAuth +- **Flow**: accessCode +- **Authorization URL**: http://example.org +- **Scopes**: + - **test.read**: Allowed to read state. + - **test.write**: Allowed to change state. + +Example +``` +``` + +Or via OAuth2 module to automatically refresh tokens and perform user authentication. +``` +``` +### additionalAuthScheme +- **Type**: OAuth +- **Flow**: accessCode +- **Authorization URL**: http://example.org +- **Scopes**: + - **additional.test.read**: Allowed to read state. + - **additional.test.write**: Allowed to change state. + +Example +``` +``` + +Or via OAuth2 module to automatically refresh tokens and perform user authentication. +``` +``` + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/api/openapi.yaml new file mode 100644 index 000000000000..326b81e29b6f --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/api/openapi.yaml @@ -0,0 +1,884 @@ +openapi: 3.0.1 +info: + description: API under test + title: My title + version: 1.0.7 +servers: +- url: / +paths: + /xml: + post: + description: "" + requestBody: + content: + application/xml: + schema: + $ref: "#/components/schemas/xml_array" + responses: + "201": + description: OK + "400": + description: Bad Request + summary: "Post an array. It's important we test apostrophes, so include one\ + \ here." + put: + requestBody: + content: + application/xml: + schema: + $ref: "#/components/schemas/xml_object" + responses: + "201": + description: OK + "400": + description: Bad Request + /paramget: + get: + parameters: + - description: The stuff to get + explode: false + in: query + name: uuid + required: false + schema: + $ref: "#/components/schemas/UuidObject" + style: form + - description: Some object to pass as query parameter + explode: false + in: query + name: someObject + required: false + schema: + $ref: "#/components/schemas/ObjectParam" + style: form + - description: Some list to pass as query parameter + explode: false + in: query + name: someList + required: false + schema: + $ref: "#/components/schemas/MyIDList" + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: JSON rsp + summary: Get some stuff with parameters. + /multiget: + get: + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: JSON rsp + "201": + content: + application/xml: + schema: + $ref: "#/components/schemas/_multiget_get_201_response" + description: XML rsp + "202": + content: + application/octet-stream: + schema: + format: binary + type: string + description: octet rsp + "203": + content: + text/plain: + schema: + type: string + description: string rsp + "204": + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: Duplicate Response long text. One. + "205": + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: Duplicate Response long text. Two. + "206": + content: + application/json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: Duplicate Response long text. Three. + summary: Get some stuff. + /xml_other: + post: + requestBody: + content: + text/xml: + schema: + $ref: "#/components/schemas/anotherXmlObject" + responses: + "201": + content: + text/xml: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: OK + "400": + description: Bad Request + put: + requestBody: + content: + application/xml: + schema: + $ref: "#/components/schemas/anotherXmlArray" + responses: + "201": + description: OK + "400": + description: Bad Request + /xml_extra: + post: + requestBody: + content: + application/xml: + schema: + $ref: "#/components/schemas/duplicate_xml_object" + responses: + "201": + description: OK + "400": + description: Bad Request + /uuid: + get: + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/UuidObject" + description: Duplicate Response long text. One. + /required_octet_stream: + put: + requestBody: + content: + application/octet-stream: + schema: + format: byte + type: string + required: true + responses: + "200": + description: OK + /readonly_auth_scheme: + get: + responses: + "200": + description: Check that limiting to a single required auth scheme works + security: + - authScheme: + - test.read + /multiple_auth_scheme: + get: + responses: + "200": + description: Check that limiting to multiple required auth schemes works + security: + - authScheme: + - test.read + - test.write + /untyped_property: + get: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/ObjectUntypedProps" + responses: + "200": + description: Check that untyped properties works + /responses_with_headers: + get: + responses: + "200": + content: + application/json: + schema: + type: String + description: Success + headers: + Success-Info: + explode: false + required: true + schema: + type: String + style: simple + Bool-Header: + explode: false + schema: + type: bool + style: simple + Object-Header: + explode: false + schema: + $ref: "#/components/schemas/ObjectHeader" + style: simple + "412": + description: Precondition Failed + headers: + Further-Info: + explode: false + schema: + type: String + style: simple + Failure-Info: + explode: false + schema: + type: String + style: simple + /mandatory-request-header: + get: + parameters: + - explode: false + in: header + name: X-Header + required: true + schema: + type: string + style: simple + responses: + "200": + description: Success + /register-callback: + post: + callbacks: + callback: + '{$request.query.url}/callback': + post: + operationId: CallbackCallbackPost + responses: + "204": + description: OK + x-callback-request: true + parameters: + - explode: true + in: query + name: url + required: true + schema: + format: uri + type: string + style: form + responses: + "204": + description: OK + /callback-with-header: + post: + callbacks: + callback: + '{$request.query.url}/callback-with-header': + post: + operationId: CallbackCallbackWithHeaderPost + parameters: + - explode: false + in: header + name: Information + required: false + schema: + type: string + style: simple + responses: + "204": + description: OK + x-callback-request: true + parameters: + - explode: true + in: query + name: url + required: true + schema: + format: uri + type: string + style: form + responses: + "204": + description: OK + /rfc7807: + get: + responses: + "204": + content: + application/json: + schema: + $ref: "#/components/schemas/ObjectWithArrayOfObjects" + description: OK + "404": + content: + application/problem+json: + schema: + $ref: "#/components/schemas/ObjectWithArrayOfObjects" + description: NotFound + "406": + content: + application/problem+xml: + schema: + $ref: "#/components/schemas/ObjectWithArrayOfObjects" + description: NotAcceptable + /merge-patch-json: + get: + responses: + "200": + content: + application/merge-patch+json: + schema: + $ref: "#/components/schemas/anotherXmlObject" + description: merge-patch+json-encoded response + /enum_in_path/{path_param}: + get: + parameters: + - explode: false + in: path + name: path_param + required: true + schema: + $ref: "#/components/schemas/StringEnum" + style: simple + responses: + "200": + description: Success + /override-server: + get: + responses: + "204": + description: Success. + servers: + - url: /override + /complex-query-param: + get: + parameters: + - explode: true + in: query + name: list-of-strings + required: false + schema: + items: + $ref: "#/components/schemas/StringObject" + type: array + style: form + responses: + "200": + description: Success + /repos/{repoId}: + get: + operationId: GetRepoInfo + parameters: + - explode: false + in: path + name: repoId + required: true + schema: + type: string + style: simple + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/StringObject" + description: OK + tags: + - repo + - Info + /repos: + post: + operationId: CreateRepo + requestBody: + content: + application/json: + example: + requiredParam: true + schema: + $ref: "#/components/schemas/ObjectParam" + required: true + responses: + "200": + description: Success + tags: + - Repo + /one-of: + get: + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/_one_of_get_200_response" + description: Success + /any-of: + get: + parameters: + - description: list of any of objects + explode: true + in: query + name: any-of + required: false + schema: + items: + $ref: "#/components/schemas/AnyOfObject" + minItems: 1 + type: array + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/AnyOfObject" + description: Success + "201": + content: + application/json: + schema: + $ref: "#/components/schemas/12345AnyOfObject" + description: AlternateSuccess + "202": + content: + application/json: + schema: + $ref: "#/components/schemas/_any_of_get_202_response" + description: AnyOfSuccess + /json-complex-query-param: + get: + parameters: + - content: + application/json: + schema: + items: + $ref: "#/components/schemas/StringObject" + type: array + in: query + name: list-of-strings + required: false + responses: + "200": + description: Success + /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b}: + get: + parameters: + - explode: false + in: path + name: path_param_a + required: true + schema: + $ref: "#/components/schemas/StringObject" + style: simple + - explode: false + in: path + name: path_param_b + required: true + schema: + $ref: "#/components/schemas/StringObject" + style: simple + responses: + "200": + description: Success + /get-with-bool: + get: + description: Get with a boolean parameter + operationId: GetWithBooleanParameter + parameters: + - description: Let's check apostrophes get encoded properly! + explode: true + in: query + name: iambool + required: true + schema: + type: boolean + style: form + responses: + "200": + description: OK + /operation-two-first-letter-headers: + post: + description: Check we don't barf if two boolean parameters have the same first + letter + operationId: TwoFirstLetterHeaders + parameters: + - explode: false + in: header + name: x-header-one + required: false + schema: + type: boolean + style: simple + - explode: false + in: header + name: x-header-two + required: false + schema: + type: boolean + style: simple + responses: + "200": + description: OK + /form-test: + post: + operationId: FormTest + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/FormTest_request" + required: true + responses: + "200": + description: OK + summary: Test a Form Post + /examples-test: + get: + description: Test examples in OpenAPI + operationId: ExamplesTest + parameters: + - description: A list of IDs to get + examples: + oneId: + value: + - foo + multipleIds: + value: + - foo + - bar + explode: false + in: query + name: ids + required: false + schema: + items: + type: string + type: array + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/AdditionalPropertiesReferencedAnyOfObject" + description: OK + summary: Test examples +components: + parameters: + ids: + description: A list of IDs to get + examples: + oneId: + value: + - foo + multipleIds: + value: + - foo + - bar + explode: false + in: query + name: ids + required: false + schema: + items: + type: string + type: array + style: form + schemas: + AnyOfProperty: + description: Test containing an anyOf object + properties: + requiredAnyOf: + $ref: "#/components/schemas/AnyOfObject" + optionalAnyOf: + $ref: "#/components/schemas/12345AnyOfObject" + required: + - requiredAnyOf + AdditionalPropertiesReferencedAnyOfObject: + additionalProperties: + $ref: "#/components/schemas/AnyOfProperty" + description: Check that an object with only additional properties that references + another object (e.g. an anyOf object) isn't treated as freeForm + type: object + AnyOfObject: + anyOf: + - $ref: "#/components/schemas/AnyOfObject_anyOf" + - description: Alternate option + type: string + description: Test a model containing an anyOf + AnyOfHashMapObject: + anyOf: + - type: string + - additionalProperties: + type: string + type: object + description: Test a model containing an anyOf of a hash map + "12345AnyOfObject": + anyOf: + - $ref: "#/components/schemas/_12345AnyOfObject_anyOf" + - description: Alternate option + type: string + description: Test a model containing an anyOf that starts with a number + EnumWithStarObject: + description: Test a model containing a special character in the enum + enum: + - FOO + - BAR + - '*' + type: string + UuidObject: + description: Test a model containing a UUID + format: uuid + type: string + xml_array: + items: + $ref: "#/components/schemas/xml_inner" + type: array + xml: + name: CamelXmlArray + wrapped: true + xml_inner: + type: string + xml: + name: camelXmlInner + xml_object: + description: An XML object + properties: + innerString: + type: string + other_inner_rename: + type: integer + title: an XML object + type: object + xml: + name: camelXmlObject + namespace: http://foo.bar + duplicate_xml_object: + description: An XML object + properties: + inner_string: + type: string + inner_array: + $ref: "#/components/schemas/xml_array" + required: + - inner_array + type: object + xml: + name: camelDuplicateXmlObject + namespace: http://different.bar + anotherXmlArray: + items: + $ref: "#/components/schemas/anotherXmlInner" + type: array + xml: + name: snake_another_xml_array + wrapped: true + anotherXmlInner: + type: string + xml: + name: snake_another_xml_inner + anotherXmlObject: + description: An XML object + example: + inner_string: inner_string + properties: + inner_string: + type: string + type: object + xml: + name: snake_another_xml_object + namespace: http://foo.bar + ObjectWithArrayOfObjects: + example: + objectArray: + - null + - null + properties: + objectArray: + items: + $ref: "#/components/schemas/StringObject" + type: array + type: object + StringObject: + type: string + MyIDList: + items: + $ref: "#/components/schemas/MyID" + type: array + MyID: + type: integer + ObjectUntypedProps: + example: + not_required_untyped_nullable: "" + required_untyped: "" + required_untyped_nullable: "" + not_required_untyped: "" + properties: + required_untyped: + nullable: false + required_untyped_nullable: + nullable: true + not_required_untyped: + nullable: false + not_required_untyped_nullable: + nullable: false + required: + - required_untyped + - required_untyped_nullable + type: object + ObjectParam: + example: + requiredParam: true + optionalParam: 0 + properties: + requiredParam: + type: boolean + optionalParam: + type: integer + required: + - requiredParam + type: object + ObjectHeader: + properties: + requiredObjectHeader: + type: boolean + optionalObjectHeader: + type: integer + required: + - requiredObjectHeader + type: object + RequiredObjectHeader: + type: boolean + OptionalObjectHeader: + type: integer + AdditionalPropertiesWithNullable: + properties: + nullableString: + nullable: true + type: string + nullableMap: + additionalProperties: + $ref: "#/components/schemas/NullableObject" + type: object + type: object + AdditionalPropertiesWithList: + additionalProperties: + items: + type: string + type: array + maxProperties: 1 + type: object + NullableObject: + nullable: true + type: string + NullableTest: + properties: + nullable: + nullable: true + type: string + nullableWithNullDefault: + nullable: true + type: string + nullableWithPresentDefault: + default: default + nullable: true + type: string + nullableWithNoDefault: + nullable: true + type: string + nullableArray: + items: + type: string + nullable: true + type: array + min_item_test: + items: + type: integer + minItems: 1 + type: array + max_item_test: + items: + type: integer + maxItems: 2 + type: array + min_max_item_test: + items: + type: integer + maxItems: 3 + minItems: 1 + type: array + required: + - nullable + type: object + StringEnum: + enum: + - FOO + - BAR + type: string + Ok: + type: string + Error: + type: string + Err: + type: string + Result: + type: string + _multiget_get_201_response: + properties: + foo: + type: string + type: object + _one_of_get_200_response: + oneOf: + - type: integer + - items: + type: string + type: array + _any_of_get_202_response: + anyOf: + - $ref: "#/components/schemas/StringObject" + - $ref: "#/components/schemas/UuidObject" + FormTest_request: + properties: + requiredArray: + items: + type: string + type: array + type: object + AnyOfObject_anyOf: + enum: + - FOO + - BAR + type: string + _12345AnyOfObject_anyOf: + enum: + - FOO + - BAR + - '*' + type: string + securitySchemes: + authScheme: + flows: + authorizationCode: + authorizationUrl: http://example.org + scopes: + test.read: Allowed to read state. + test.write: Allowed to change state. + tokenUrl: http://example.org + type: oauth2 + additionalAuthScheme: + flows: + authorizationCode: + authorizationUrl: http://example.org + scopes: + additional.test.read: Allowed to read state. + additional.test.write: Allowed to change state. + tokenUrl: http://example.org + type: oauth2 + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/bin/cli.rs new file mode 100644 index 000000000000..7557b8978380 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/bin/cli.rs @@ -0,0 +1,901 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use openapi_v3::{ + models, ApiNoContext, Client, ContextWrapperExt, + AnyOfGetResponse, + CallbackWithHeaderPostResponse, + ComplexQueryParamGetResponse, + ExamplesTestResponse, + FormTestResponse, + GetWithBooleanParameterResponse, + JsonComplexQueryParamGetResponse, + MandatoryRequestHeaderGetResponse, + MergePatchJsonGetResponse, + MultigetGetResponse, + MultipleAuthSchemeGetResponse, + OneOfGetResponse, + OverrideServerGetResponse, + ParamgetGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredOctetStreamPutResponse, + ResponsesWithHeadersGetResponse, + Rfc7807GetResponse, + TwoFirstLetterHeadersResponse, + UntypedPropertyGetResponse, + UuidGetResponse, + XmlExtraPostResponse, + XmlOtherPostResponse, + XmlOtherPutResponse, + XmlPostResponse, + XmlPutResponse, + EnumInPathPathParamGetResponse, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, + CreateRepoResponse, + GetRepoInfoResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "My title", + version = "1.0.7", + about = "CLI access to My title" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, + + /// Bearer token if used for authentication + #[structopt(env = "OPENAPI_V3_BEARER_TOKEN", hide_env_values = true)] + bearer_token: Option, +} + +#[derive(StructOpt, Debug)] +enum Operation { + AnyOfGet { + /// list of any of objects + #[structopt(parse(try_from_str = parse_json), long)] + any_of: Option>, + }, + CallbackWithHeaderPost { + url: String, + }, + ComplexQueryParamGet { + #[structopt(parse(try_from_str = parse_json), long)] + list_of_strings: Option>, + }, + /// Test examples + ExamplesTest { + /// A list of IDs to get + #[structopt(parse(try_from_str = parse_json), long)] + ids: Option>, + }, + /// Test a Form Post + FormTest { + #[structopt(parse(try_from_str = parse_json), long)] + required_array: Option>, + }, + GetWithBooleanParameter { + /// Let's check apostrophes get encoded properly! + #[structopt(short, long)] + iambool: bool, + }, + JsonComplexQueryParamGet { + #[structopt(parse(try_from_str = parse_json), long)] + list_of_strings: Option>, + }, + MandatoryRequestHeaderGet { + x_header: String, + }, + MergePatchJsonGet { + }, + /// Get some stuff. + MultigetGet { + }, + MultipleAuthSchemeGet { + }, + OneOfGet { + }, + OverrideServerGet { + }, + /// Get some stuff with parameters. + ParamgetGet { + /// The stuff to get + #[structopt(parse(try_from_str = parse_json))] + uuid: Option, + /// Some object to pass as query parameter + #[structopt(parse(try_from_str = parse_json))] + some_object: Option, + /// Some list to pass as query parameter + #[structopt(parse(try_from_str = parse_json), long)] + some_list: Option>, + }, + ReadonlyAuthSchemeGet { + }, + RegisterCallbackPost { + url: String, + }, + RequiredOctetStreamPut { + #[structopt(parse(try_from_str = parse_json))] + body: swagger::ByteArray, + }, + ResponsesWithHeadersGet { + }, + Rfc7807Get { + }, + TwoFirstLetterHeaders { + #[structopt(long)] + x_header_one: Option, + #[structopt(long)] + x_header_two: Option, + }, + UntypedPropertyGet { + #[structopt(parse(try_from_str = parse_json))] + object_untyped_props: Option, + }, + UuidGet { + }, + XmlExtraPost { + #[structopt(parse(try_from_str = parse_json))] + duplicate_xml_object: Option, + }, + XmlOtherPost { + #[structopt(parse(try_from_str = parse_json))] + another_xml_object: Option, + }, + XmlOtherPut { + #[structopt(parse(try_from_str = parse_json))] + another_xml_array: Option, + }, + /// Post an array. It's important we test apostrophes, so include one here. + XmlPost { + #[structopt(parse(try_from_str = parse_json))] + xml_array: Option, + }, + XmlPut { + #[structopt(parse(try_from_str = parse_json))] + xml_object: Option, + }, + EnumInPathPathParamGet { + #[structopt(parse(try_from_str = parse_json))] + path_param: models::StringEnum, + }, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet { + path_param_a: String, + path_param_b: String, + }, + CreateRepo { + #[structopt(parse(try_from_str = parse_json))] + object_param: models::ObjectParam, + }, + GetRepoInfo { + repo_id: String, + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let mut auth_data: Option = None; + + if let Some(ref bearer_token) = args.bearer_token { + debug!("Using bearer token"); + auth_data = Some(AuthData::bearer(bearer_token)); + } + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::AnyOfGet { + any_of, + } => { + info!("Performing a AnyOfGet request"); + + let result = client.any_of_get( + any_of.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + AnyOfGetResponse::Success + (body) + => "Success\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + AnyOfGetResponse::AlternateSuccess + (body) + => "AlternateSuccess\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + AnyOfGetResponse::AnyOfSuccess + (body) + => "AnyOfSuccess\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::CallbackWithHeaderPost { + url, + } => { + info!("Performing a CallbackWithHeaderPost request"); + + let result = client.callback_with_header_post( + url, + ).await?; + debug!("Result: {:?}", result); + + match result { + CallbackWithHeaderPostResponse::OK + => "OK\n".to_string() + , + } + } + Operation::ComplexQueryParamGet { + list_of_strings, + } => { + info!("Performing a ComplexQueryParamGet request"); + + let result = client.complex_query_param_get( + list_of_strings.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + ComplexQueryParamGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::ExamplesTest { + ids, + } => { + info!("Performing a ExamplesTest request"); + + let result = client.examples_test( + ids.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + ExamplesTestResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::FormTest { + required_array, + } => { + info!("Performing a FormTest request"); + + let result = client.form_test( + required_array.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + FormTestResponse::OK + => "OK\n".to_string() + , + } + } + Operation::GetWithBooleanParameter { + iambool, + } => { + info!("Performing a GetWithBooleanParameter request"); + + let result = client.get_with_boolean_parameter( + iambool, + ).await?; + debug!("Result: {:?}", result); + + match result { + GetWithBooleanParameterResponse::OK + => "OK\n".to_string() + , + } + } + Operation::JsonComplexQueryParamGet { + list_of_strings, + } => { + info!("Performing a JsonComplexQueryParamGet request"); + + let result = client.json_complex_query_param_get( + list_of_strings.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + JsonComplexQueryParamGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::MandatoryRequestHeaderGet { + x_header, + } => { + info!("Performing a MandatoryRequestHeaderGet request"); + + let result = client.mandatory_request_header_get( + x_header, + ).await?; + debug!("Result: {:?}", result); + + match result { + MandatoryRequestHeaderGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::MergePatchJsonGet { + } => { + info!("Performing a MergePatchJsonGet request"); + + let result = client.merge_patch_json_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + MergePatchJsonGetResponse::Merge + (body) + => "Merge\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::MultigetGet { + } => { + info!("Performing a MultigetGet request"); + + let result = client.multiget_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + MultigetGetResponse::JSONRsp + (body) + => "JSONRsp\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::XMLRsp + (body) + => "XMLRsp\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::OctetRsp + (body) + => "OctetRsp\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::StringRsp + (body) + => "StringRsp\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::DuplicateResponseLongText + (body) + => "DuplicateResponseLongText\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::DuplicateResponseLongText_2 + (body) + => "DuplicateResponseLongText_2\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + MultigetGetResponse::DuplicateResponseLongText_3 + (body) + => "DuplicateResponseLongText_3\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::MultipleAuthSchemeGet { + } => { + info!("Performing a MultipleAuthSchemeGet request"); + + let result = client.multiple_auth_scheme_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks + => "CheckThatLimitingToMultipleRequiredAuthSchemesWorks\n".to_string() + , + } + } + Operation::OneOfGet { + } => { + info!("Performing a OneOfGet request"); + + let result = client.one_of_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + OneOfGetResponse::Success + (body) + => "Success\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::OverrideServerGet { + } => { + info!("Performing a OverrideServerGet request"); + + let result = client.override_server_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + OverrideServerGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::ParamgetGet { + uuid, + some_object, + some_list, + } => { + info!("Performing a ParamgetGet request"); + + let result = client.paramget_get( + uuid, + some_object, + some_list.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + ParamgetGetResponse::JSONRsp + (body) + => "JSONRsp\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::ReadonlyAuthSchemeGet { + } => { + info!("Performing a ReadonlyAuthSchemeGet request"); + + let result = client.readonly_auth_scheme_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks + => "CheckThatLimitingToASingleRequiredAuthSchemeWorks\n".to_string() + , + } + } + Operation::RegisterCallbackPost { + url, + } => { + info!("Performing a RegisterCallbackPost request"); + + let result = client.register_callback_post( + url, + ).await?; + debug!("Result: {:?}", result); + + match result { + RegisterCallbackPostResponse::OK + => "OK\n".to_string() + , + } + } + Operation::RequiredOctetStreamPut { + body, + } => { + info!("Performing a RequiredOctetStreamPut request"); + + let result = client.required_octet_stream_put( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + RequiredOctetStreamPutResponse::OK + => "OK\n".to_string() + , + } + } + Operation::ResponsesWithHeadersGet { + } => { + info!("Performing a ResponsesWithHeadersGet request"); + + let result = client.responses_with_headers_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + ResponsesWithHeadersGetResponse::Success + { + body, + success_info, + bool_header, + object_header, + } + => "Success\n".to_string() + + + &format!("body: {}\n", serde_json::to_string_pretty(&body)?) + + &format!( + "success_info: {}\n", + serde_json::to_string_pretty(&success_info)? + ) + + &format!( + "bool_header: {}\n", + serde_json::to_string_pretty(&bool_header)? + ) + + &format!( + "object_header: {}\n", + serde_json::to_string_pretty(&object_header)? + ), + ResponsesWithHeadersGetResponse::PreconditionFailed + { + further_info, + failure_info, + } + => "PreconditionFailed\n".to_string() + + + &format!( + "further_info: {}\n", + serde_json::to_string_pretty(&further_info)? + ) + + &format!( + "failure_info: {}\n", + serde_json::to_string_pretty(&failure_info)? + ), + } + } + Operation::Rfc7807Get { + } => { + info!("Performing a Rfc7807Get request"); + + let result = client.rfc7807_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Rfc7807GetResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + Rfc7807GetResponse::NotFound + (body) + => "NotFound\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + Rfc7807GetResponse::NotAcceptable + (body) + => "NotAcceptable\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::TwoFirstLetterHeaders { + x_header_one, + x_header_two, + } => { + info!("Performing a TwoFirstLetterHeaders request"); + + let result = client.two_first_letter_headers( + x_header_one, + x_header_two, + ).await?; + debug!("Result: {:?}", result); + + match result { + TwoFirstLetterHeadersResponse::OK + => "OK\n".to_string() + , + } + } + Operation::UntypedPropertyGet { + object_untyped_props, + } => { + info!("Performing a UntypedPropertyGet request"); + + let result = client.untyped_property_get( + object_untyped_props, + ).await?; + debug!("Result: {:?}", result); + + match result { + UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks + => "CheckThatUntypedPropertiesWorks\n".to_string() + , + } + } + Operation::UuidGet { + } => { + info!("Performing a UuidGet request"); + + let result = client.uuid_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + UuidGetResponse::DuplicateResponseLongText + (body) + => "DuplicateResponseLongText\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::XmlExtraPost { + duplicate_xml_object, + } => { + info!("Performing a XmlExtraPost request"); + + let result = client.xml_extra_post( + duplicate_xml_object, + ).await?; + debug!("Result: {:?}", result); + + match result { + XmlExtraPostResponse::OK + => "OK\n".to_string() + , + XmlExtraPostResponse::BadRequest + => "BadRequest\n".to_string() + , + } + } + Operation::XmlOtherPost { + another_xml_object, + } => { + info!("Performing a XmlOtherPost request"); + + let result = client.xml_other_post( + another_xml_object, + ).await?; + debug!("Result: {:?}", result); + + match result { + XmlOtherPostResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + XmlOtherPostResponse::BadRequest + => "BadRequest\n".to_string() + , + } + } + Operation::XmlOtherPut { + another_xml_array, + } => { + info!("Performing a XmlOtherPut request"); + + let result = client.xml_other_put( + another_xml_array, + ).await?; + debug!("Result: {:?}", result); + + match result { + XmlOtherPutResponse::OK + => "OK\n".to_string() + , + XmlOtherPutResponse::BadRequest + => "BadRequest\n".to_string() + , + } + } + Operation::XmlPost { + xml_array, + } => { + info!("Performing a XmlPost request"); + + let result = client.xml_post( + xml_array, + ).await?; + debug!("Result: {:?}", result); + + match result { + XmlPostResponse::OK + => "OK\n".to_string() + , + XmlPostResponse::BadRequest + => "BadRequest\n".to_string() + , + } + } + Operation::XmlPut { + xml_object, + } => { + info!("Performing a XmlPut request"); + + let result = client.xml_put( + xml_object, + ).await?; + debug!("Result: {:?}", result); + + match result { + XmlPutResponse::OK + => "OK\n".to_string() + , + XmlPutResponse::BadRequest + => "BadRequest\n".to_string() + , + } + } + Operation::EnumInPathPathParamGet { + path_param, + } => { + info!("Performing a EnumInPathPathParamGet request on {:?}", ( + &path_param + )); + + let result = client.enum_in_path_path_param_get( + path_param, + ).await?; + debug!("Result: {:?}", result); + + match result { + EnumInPathPathParamGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet { + path_param_a, + path_param_b, + } => { + info!("Performing a MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet request on {:?}", ( + &path_param_a, + &path_param_b + )); + + let result = client.multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + path_param_a, + path_param_b, + ).await?; + debug!("Result: {:?}", result); + + match result { + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::CreateRepo { + object_param, + } => { + info!("Performing a CreateRepo request"); + + let result = client.create_repo( + object_param, + ).await?; + debug!("Result: {:?}", result); + + match result { + CreateRepoResponse::Success + => "Success\n".to_string() + , + } + } + Operation::GetRepoInfo { + repo_id, + } => { + info!("Performing a GetRepoInfo request on {:?}", ( + &repo_id + )); + + let result = client.get_repo_info( + repo_id, + ).await?; + debug!("Result: {:?}", result); + + match result { + GetRepoInfoResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/CatAllOf.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesReferencedAnyOfObject.md similarity index 79% rename from samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/CatAllOf.md rename to samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesReferencedAnyOfObject.md index 9ce8a959ef0b..6e48e803eb2d 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/docs/CatAllOf.md +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesReferencedAnyOfObject.md @@ -1,9 +1,8 @@ -# CatAllOf +# AdditionalPropertiesReferencedAnyOfObject ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**declawed** | **bool** | | [optional] [default to None] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/server/petstore/rust-server/output/no-example-v3/docs/InlineObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithList.md similarity index 78% rename from samples/server/petstore/rust-server/output/no-example-v3/docs/InlineObject.md rename to samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithList.md index 75f57d2c007d..a589150380b4 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/docs/InlineObject.md +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithList.md @@ -1,9 +1,8 @@ -# InlineObject +# AdditionalPropertiesWithList ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**property** | **String** | | [optional] [default to None] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithNullable.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithNullable.md new file mode 100644 index 000000000000..100a70bb5723 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AdditionalPropertiesWithNullable.md @@ -0,0 +1,11 @@ +# AdditionalPropertiesWithNullable + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nullable_string** | **swagger::Nullable** | | [optional] [default to None] +**nullable_map** | **std::collections::HashMap>** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlArray.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlArray.md new file mode 100644 index 000000000000..aa3674f8a248 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlArray.md @@ -0,0 +1,9 @@ +# AnotherXmlArray + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlInner.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlInner.md new file mode 100644 index 000000000000..8901bb75ccb4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlInner.md @@ -0,0 +1,9 @@ +# AnotherXmlInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/no-example-v3/docs/InlineRequest.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlObject.md similarity index 76% rename from samples/server/petstore/rust-server/output/no-example-v3/docs/InlineRequest.md rename to samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlObject.md index 73ca04d17667..9bf2745b5233 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/docs/InlineRequest.md +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnotherXmlObject.md @@ -1,9 +1,9 @@ -# InlineRequest +# AnotherXmlObject ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**property** | **String** | | [optional] [default to None] +**inner_string** | **String** | | [optional] [default to None] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfGet202Response.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfGet202Response.md new file mode 100644 index 000000000000..40639b6228bb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfGet202Response.md @@ -0,0 +1,9 @@ +# AnyOfGet202Response + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfHashMapObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfHashMapObject.md new file mode 100644 index 000000000000..28263cd2a834 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfHashMapObject.md @@ -0,0 +1,9 @@ +# AnyOfHashMapObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObject.md new file mode 100644 index 000000000000..36847cbf6949 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObject.md @@ -0,0 +1,9 @@ +# AnyOfObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObjectAnyOf.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObjectAnyOf.md new file mode 100644 index 000000000000..079256f1726f --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfObjectAnyOf.md @@ -0,0 +1,9 @@ +# AnyOfObjectAnyOf + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfProperty.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfProperty.md new file mode 100644 index 000000000000..c4e69ef4caf6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/AnyOfProperty.md @@ -0,0 +1,11 @@ +# AnyOfProperty + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**required_any_of** | [***models::AnyOfObject**](AnyOfObject.md) | | +**optional_any_of** | [***models::Model12345AnyOfObject**](12345AnyOfObject.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/DuplicateXmlObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/DuplicateXmlObject.md new file mode 100644 index 000000000000..3cd921bde314 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/DuplicateXmlObject.md @@ -0,0 +1,11 @@ +# DuplicateXmlObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**inner_string** | **String** | | [optional] [default to None] +**inner_array** | [***models::XmlArray**](xml_array.md) | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/EnumWithStarObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/EnumWithStarObject.md new file mode 100644 index 000000000000..acbe211f1fcd --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/EnumWithStarObject.md @@ -0,0 +1,9 @@ +# EnumWithStarObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Err.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Err.md new file mode 100644 index 000000000000..58f6f4cadf82 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Err.md @@ -0,0 +1,9 @@ +# Err + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Error.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Error.md new file mode 100644 index 000000000000..725f180224dd --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Error.md @@ -0,0 +1,9 @@ +# Error + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObject.md new file mode 100644 index 000000000000..8999550d65e6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObject.md @@ -0,0 +1,9 @@ +# Model12345AnyOfObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObjectAnyOf.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObjectAnyOf.md new file mode 100644 index 000000000000..096f40837fa6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Model12345AnyOfObjectAnyOf.md @@ -0,0 +1,9 @@ +# Model12345AnyOfObjectAnyOf + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MultigetGet201Response.md similarity index 92% rename from samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md rename to samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MultigetGet201Response.md index 142fba463560..28a7502b7470 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/docs/InlineResponse201.md +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MultigetGet201Response.md @@ -1,4 +1,4 @@ -# InlineResponse201 +# MultigetGet201Response ## Properties Name | Type | Description | Notes diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyId.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyId.md new file mode 100644 index 000000000000..17bc8db207e5 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyId.md @@ -0,0 +1,9 @@ +# MyId + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyIdList.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyIdList.md new file mode 100644 index 000000000000..ccf714b88e5f --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/MyIdList.md @@ -0,0 +1,9 @@ +# MyIdList + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableObject.md new file mode 100644 index 000000000000..8ec9beb94196 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableObject.md @@ -0,0 +1,9 @@ +# NullableObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableTest.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableTest.md new file mode 100644 index 000000000000..be0cda4a1e9c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/NullableTest.md @@ -0,0 +1,17 @@ +# NullableTest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nullable** | **swagger::Nullable** | | +**nullable_with_null_default** | **swagger::Nullable** | | [optional] [default to None] +**nullable_with_present_default** | **swagger::Nullable** | | [optional] [default to Some(swagger::Nullable::Present("default".to_string()))] +**nullable_with_no_default** | **swagger::Nullable** | | [optional] [default to None] +**nullable_array** | **swagger::Nullable>** | | [optional] [default to None] +**min_item_test** | **Vec** | | [optional] [default to None] +**max_item_test** | **Vec** | | [optional] [default to None] +**min_max_item_test** | **Vec** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectHeader.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectHeader.md new file mode 100644 index 000000000000..c5fb58d312cf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectHeader.md @@ -0,0 +1,11 @@ +# ObjectHeader + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**required_object_header** | **bool** | | +**optional_object_header** | **i32** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectParam.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectParam.md new file mode 100644 index 000000000000..caac197917ab --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectParam.md @@ -0,0 +1,11 @@ +# ObjectParam + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**required_param** | **bool** | | +**optional_param** | **i32** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectUntypedProps.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectUntypedProps.md new file mode 100644 index 000000000000..1b668dec84f2 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectUntypedProps.md @@ -0,0 +1,13 @@ +# ObjectUntypedProps + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**required_untyped** | [***serde_json::Value**](.md) | | +**required_untyped_nullable** | [***swagger::Nullable**](.md) | | +**not_required_untyped** | [***serde_json::Value**](.md) | | [optional] [default to None] +**not_required_untyped_nullable** | [***serde_json::Value**](.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectWithArrayOfObjects.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectWithArrayOfObjects.md new file mode 100644 index 000000000000..6801b3966ec4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/ObjectWithArrayOfObjects.md @@ -0,0 +1,10 @@ +# ObjectWithArrayOfObjects + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**object_array** | **Vec** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Ok.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Ok.md new file mode 100644 index 000000000000..723258446330 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Ok.md @@ -0,0 +1,9 @@ +# Ok + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OneOfGet200Response.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OneOfGet200Response.md new file mode 100644 index 000000000000..154891aef9e6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OneOfGet200Response.md @@ -0,0 +1,9 @@ +# OneOfGet200Response + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OptionalObjectHeader.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OptionalObjectHeader.md new file mode 100644 index 000000000000..892c56b99189 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/OptionalObjectHeader.md @@ -0,0 +1,9 @@ +# OptionalObjectHeader + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/RequiredObjectHeader.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/RequiredObjectHeader.md new file mode 100644 index 000000000000..2cc642196fd8 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/RequiredObjectHeader.md @@ -0,0 +1,9 @@ +# RequiredObjectHeader + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Result.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Result.md new file mode 100644 index 000000000000..a6f795bc9662 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/Result.md @@ -0,0 +1,9 @@ +# Result + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringEnum.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringEnum.md new file mode 100644 index 000000000000..b0009f7e8269 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringEnum.md @@ -0,0 +1,9 @@ +# StringEnum + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringObject.md new file mode 100644 index 000000000000..2b822551043c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/StringObject.md @@ -0,0 +1,9 @@ +# StringObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/UuidObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/UuidObject.md new file mode 100644 index 000000000000..d308889dad47 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/UuidObject.md @@ -0,0 +1,9 @@ +# UuidObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlArray.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlArray.md new file mode 100644 index 000000000000..e58358c6a790 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlArray.md @@ -0,0 +1,9 @@ +# XmlArray + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlInner.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlInner.md new file mode 100644 index 000000000000..99b76bc3a613 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlInner.md @@ -0,0 +1,9 @@ +# XmlInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlObject.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlObject.md new file mode 100644 index 000000000000..49ab2bec0e79 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/XmlObject.md @@ -0,0 +1,11 @@ +# XmlObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**inner_string** | **String** | | [optional] [default to None] +**other_inner_rename** | **i32** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/default_api.md new file mode 100644 index 000000000000..60a218dd56d7 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/default_api.md @@ -0,0 +1,838 @@ +# default_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +****](default_api.md#) | **GET** /any-of | +****](default_api.md#) | **POST** /callback-with-header | +****](default_api.md#) | **GET** /complex-query-param | +**ExamplesTest**](default_api.md#ExamplesTest) | **GET** /examples-test | Test examples +**FormTest**](default_api.md#FormTest) | **POST** /form-test | Test a Form Post +**GetWithBooleanParameter**](default_api.md#GetWithBooleanParameter) | **GET** /get-with-bool | +****](default_api.md#) | **GET** /json-complex-query-param | +****](default_api.md#) | **GET** /mandatory-request-header | +****](default_api.md#) | **GET** /merge-patch-json | +****](default_api.md#) | **GET** /multiget | Get some stuff. +****](default_api.md#) | **GET** /multiple_auth_scheme | +****](default_api.md#) | **GET** /one-of | +****](default_api.md#) | **GET** /override-server | +****](default_api.md#) | **GET** /paramget | Get some stuff with parameters. +****](default_api.md#) | **GET** /readonly_auth_scheme | +****](default_api.md#) | **POST** /register-callback | +****](default_api.md#) | **PUT** /required_octet_stream | +****](default_api.md#) | **GET** /responses_with_headers | +****](default_api.md#) | **GET** /rfc7807 | +**TwoFirstLetterHeaders**](default_api.md#TwoFirstLetterHeaders) | **POST** /operation-two-first-letter-headers | +****](default_api.md#) | **GET** /untyped_property | +****](default_api.md#) | **GET** /uuid | +****](default_api.md#) | **POST** /xml_extra | +****](default_api.md#) | **POST** /xml_other | +****](default_api.md#) | **PUT** /xml_other | +****](default_api.md#) | **POST** /xml | Post an array. It's important we test apostrophes, so include one here. +****](default_api.md#) | **PUT** /xml | +****](default_api.md#) | **GET** /enum_in_path/{path_param} | +****](default_api.md#) | **GET** /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b} | + + +# **** +> models::AnyOfObject (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **any_of** | [**models::AnyOfObject**](models::AnyOfObject.md)| list of any of objects | + +### Return type + +[**models::AnyOfObject**](AnyOfObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (url) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **url** | **String**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **list_of_strings** | [**String**](String.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **ExamplesTest** +> models::AdditionalPropertiesReferencedAnyOfObject ExamplesTest(optional) +Test examples + +Test examples in OpenAPI + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ids** | [**String**](String.md)| A list of IDs to get | + +### Return type + +[**models::AdditionalPropertiesReferencedAnyOfObject**](AdditionalPropertiesReferencedAnyOfObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **FormTest** +> FormTest(optional) +Test a Form Post + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **required_array** | [**String**](String.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **GetWithBooleanParameter** +> GetWithBooleanParameter(iambool) + + +Get with a boolean parameter + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **iambool** | **bool**| Let's check apostrophes get encoded properly! | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **list_of_strings** | [**String**](String.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (x_header) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **x_header** | **String**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::AnotherXmlObject () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::AnotherXmlObject**](anotherXmlObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/merge-patch+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::AnotherXmlObject () +Get some stuff. + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::AnotherXmlObject**](anotherXmlObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/octet-stream, application/xml, text/plain + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (ctx, ) + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +[authScheme](../README.md#authScheme) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::OneOfGet200Response () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::OneOfGet200Response**](_one_of_get_200_response.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::AnotherXmlObject (optional) +Get some stuff with parameters. + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **uuid** | [****](.md)| The stuff to get | + **some_object** | [****](.md)| Some object to pass as query parameter | + **some_list** | [**i32**](i32.md)| Some list to pass as query parameter | + +### Return type + +[**models::AnotherXmlObject**](anotherXmlObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (ctx, ) + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +[authScheme](../README.md#authScheme) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (url) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **url** | **String**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (body) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | **swagger::ByteArray**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/octet-stream + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> String () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +**String** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::ObjectWithArrayOfObjects () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::ObjectWithArrayOfObjects**](ObjectWithArrayOfObjects.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/problem+json, application/problem+xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **TwoFirstLetterHeaders** +> TwoFirstLetterHeaders(optional) + + +Check we don't barf if two boolean parameters have the same first letter + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **x_header_one** | **bool**| | + **x_header_two** | **bool**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **object_untyped_props** | [**ObjectUntypedProps**](ObjectUntypedProps.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> uuid::Uuid () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**uuid::Uuid**](UUID.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **duplicate_xml_object** | [**DuplicateXmlObject**](DuplicateXmlObject.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> models::AnotherXmlObject (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **another_xml_object** | [**AnotherXmlObject**](AnotherXmlObject.md)| | + +### Return type + +[**models::AnotherXmlObject**](anotherXmlObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: text/xml + - **Accept**: text/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **another_xml_array** | [**AnotherXmlArray**](AnotherXmlArray.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) +Post an array. It's important we test apostrophes, so include one here. + + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xml_array** | [**XmlArray**](XmlArray.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (optional) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **xml_object** | [**XmlObject**](XmlObject.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (path_param) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **path_param** | [****](.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> (path_param_a, path_param_b) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **path_param_a** | **String**| | + **path_param_b** | **String**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/repo_api.md b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/repo_api.md new file mode 100644 index 000000000000..26deaf0ae94b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/repo_api.md @@ -0,0 +1,60 @@ +# repo_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**CreateRepo**](repo_api.md#CreateRepo) | **POST** /repos | +**GetRepoInfo**](repo_api.md#GetRepoInfo) | **GET** /repos/{repoId} | + + +# **CreateRepo** +> CreateRepo(object_param) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **object_param** | [**ObjectParam**](ObjectParam.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **GetRepoInfo** +> String GetRepoInfo(repo_id) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **repo_id** | **String**| | + +### Return type + +[**String**](string.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/client_auth.rs new file mode 100644 index 000000000000..db0c36da52fc --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use openapi_v3::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/main.rs new file mode 100644 index 000000000000..d32949fa1a78 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/main.rs @@ -0,0 +1,361 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + +mod server; + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + AnyOfGetResponse, + CallbackWithHeaderPostResponse, + ComplexQueryParamGetResponse, + ExamplesTestResponse, + FormTestResponse, + GetWithBooleanParameterResponse, + JsonComplexQueryParamGetResponse, + MandatoryRequestHeaderGetResponse, + MergePatchJsonGetResponse, + MultigetGetResponse, + MultipleAuthSchemeGetResponse, + OneOfGetResponse, + OverrideServerGetResponse, + ParamgetGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredOctetStreamPutResponse, + ResponsesWithHeadersGetResponse, + Rfc7807GetResponse, + TwoFirstLetterHeadersResponse, + UntypedPropertyGetResponse, + UuidGetResponse, + XmlExtraPostResponse, + XmlOtherPostResponse, + XmlOtherPutResponse, + XmlPostResponse, + XmlPutResponse, + EnumInPathPathParamGetResponse, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, + CreateRepoResponse, + GetRepoInfoResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "AnyOfGet", + "CallbackWithHeaderPost", + "ComplexQueryParamGet", + "ExamplesTest", + "FormTest", + "GetWithBooleanParameter", + "JsonComplexQueryParamGet", + "MandatoryRequestHeaderGet", + "MergePatchJsonGet", + "MultigetGet", + "MultipleAuthSchemeGet", + "OneOfGet", + "OverrideServerGet", + "ParamgetGet", + "ReadonlyAuthSchemeGet", + "RegisterCallbackPost", + "RequiredOctetStreamPut", + "ResponsesWithHeadersGet", + "Rfc7807Get", + "TwoFirstLetterHeaders", + "UntypedPropertyGet", + "UuidGet", + "XmlExtraPost", + "XmlOtherPost", + "XmlOtherPut", + "XmlPost", + "XmlPut", + "MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet", + "CreateRepo", + "GetRepoInfo", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + [ + "test.read", + "test.write", + "additional.test.read", + "additional.test.write", + ].join::<&str>(", ") + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + // We could do HTTPS here, but for simplicity we don't + rt.spawn(server::create("127.0.0.1:8081", false)); + + match matches.value_of("operation") { + Some("AnyOfGet") => { + let result = rt.block_on(client.any_of_get( + Some(&Vec::new()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("CallbackWithHeaderPost") => { + let result = rt.block_on(client.callback_with_header_post( + "url_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("ComplexQueryParamGet") => { + let result = rt.block_on(client.complex_query_param_get( + Some(&Vec::new()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("ExamplesTest") => { + let result = rt.block_on(client.examples_test( + Some(&vec!["foo".to_string()]) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FormTest") => { + let result = rt.block_on(client.form_test( + Some(&Vec::new()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetWithBooleanParameter") => { + let result = rt.block_on(client.get_with_boolean_parameter( + true + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("JsonComplexQueryParamGet") => { + let result = rt.block_on(client.json_complex_query_param_get( + Some(&Vec::new()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MandatoryRequestHeaderGet") => { + let result = rt.block_on(client.mandatory_request_header_get( + "x_header_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MergePatchJsonGet") => { + let result = rt.block_on(client.merge_patch_json_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MultigetGet") => { + let result = rt.block_on(client.multiget_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("MultipleAuthSchemeGet") => { + let result = rt.block_on(client.multiple_auth_scheme_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("OneOfGet") => { + let result = rt.block_on(client.one_of_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("OverrideServerGet") => { + let result = rt.block_on(client.override_server_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("ParamgetGet") => { + let result = rt.block_on(client.paramget_get( + Some(serde_json::from_str::(r#"38400000-8cf0-11bd-b23e-10b96e4ef00d"#).expect("Failed to parse JSON example")), + None, + Some(&Vec::new()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("ReadonlyAuthSchemeGet") => { + let result = rt.block_on(client.readonly_auth_scheme_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("RegisterCallbackPost") => { + let result = rt.block_on(client.register_callback_post( + "url_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("RequiredOctetStreamPut") => { + let result = rt.block_on(client.required_octet_stream_put( + swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("ResponsesWithHeadersGet") => { + let result = rt.block_on(client.responses_with_headers_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Rfc7807Get") => { + let result = rt.block_on(client.rfc7807_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("TwoFirstLetterHeaders") => { + let result = rt.block_on(client.two_first_letter_headers( + Some(true), + Some(true) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("UntypedPropertyGet") => { + let result = rt.block_on(client.untyped_property_get( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("UuidGet") => { + let result = rt.block_on(client.uuid_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("XmlExtraPost") => { + let result = rt.block_on(client.xml_extra_post( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("XmlOtherPost") => { + let result = rt.block_on(client.xml_other_post( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("XmlOtherPut") => { + let result = rt.block_on(client.xml_other_put( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("XmlPost") => { + let result = rt.block_on(client.xml_post( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("XmlPut") => { + let result = rt.block_on(client.xml_put( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("EnumInPathPathParamGet") => { + let result = rt.block_on(client.enum_in_path_path_param_get( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet") => { + let result = rt.block_on(client.multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + "path_param_a_example".to_string(), + "path_param_b_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("CreateRepo") => { + let result = rt.block_on(client.create_repo( + serde_json::from_str::(r#"{"requiredParam":true}"#).expect("Failed to parse JSON example") + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetRepoInfo") => { + let result = rt.block_on(client.get_repo_info( + "repo_id_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/server.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/server.rs new file mode 100644 index 000000000000..fc466245a56d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/server.rs @@ -0,0 +1,125 @@ +//! Main library entry point for openapi_v3 implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use openapi_v3::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + +use openapi_v3::CallbackApi; +use openapi_v3::CallbackCallbackWithHeaderPostResponse; +use openapi_v3::CallbackCallbackPostResponse; +use openapi_v3::client::callbacks::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl CallbackApi for Server where C: Has + Send + Sync +{ + async fn callback_callback_with_header_post( + &self, + callback_request_query_url: String, + information: Option, + context: &C) -> Result + { + info!("callback_callback_with_header_post({:?}) - X-Span-ID: {:?}", information, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn callback_callback_post( + &self, + callback_request_query_url: String, + context: &C) -> Result + { + info!("callback_callback_post() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/main.rs new file mode 100644 index 000000000000..08af24903e54 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for openapi_v3 implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server.rs new file mode 100644 index 000000000000..2849321515c1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server.rs @@ -0,0 +1,423 @@ +//! Main library entry point for openapi_v3 implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use openapi_v3::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + openapi_v3::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use openapi_v3::{ + Api, + AnyOfGetResponse, + CallbackWithHeaderPostResponse, + ComplexQueryParamGetResponse, + ExamplesTestResponse, + FormTestResponse, + GetWithBooleanParameterResponse, + JsonComplexQueryParamGetResponse, + MandatoryRequestHeaderGetResponse, + MergePatchJsonGetResponse, + MultigetGetResponse, + MultipleAuthSchemeGetResponse, + OneOfGetResponse, + OverrideServerGetResponse, + ParamgetGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredOctetStreamPutResponse, + ResponsesWithHeadersGetResponse, + Rfc7807GetResponse, + TwoFirstLetterHeadersResponse, + UntypedPropertyGetResponse, + UuidGetResponse, + XmlExtraPostResponse, + XmlOtherPostResponse, + XmlOtherPutResponse, + XmlPostResponse, + XmlPutResponse, + EnumInPathPathParamGetResponse, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, + CreateRepoResponse, + GetRepoInfoResponse, +}; +use openapi_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn any_of_get( + &self, + any_of: Option<&Vec>, + context: &C) -> Result + { + info!("any_of_get({:?}) - X-Span-ID: {:?}", any_of, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn callback_with_header_post( + &self, + url: String, + context: &C) -> Result + { + info!("callback_with_header_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result + { + info!("complex_query_param_get({:?}) - X-Span-ID: {:?}", list_of_strings, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + context: &C) -> Result + { + info!("examples_test({:?}) - X-Span-ID: {:?}", ids, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Test a Form Post + async fn form_test( + &self, + required_array: Option<&Vec>, + context: &C) -> Result + { + info!("form_test({:?}) - X-Span-ID: {:?}", required_array, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn get_with_boolean_parameter( + &self, + iambool: bool, + context: &C) -> Result + { + info!("get_with_boolean_parameter({}) - X-Span-ID: {:?}", iambool, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result + { + info!("json_complex_query_param_get({:?}) - X-Span-ID: {:?}", list_of_strings, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn mandatory_request_header_get( + &self, + x_header: String, + context: &C) -> Result + { + info!("mandatory_request_header_get(\"{}\") - X-Span-ID: {:?}", x_header, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn merge_patch_json_get( + &self, + context: &C) -> Result + { + info!("merge_patch_json_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Get some stuff. + async fn multiget_get( + &self, + context: &C) -> Result + { + info!("multiget_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn multiple_auth_scheme_get( + &self, + context: &C) -> Result + { + info!("multiple_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn one_of_get( + &self, + context: &C) -> Result + { + info!("one_of_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn override_server_get( + &self, + context: &C) -> Result + { + info!("override_server_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Get some stuff with parameters. + async fn paramget_get( + &self, + uuid: Option, + some_object: Option, + some_list: Option<&Vec>, + context: &C) -> Result + { + info!("paramget_get({:?}, {:?}, {:?}) - X-Span-ID: {:?}", uuid, some_object, some_list, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn readonly_auth_scheme_get( + &self, + context: &C) -> Result + { + info!("readonly_auth_scheme_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn register_callback_post( + &self, + url: String, + context: &C) -> Result + { + info!("register_callback_post(\"{}\") - X-Span-ID: {:?}", url, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn required_octet_stream_put( + &self, + body: swagger::ByteArray, + context: &C) -> Result + { + info!("required_octet_stream_put({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn responses_with_headers_get( + &self, + context: &C) -> Result + { + info!("responses_with_headers_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn rfc7807_get( + &self, + context: &C) -> Result + { + info!("rfc7807_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn two_first_letter_headers( + &self, + x_header_one: Option, + x_header_two: Option, + context: &C) -> Result + { + info!("two_first_letter_headers({:?}, {:?}) - X-Span-ID: {:?}", x_header_one, x_header_two, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn untyped_property_get( + &self, + object_untyped_props: Option, + context: &C) -> Result + { + info!("untyped_property_get({:?}) - X-Span-ID: {:?}", object_untyped_props, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn uuid_get( + &self, + context: &C) -> Result + { + info!("uuid_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn xml_extra_post( + &self, + duplicate_xml_object: Option, + context: &C) -> Result + { + info!("xml_extra_post({:?}) - X-Span-ID: {:?}", duplicate_xml_object, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn xml_other_post( + &self, + another_xml_object: Option, + context: &C) -> Result + { + info!("xml_other_post({:?}) - X-Span-ID: {:?}", another_xml_object, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn xml_other_put( + &self, + another_xml_array: Option, + context: &C) -> Result + { + info!("xml_other_put({:?}) - X-Span-ID: {:?}", another_xml_array, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Post an array. It's important we test apostrophes, so include one here. + async fn xml_post( + &self, + xml_array: Option, + context: &C) -> Result + { + info!("xml_post({:?}) - X-Span-ID: {:?}", xml_array, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn xml_put( + &self, + xml_object: Option, + context: &C) -> Result + { + info!("xml_put({:?}) - X-Span-ID: {:?}", xml_object, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn enum_in_path_path_param_get( + &self, + path_param: models::StringEnum, + context: &C) -> Result + { + info!("enum_in_path_path_param_get({:?}) - X-Span-ID: {:?}", path_param, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + &self, + path_param_a: String, + path_param_b: String, + context: &C) -> Result + { + info!("multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get(\"{}\", \"{}\") - X-Span-ID: {:?}", path_param_a, path_param_b, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn create_repo( + &self, + object_param: models::ObjectParam, + context: &C) -> Result + { + info!("create_repo({:?}) - X-Span-ID: {:?}", object_param, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn get_repo_info( + &self, + repo_id: String, + context: &C) -> Result + { + info!("get_repo_info(\"{}\") - X-Span-ID: {:?}", repo_id, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server_auth.rs new file mode 100644 index 000000000000..1c9b18394f21 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server_auth.rs @@ -0,0 +1,132 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use openapi_v3::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + [ + "test.read", + "test.write", + "additional.test.read", + "additional.test.write", + ].join::<&str>(", ") + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/callbacks.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/callbacks.rs new file mode 100644 index 000000000000..508c7ac05651 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/callbacks.rs @@ -0,0 +1,295 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::CallbackApi as Api; +use crate::CallbackCallbackWithHeaderPostResponse; +use crate::CallbackCallbackPostResponse; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/(?P.*)/callback$", + r"^/(?P.*)/callback-with-header$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_REQUEST_QUERY_URL_CALLBACK: usize = 0; + lazy_static! { + pub static ref REGEX_REQUEST_QUERY_URL_CALLBACK: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/(?P.*)/callback$") + .expect("Unable to create regex for REQUEST_QUERY_URL_CALLBACK"); + } + pub(crate) static ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER: usize = 1; + lazy_static! { + pub static ref REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/(?P.*)/callback-with-header$") + .expect("Unable to create regex for REQUEST_QUERY_URL_CALLBACK_WITH_HEADER"); + } +} + + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // CallbackCallbackWithHeaderPost - POST /{$request.query.url}/callback-with-header + hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE REQUEST_QUERY_URL_CALLBACK_WITH_HEADER in set but failed match against \"{}\"", path, paths::REGEX_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER.as_str()) + ); + + let callback_request_query_url = path_params["request_query_url"].to_string(); + // Header parameters + let param_information = headers.get(HeaderName::from_static("information")); + + let param_information = match param_information { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header Information - {err}"))) + .expect("Unable to create Bad Request response for invalid header Information")); + + }, + }, + None => { + None + } + }; + + let result = api_impl.callback_callback_with_header_post( + callback_request_query_url, + param_information, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + CallbackCallbackWithHeaderPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // CallbackCallbackPost - POST /{$request.query.url}/callback + hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_REQUEST_QUERY_URL_CALLBACK + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE REQUEST_QUERY_URL_CALLBACK in set but failed match against \"{}\"", path, paths::REGEX_REQUEST_QUERY_URL_CALLBACK.as_str()) + ); + + let callback_request_query_url = path_params["request_query_url"].to_string(); + let result = api_impl.callback_callback_post( + callback_request_query_url, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + CallbackCallbackPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => method_not_allowed(), + _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // CallbackCallbackWithHeaderPost - POST /{$request.query.url}/callback-with-header + hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => Some("CallbackCallbackWithHeaderPost"), + // CallbackCallbackPost - POST /{$request.query.url}/callback + hyper::Method::POST if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => Some("CallbackCallbackPost"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/mod.rs new file mode 100644 index 000000000000..05167aaef685 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/mod.rs @@ -0,0 +1,3158 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + AnyOfGetResponse, + CallbackWithHeaderPostResponse, + ComplexQueryParamGetResponse, + ExamplesTestResponse, + FormTestResponse, + GetWithBooleanParameterResponse, + JsonComplexQueryParamGetResponse, + MandatoryRequestHeaderGetResponse, + MergePatchJsonGetResponse, + MultigetGetResponse, + MultipleAuthSchemeGetResponse, + OneOfGetResponse, + OverrideServerGetResponse, + ParamgetGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredOctetStreamPutResponse, + ResponsesWithHeadersGetResponse, + Rfc7807GetResponse, + TwoFirstLetterHeadersResponse, + UntypedPropertyGetResponse, + UuidGetResponse, + XmlExtraPostResponse, + XmlOtherPostResponse, + XmlOtherPutResponse, + XmlPostResponse, + XmlPutResponse, + EnumInPathPathParamGetResponse, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, + CreateRepoResponse, + GetRepoInfoResponse + }; + +pub mod callbacks; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Has> + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn any_of_get( + &self, + param_any_of: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/any-of", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_any_of) = param_any_of { + query_string.append_pair("any-of", + ¶m_any_of.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(AnyOfGetResponse::Success + (body) + ) + } + 201 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(AnyOfGetResponse::AlternateSuccess + (body) + ) + } + 202 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(AnyOfGetResponse::AnyOfSuccess + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn callback_with_header_post( + &self, + param_url: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/callback-with-header", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("url", + ¶m_url); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + CallbackWithHeaderPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn complex_query_param_get( + &self, + param_list_of_strings: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/complex-query-param", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_list_of_strings) = param_list_of_strings { + query_string.append_pair("list-of-strings", + ¶m_list_of_strings.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + ComplexQueryParamGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn examples_test( + &self, + param_ids: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/examples-test", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_ids) = param_ids { + query_string.append_pair("ids", + ¶m_ids.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(ExamplesTestResponse::OK + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn form_test( + &self, + param_required_array: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/form-test", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes form body + let mut params = vec![]; + if let Some(param_required_array) = param_required_array { + // style=form,explode=true + for param_required_array in param_required_array { + #[allow(clippy::uninlined_format_args)] + params.push(("requiredArray", + format!("{:?}", param_required_array) + )); + } + } + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "application/x-www-form-urlencoded"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + FormTestResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_with_boolean_parameter( + &self, + param_iambool: bool, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/get-with-bool", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("iambool", + ¶m_iambool.to_string()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + GetWithBooleanParameterResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn json_complex_query_param_get( + &self, + param_list_of_strings: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/json-complex-query-param", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_list_of_strings) = param_list_of_strings { + query_string.append_pair("list-of-strings", + &match serde_json::to_string(¶m_list_of_strings) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize list_of_strings to string: {e}"))), + }); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + JsonComplexQueryParamGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn mandatory_request_header_get( + &self, + param_x_header: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/mandatory-request-header", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + // Header parameters + request.headers_mut().append( + HeaderName::from_static("x-header"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_x_header.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header x_header - {e}"))); + }, + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + MandatoryRequestHeaderGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn merge_patch_json_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/merge-patch-json", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MergePatchJsonGetResponse::Merge + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn multiget_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multiget", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MultigetGetResponse::JSONRsp + (body) + ) + } + 201 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MultigetGetResponse::XMLRsp + (body) + ) + } + 202 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = swagger::ByteArray(body.to_vec()); + + + Ok(MultigetGetResponse::OctetRsp + (body) + ) + } + 203 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = body.to_string(); + + + Ok(MultigetGetResponse::StringRsp + (body) + ) + } + 204 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MultigetGetResponse::DuplicateResponseLongText + (body) + ) + } + 205 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MultigetGetResponse::DuplicateResponseLongText_2 + (body) + ) + } + 206 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(MultigetGetResponse::DuplicateResponseLongText_3 + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn multiple_auth_scheme_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multiple_auth_scheme", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn one_of_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/one-of", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(OneOfGetResponse::Success + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn override_server_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/override/override-server", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + OverrideServerGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn paramget_get( + &self, + param_uuid: Option, + param_some_object: Option, + param_some_list: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/paramget", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_uuid) = param_uuid { + query_string.append_pair("uuid", + ¶m_uuid.to_string()); + } + if let Some(param_some_object) = param_some_object { + query_string.append_pair("someObject", + ¶m_some_object.to_string()); + } + if let Some(param_some_list) = param_some_list { + query_string.append_pair("someList", + ¶m_some_list.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(ParamgetGetResponse::JSONRsp + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn readonly_auth_scheme_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/readonly_auth_scheme", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn register_callback_post( + &self, + param_url: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/register-callback", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("url", + ¶m_url); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + RegisterCallbackPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn required_octet_stream_put( + &self, + param_body: swagger::ByteArray, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/required_octet_stream", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = param_body.0; + *request.body_mut() = Body::from(body); + + let header = "application/octet-stream"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + RequiredOctetStreamPutResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn responses_with_headers_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/responses_with_headers", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let response_success_info = match response.headers().get(HeaderName::from_static("success-info")) { + Some(response_success_info) => { + let response_success_info = response_success_info.clone(); + let response_success_info = match TryInto::>::try_into(response_success_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Success-Info for response 200 - {e}"))); + }, + }; + response_success_info.0 + }, + None => return Err(ApiError(String::from("Required response header Success-Info for response 200 was not found."))), + }; + + let response_bool_header = match response.headers().get(HeaderName::from_static("bool-header")) { + Some(response_bool_header) => { + let response_bool_header = response_bool_header.clone(); + let response_bool_header = match TryInto::>::try_into(response_bool_header) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Bool-Header for response 200 - {e}"))); + }, + }; + Some(response_bool_header.0) + }, + None => None, + }; + + let response_object_header = match response.headers().get(HeaderName::from_static("object-header")) { + Some(response_object_header) => { + let response_object_header = response_object_header.clone(); + let response_object_header = match TryInto::>::try_into(response_object_header) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Object-Header for response 200 - {e}"))); + }, + }; + Some(response_object_header.0) + }, + None => None, + }; + + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(ResponsesWithHeadersGetResponse::Success + { + body, + success_info: response_success_info, + bool_header: response_bool_header, + object_header: response_object_header, + } + ) + } + 412 => { + let response_further_info = match response.headers().get(HeaderName::from_static("further-info")) { + Some(response_further_info) => { + let response_further_info = response_further_info.clone(); + let response_further_info = match TryInto::>::try_into(response_further_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Further-Info for response 412 - {e}"))); + }, + }; + Some(response_further_info.0) + }, + None => None, + }; + + let response_failure_info = match response.headers().get(HeaderName::from_static("failure-info")) { + Some(response_failure_info) => { + let response_failure_info = response_failure_info.clone(); + let response_failure_info = match TryInto::>::try_into(response_failure_info) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header Failure-Info for response 412 - {e}"))); + }, + }; + Some(response_failure_info.0) + }, + None => None, + }; + + Ok( + ResponsesWithHeadersGetResponse::PreconditionFailed + { + further_info: response_further_info, + failure_info: response_failure_info, + } + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn rfc7807_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/rfc7807", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(Rfc7807GetResponse::OK + (body) + ) + } + 404 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(Rfc7807GetResponse::NotFound + (body) + ) + } + 406 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(Rfc7807GetResponse::NotAcceptable + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn two_first_letter_headers( + &self, + param_x_header_one: Option, + param_x_header_two: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/operation-two-first-letter-headers", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + // Header parameters + #[allow(clippy::single_match)] + match param_x_header_one { + Some(param_x_header_one) => { + request.headers_mut().append( + HeaderName::from_static("x-header-one"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_x_header_one.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header x_header_one - {e}"))); + }, + }); + }, + None => {} + } + + #[allow(clippy::single_match)] + match param_x_header_two { + Some(param_x_header_two) => { + request.headers_mut().append( + HeaderName::from_static("x-header-two"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_x_header_two.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header x_header_two - {e}"))); + }, + }); + }, + None => {} + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + TwoFirstLetterHeadersResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn untyped_property_get( + &self, + param_object_untyped_props: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/untyped_property", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_object_untyped_props) = param_object_untyped_props { + let body = serde_json::to_string(¶m_object_untyped_props).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + } + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn uuid_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/uuid", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(UuidGetResponse::DuplicateResponseLongText + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn xml_extra_post( + &self, + param_duplicate_xml_object: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/xml_extra", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_duplicate_xml_object) = param_duplicate_xml_object { + let body = param_duplicate_xml_object.as_xml(); + *request.body_mut() = Body::from(body); + } + + let header = "application/xml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + XmlExtraPostResponse::OK + ) + } + 400 => { + Ok( + XmlExtraPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn xml_other_post( + &self, + param_another_xml_object: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/xml_other", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_another_xml_object) = param_another_xml_object { + let body = param_another_xml_object.as_xml(); + *request.body_mut() = Body::from(body); + } + + let header = "text/xml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(XmlOtherPostResponse::OK + (body) + ) + } + 400 => { + Ok( + XmlOtherPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn xml_other_put( + &self, + param_another_xml_array: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/xml_other", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_another_xml_array) = param_another_xml_array { + let body = param_another_xml_array.as_xml(); + *request.body_mut() = Body::from(body); + } + + let header = "application/xml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + XmlOtherPutResponse::OK + ) + } + 400 => { + Ok( + XmlOtherPutResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn xml_post( + &self, + param_xml_array: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/xml", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_xml_array) = param_xml_array { + let body = param_xml_array.as_xml(); + *request.body_mut() = Body::from(body); + } + + let header = "application/xml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + XmlPostResponse::OK + ) + } + 400 => { + Ok( + XmlPostResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn xml_put( + &self, + param_xml_object: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/xml", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_xml_object) = param_xml_object { + let body = param_xml_object.as_xml(); + *request.body_mut() = Body::from(body); + } + + let header = "application/xml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + XmlPutResponse::OK + ) + } + 400 => { + Ok( + XmlPutResponse::BadRequest + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn enum_in_path_path_param_get( + &self, + param_path_param: models::StringEnum, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/enum_in_path/{path_param}", + self.base_path + ,path_param=utf8_percent_encode(¶m_path_param.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + EnumInPathPathParamGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + &self, + param_path_param_a: String, + param_path_param_b: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b}", + self.base_path + ,path_param_a=utf8_percent_encode(¶m_path_param_a.to_string(), ID_ENCODE_SET) + ,path_param_b=utf8_percent_encode(¶m_path_param_b.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn create_repo( + &self, + param_object_param: models::ObjectParam, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/repos", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_object_param).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + CreateRepoResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_repo_info( + &self, + param_repo_id: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/repos/{repo_id}", + self.base_path + ,repo_id=utf8_percent_encode(¶m_repo_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(GetRepoInfoResponse::OK + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/context.rs new file mode 100644 index 000000000000..2b3485f7bbe8 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/context.rs @@ -0,0 +1,152 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/lib.rs new file mode 100644 index 000000000000..f4952741578f --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/lib.rs @@ -0,0 +1,1070 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "1.0.7"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum AnyOfGetResponse { + /// Success + Success + (models::AnyOfObject) + , + /// AlternateSuccess + AlternateSuccess + (models::Model12345AnyOfObject) + , + /// AnyOfSuccess + AnyOfSuccess + (models::AnyOfGet202Response) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CallbackWithHeaderPostResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum ComplexQueryParamGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum ExamplesTestResponse { + /// OK + OK + (models::AdditionalPropertiesReferencedAnyOfObject) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FormTestResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum GetWithBooleanParameterResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum JsonComplexQueryParamGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MandatoryRequestHeaderGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MergePatchJsonGetResponse { + /// merge-patch+json-encoded response + Merge + (models::AnotherXmlObject) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum MultigetGetResponse { + /// JSON rsp + JSONRsp + (models::AnotherXmlObject) + , + /// XML rsp + XMLRsp + (models::MultigetGet201Response) + , + /// octet rsp + OctetRsp + (swagger::ByteArray) + , + /// string rsp + StringRsp + (String) + , + /// Duplicate Response long text. One. + DuplicateResponseLongText + (models::AnotherXmlObject) + , + /// Duplicate Response long text. Two. + DuplicateResponseLongText_2 + (models::AnotherXmlObject) + , + /// Duplicate Response long text. Three. + DuplicateResponseLongText_3 + (models::AnotherXmlObject) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MultipleAuthSchemeGetResponse { + /// Check that limiting to multiple required auth schemes works + CheckThatLimitingToMultipleRequiredAuthSchemesWorks +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum OneOfGetResponse { + /// Success + Success + (models::OneOfGet200Response) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum OverrideServerGetResponse { + /// Success. + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum ParamgetGetResponse { + /// JSON rsp + JSONRsp + (models::AnotherXmlObject) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum ReadonlyAuthSchemeGetResponse { + /// Check that limiting to a single required auth scheme works + CheckThatLimitingToASingleRequiredAuthSchemeWorks +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum RegisterCallbackPostResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum RequiredOctetStreamPutResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum ResponsesWithHeadersGetResponse { + /// Success + Success + { + body: String, + success_info: + String + , + bool_header: + Option< + bool + > + , + object_header: + Option< + models::ObjectHeader + > + } + , + /// Precondition Failed + PreconditionFailed + { + further_info: + Option< + String + > + , + failure_info: + Option< + String + > + } +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum Rfc7807GetResponse { + /// OK + OK + (models::ObjectWithArrayOfObjects) + , + /// NotFound + NotFound + (models::ObjectWithArrayOfObjects) + , + /// NotAcceptable + NotAcceptable + (models::ObjectWithArrayOfObjects) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TwoFirstLetterHeadersResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum UntypedPropertyGetResponse { + /// Check that untyped properties works + CheckThatUntypedPropertiesWorks +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum UuidGetResponse { + /// Duplicate Response long text. One. + DuplicateResponseLongText + (uuid::Uuid) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum XmlExtraPostResponse { + /// OK + OK + , + /// Bad Request + BadRequest +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum XmlOtherPostResponse { + /// OK + OK + (models::AnotherXmlObject) + , + /// Bad Request + BadRequest +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum XmlOtherPutResponse { + /// OK + OK + , + /// Bad Request + BadRequest +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum XmlPostResponse { + /// OK + OK + , + /// Bad Request + BadRequest +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum XmlPutResponse { + /// OK + OK + , + /// Bad Request + BadRequest +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum EnumInPathPathParamGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CreateRepoResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum GetRepoInfoResponse { + /// OK + OK + (String) +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn any_of_get( + &self, + any_of: Option<&Vec>, + context: &C) -> Result; + + async fn callback_with_header_post( + &self, + url: String, + context: &C) -> Result; + + async fn complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result; + + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + context: &C) -> Result; + + /// Test a Form Post + async fn form_test( + &self, + required_array: Option<&Vec>, + context: &C) -> Result; + + async fn get_with_boolean_parameter( + &self, + iambool: bool, + context: &C) -> Result; + + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + context: &C) -> Result; + + async fn mandatory_request_header_get( + &self, + x_header: String, + context: &C) -> Result; + + async fn merge_patch_json_get( + &self, + context: &C) -> Result; + + /// Get some stuff. + async fn multiget_get( + &self, + context: &C) -> Result; + + async fn multiple_auth_scheme_get( + &self, + context: &C) -> Result; + + async fn one_of_get( + &self, + context: &C) -> Result; + + async fn override_server_get( + &self, + context: &C) -> Result; + + /// Get some stuff with parameters. + async fn paramget_get( + &self, + uuid: Option, + some_object: Option, + some_list: Option<&Vec>, + context: &C) -> Result; + + async fn readonly_auth_scheme_get( + &self, + context: &C) -> Result; + + async fn register_callback_post( + &self, + url: String, + context: &C) -> Result; + + async fn required_octet_stream_put( + &self, + body: swagger::ByteArray, + context: &C) -> Result; + + async fn responses_with_headers_get( + &self, + context: &C) -> Result; + + async fn rfc7807_get( + &self, + context: &C) -> Result; + + async fn two_first_letter_headers( + &self, + x_header_one: Option, + x_header_two: Option, + context: &C) -> Result; + + async fn untyped_property_get( + &self, + object_untyped_props: Option, + context: &C) -> Result; + + async fn uuid_get( + &self, + context: &C) -> Result; + + async fn xml_extra_post( + &self, + duplicate_xml_object: Option, + context: &C) -> Result; + + async fn xml_other_post( + &self, + another_xml_object: Option, + context: &C) -> Result; + + async fn xml_other_put( + &self, + another_xml_array: Option, + context: &C) -> Result; + + /// Post an array. It's important we test apostrophes, so include one here. + async fn xml_post( + &self, + xml_array: Option, + context: &C) -> Result; + + async fn xml_put( + &self, + xml_object: Option, + context: &C) -> Result; + + async fn enum_in_path_path_param_get( + &self, + path_param: models::StringEnum, + context: &C) -> Result; + + async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + &self, + path_param_a: String, + path_param_b: String, + context: &C) -> Result; + + async fn create_repo( + &self, + object_param: models::ObjectParam, + context: &C) -> Result; + + async fn get_repo_info( + &self, + repo_id: String, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn any_of_get( + &self, + any_of: Option<&Vec>, + ) -> Result; + + async fn callback_with_header_post( + &self, + url: String, + ) -> Result; + + async fn complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + ) -> Result; + + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + ) -> Result; + + /// Test a Form Post + async fn form_test( + &self, + required_array: Option<&Vec>, + ) -> Result; + + async fn get_with_boolean_parameter( + &self, + iambool: bool, + ) -> Result; + + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + ) -> Result; + + async fn mandatory_request_header_get( + &self, + x_header: String, + ) -> Result; + + async fn merge_patch_json_get( + &self, + ) -> Result; + + /// Get some stuff. + async fn multiget_get( + &self, + ) -> Result; + + async fn multiple_auth_scheme_get( + &self, + ) -> Result; + + async fn one_of_get( + &self, + ) -> Result; + + async fn override_server_get( + &self, + ) -> Result; + + /// Get some stuff with parameters. + async fn paramget_get( + &self, + uuid: Option, + some_object: Option, + some_list: Option<&Vec>, + ) -> Result; + + async fn readonly_auth_scheme_get( + &self, + ) -> Result; + + async fn register_callback_post( + &self, + url: String, + ) -> Result; + + async fn required_octet_stream_put( + &self, + body: swagger::ByteArray, + ) -> Result; + + async fn responses_with_headers_get( + &self, + ) -> Result; + + async fn rfc7807_get( + &self, + ) -> Result; + + async fn two_first_letter_headers( + &self, + x_header_one: Option, + x_header_two: Option, + ) -> Result; + + async fn untyped_property_get( + &self, + object_untyped_props: Option, + ) -> Result; + + async fn uuid_get( + &self, + ) -> Result; + + async fn xml_extra_post( + &self, + duplicate_xml_object: Option, + ) -> Result; + + async fn xml_other_post( + &self, + another_xml_object: Option, + ) -> Result; + + async fn xml_other_put( + &self, + another_xml_array: Option, + ) -> Result; + + /// Post an array. It's important we test apostrophes, so include one here. + async fn xml_post( + &self, + xml_array: Option, + ) -> Result; + + async fn xml_put( + &self, + xml_object: Option, + ) -> Result; + + async fn enum_in_path_path_param_get( + &self, + path_param: models::StringEnum, + ) -> Result; + + async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + &self, + path_param_a: String, + path_param_b: String, + ) -> Result; + + async fn create_repo( + &self, + object_param: models::ObjectParam, + ) -> Result; + + async fn get_repo_info( + &self, + repo_id: String, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn any_of_get( + &self, + any_of: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().any_of_get(any_of, &context).await + } + + async fn callback_with_header_post( + &self, + url: String, + ) -> Result + { + let context = self.context().clone(); + self.api().callback_with_header_post(url, &context).await + } + + async fn complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().complex_query_param_get(list_of_strings, &context).await + } + + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().examples_test(ids, &context).await + } + + /// Test a Form Post + async fn form_test( + &self, + required_array: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().form_test(required_array, &context).await + } + + async fn get_with_boolean_parameter( + &self, + iambool: bool, + ) -> Result + { + let context = self.context().clone(); + self.api().get_with_boolean_parameter(iambool, &context).await + } + + async fn json_complex_query_param_get( + &self, + list_of_strings: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().json_complex_query_param_get(list_of_strings, &context).await + } + + async fn mandatory_request_header_get( + &self, + x_header: String, + ) -> Result + { + let context = self.context().clone(); + self.api().mandatory_request_header_get(x_header, &context).await + } + + async fn merge_patch_json_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().merge_patch_json_get(&context).await + } + + /// Get some stuff. + async fn multiget_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().multiget_get(&context).await + } + + async fn multiple_auth_scheme_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().multiple_auth_scheme_get(&context).await + } + + async fn one_of_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().one_of_get(&context).await + } + + async fn override_server_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().override_server_get(&context).await + } + + /// Get some stuff with parameters. + async fn paramget_get( + &self, + uuid: Option, + some_object: Option, + some_list: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().paramget_get(uuid, some_object, some_list, &context).await + } + + async fn readonly_auth_scheme_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().readonly_auth_scheme_get(&context).await + } + + async fn register_callback_post( + &self, + url: String, + ) -> Result + { + let context = self.context().clone(); + self.api().register_callback_post(url, &context).await + } + + async fn required_octet_stream_put( + &self, + body: swagger::ByteArray, + ) -> Result + { + let context = self.context().clone(); + self.api().required_octet_stream_put(body, &context).await + } + + async fn responses_with_headers_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().responses_with_headers_get(&context).await + } + + async fn rfc7807_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().rfc7807_get(&context).await + } + + async fn two_first_letter_headers( + &self, + x_header_one: Option, + x_header_two: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().two_first_letter_headers(x_header_one, x_header_two, &context).await + } + + async fn untyped_property_get( + &self, + object_untyped_props: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().untyped_property_get(object_untyped_props, &context).await + } + + async fn uuid_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().uuid_get(&context).await + } + + async fn xml_extra_post( + &self, + duplicate_xml_object: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().xml_extra_post(duplicate_xml_object, &context).await + } + + async fn xml_other_post( + &self, + another_xml_object: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().xml_other_post(another_xml_object, &context).await + } + + async fn xml_other_put( + &self, + another_xml_array: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().xml_other_put(another_xml_array, &context).await + } + + /// Post an array. It's important we test apostrophes, so include one here. + async fn xml_post( + &self, + xml_array: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().xml_post(xml_array, &context).await + } + + async fn xml_put( + &self, + xml_object: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().xml_put(xml_object, &context).await + } + + async fn enum_in_path_path_param_get( + &self, + path_param: models::StringEnum, + ) -> Result + { + let context = self.context().clone(); + self.api().enum_in_path_path_param_get(path_param, &context).await + } + + async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + &self, + path_param_a: String, + path_param_b: String, + ) -> Result + { + let context = self.context().clone(); + self.api().multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get(path_param_a, path_param_b, &context).await + } + + async fn create_repo( + &self, + object_param: models::ObjectParam, + ) -> Result + { + let context = self.context().clone(); + self.api().create_repo(object_param, &context).await + } + + async fn get_repo_info( + &self, + repo_id: String, + ) -> Result + { + let context = self.context().clone(); + self.api().get_repo_info(repo_id, &context).await + } + +} + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CallbackCallbackWithHeaderPostResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CallbackCallbackPostResponse { + /// OK + OK +} + + +/// Callback API +#[async_trait] +pub trait CallbackApi { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn callback_callback_with_header_post( + &self, + callback_request_query_url: String, + information: Option, + context: &C) -> Result; + + async fn callback_callback_post( + &self, + callback_request_query_url: String, + context: &C) -> Result; + +} + +/// Callback API without a `Context` +#[async_trait] +pub trait CallbackApiNoContext { + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn callback_callback_with_header_post( + &self, + callback_request_query_url: String, + information: Option, + ) -> Result; + + async fn callback_callback_post( + &self, + callback_request_query_url: String, + ) -> Result; + +} + +pub trait CallbackContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn callback_callback_with_header_post( + &self, + callback_request_query_url: String, + information: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().callback_callback_with_header_post( + callback_request_query_url, + information, + &context).await + } + + async fn callback_callback_post( + &self, + callback_request_query_url: String, + ) -> Result + { + let context = self.context().clone(); + self.api().callback_callback_post( + callback_request_query_url, + &context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(any(feature = "client", feature = "server"))] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/models.rs new file mode 100644 index 000000000000..d93d890a243a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/models.rs @@ -0,0 +1,5703 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; + +/// Check that an object with only additional properties that references another object (e.g. an anyOf object) isn't treated as freeForm +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AdditionalPropertiesReferencedAnyOfObject(std::collections::HashMap); + +impl std::convert::From> for AdditionalPropertiesReferencedAnyOfObject { + fn from(x: std::collections::HashMap) -> Self { + AdditionalPropertiesReferencedAnyOfObject(x) + } +} + +impl std::convert::From for std::collections::HashMap { + fn from(x: AdditionalPropertiesReferencedAnyOfObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for AdditionalPropertiesReferencedAnyOfObject { + type Target = std::collections::HashMap; + fn deref(&self) -> &std::collections::HashMap { + &self.0 + } +} + +impl std::ops::DerefMut for AdditionalPropertiesReferencedAnyOfObject { + fn deref_mut(&mut self) -> &mut std::collections::HashMap { + &mut self.0 + } +} + +/// Converts the AdditionalPropertiesReferencedAnyOfObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AdditionalPropertiesReferencedAnyOfObject { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesReferencedAnyOfObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AdditionalPropertiesReferencedAnyOfObject { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AdditionalPropertiesReferencedAnyOfObject is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AdditionalPropertiesReferencedAnyOfObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AdditionalPropertiesReferencedAnyOfObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesReferencedAnyOfObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AdditionalPropertiesReferencedAnyOfObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AdditionalPropertiesWithList(std::collections::HashMap>); + +impl std::convert::From>> for AdditionalPropertiesWithList { + fn from(x: std::collections::HashMap>) -> Self { + AdditionalPropertiesWithList(x) + } +} + +impl std::convert::From for std::collections::HashMap> { + fn from(x: AdditionalPropertiesWithList) -> Self { + x.0 + } +} + +impl std::ops::Deref for AdditionalPropertiesWithList { + type Target = std::collections::HashMap>; + fn deref(&self) -> &std::collections::HashMap> { + &self.0 + } +} + +impl std::ops::DerefMut for AdditionalPropertiesWithList { + fn deref_mut(&mut self) -> &mut std::collections::HashMap> { + &mut self.0 + } +} + +/// Converts the AdditionalPropertiesWithList value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AdditionalPropertiesWithList { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesWithList value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AdditionalPropertiesWithList { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AdditionalPropertiesWithList is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AdditionalPropertiesWithList - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AdditionalPropertiesWithList - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesWithList - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AdditionalPropertiesWithList { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AdditionalPropertiesWithNullable { + #[serde(rename = "nullableString")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_string: Option>, + + #[serde(rename = "nullableMap")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_map: Option>>, + +} + + +impl AdditionalPropertiesWithNullable { + #[allow(clippy::new_without_default)] + pub fn new() -> AdditionalPropertiesWithNullable { + AdditionalPropertiesWithNullable { + nullable_string: None, + nullable_map: None, + } + } +} + +/// Converts the AdditionalPropertiesWithNullable value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AdditionalPropertiesWithNullable { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.nullable_string.as_ref().map(|nullable_string| { + [ + "nullableString".to_string(), + nullable_string.as_ref().map_or("null".to_string(), |x| x.to_string()), + ].join(",") + }), + // Skipping map nullableMap in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesWithNullable value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AdditionalPropertiesWithNullable { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub nullable_string: Vec>, + pub nullable_map: Vec>>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing AdditionalPropertiesWithNullable".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "nullableString" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in AdditionalPropertiesWithNullable".to_string()), + "nullableMap" => return std::result::Result::Err("Parsing a container in this style is not supported in AdditionalPropertiesWithNullable".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing AdditionalPropertiesWithNullable".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(AdditionalPropertiesWithNullable { + nullable_string: std::result::Result::Err("Nullable types not supported in AdditionalPropertiesWithNullable".to_string())?, + nullable_map: intermediate_rep.nullable_map.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AdditionalPropertiesWithNullable - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AdditionalPropertiesWithNullable - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesWithNullable - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AdditionalPropertiesWithNullable { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +// Utility function for wrapping list elements when serializing xml +#[allow(non_snake_case)] +fn wrap_in_snake_another_xml_inner(item: &Vec, serializer: S) -> std::result::Result +where + S: serde::ser::Serializer, +{ + serde_xml_rs::wrap_primitives(item, serializer, "snake_another_xml_inner") +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnotherXmlArray( + #[serde(serialize_with = "wrap_in_snake_another_xml_inner")] + Vec +); + +impl std::convert::From> for AnotherXmlArray { + fn from(x: Vec) -> Self { + AnotherXmlArray(x) + } +} + +impl std::convert::From for Vec { + fn from(x: AnotherXmlArray) -> Self { + x.0 + } +} + +impl std::iter::FromIterator for AnotherXmlArray { + fn from_iter>(u: U) -> Self { + AnotherXmlArray(Vec::::from_iter(u)) + } +} + +impl std::iter::IntoIterator for AnotherXmlArray { + type Item = String; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a AnotherXmlArray { + type Item = &'a String; + type IntoIter = std::slice::Iter<'a, String>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a mut AnotherXmlArray { + type Item = &'a mut String; + type IntoIter = std::slice::IterMut<'a, String>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() + } +} + +impl std::ops::Deref for AnotherXmlArray { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for AnotherXmlArray { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Converts the AnotherXmlArray value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AnotherXmlArray { + fn to_string(&self) -> String { + self.iter().map(|x| x.to_string()).collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnotherXmlArray value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AnotherXmlArray { + type Err = ::Err; + + fn from_str(s: &str) -> std::result::Result { + let mut items = vec![]; + for item in s.split(',') + { + items.push(item.parse()?); + } + std::result::Result::Ok(AnotherXmlArray(items)) + } +} + + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnotherXmlArray - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnotherXmlArray - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnotherXmlArray - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnotherXmlArray { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "snake_another_xml_inner")] +pub struct AnotherXmlInner(String); + +impl std::convert::From for AnotherXmlInner { + fn from(x: String) -> Self { + AnotherXmlInner(x) + } +} + +impl std::convert::From for String { + fn from(x: AnotherXmlInner) -> Self { + x.0 + } +} + +impl std::ops::Deref for AnotherXmlInner { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for AnotherXmlInner { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for AnotherXmlInner { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for AnotherXmlInner { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(AnotherXmlInner(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnotherXmlInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnotherXmlInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnotherXmlInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnotherXmlInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// An XML object +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "snake_another_xml_object")] +pub struct AnotherXmlObject { + #[serde(rename = "inner_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub inner_string: Option, + +} + + +impl AnotherXmlObject { + #[allow(clippy::new_without_default)] + pub fn new() -> AnotherXmlObject { + AnotherXmlObject { + inner_string: None, + } + } +} + +/// Converts the AnotherXmlObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AnotherXmlObject { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.inner_string.as_ref().map(|inner_string| { + [ + "inner_string".to_string(), + inner_string.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnotherXmlObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AnotherXmlObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub inner_string: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing AnotherXmlObject".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "inner_string" => intermediate_rep.inner_string.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing AnotherXmlObject".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(AnotherXmlObject { + inner_string: intermediate_rep.inner_string.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnotherXmlObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnotherXmlObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnotherXmlObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnotherXmlObject { + /// Associated constant for this model's XML namespace. + #[allow(dead_code)] + pub const NAMESPACE: &'static str = "http://foo.bar"; +} + +impl AnotherXmlObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + let mut namespaces = std::collections::BTreeMap::new(); + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), Self::NAMESPACE.to_string()); + serde_xml_rs::to_string_with_namespaces(&self, namespaces).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnyOfGet202Response(swagger::AnyOf2); + +impl std::convert::From> for AnyOfGet202Response { + fn from(x: swagger::AnyOf2) -> Self { + AnyOfGet202Response(x) + } +} + +impl std::convert::From for swagger::AnyOf2 { + fn from(x: AnyOfGet202Response) -> Self { + x.0 + } +} + +impl std::ops::Deref for AnyOfGet202Response { + type Target = swagger::AnyOf2; + fn deref(&self) -> &swagger::AnyOf2 { + &self.0 + } +} + +impl std::ops::DerefMut for AnyOfGet202Response { + fn deref_mut(&mut self) -> &mut swagger::AnyOf2 { + &mut self.0 + } +} + +/// Converts the AnyOfGet202Response value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AnyOfGet202Response { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnyOfGet202Response value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AnyOfGet202Response { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AnyOfGet202Response is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnyOfGet202Response - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnyOfGet202Response - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnyOfGet202Response - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnyOfGet202Response { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Test a model containing an anyOf of a hash map +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnyOfHashMapObject(swagger::AnyOf2>); + +impl std::convert::From>> for AnyOfHashMapObject { + fn from(x: swagger::AnyOf2>) -> Self { + AnyOfHashMapObject(x) + } +} + +impl std::convert::From for swagger::AnyOf2> { + fn from(x: AnyOfHashMapObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for AnyOfHashMapObject { + type Target = swagger::AnyOf2>; + fn deref(&self) -> &swagger::AnyOf2> { + &self.0 + } +} + +impl std::ops::DerefMut for AnyOfHashMapObject { + fn deref_mut(&mut self) -> &mut swagger::AnyOf2> { + &mut self.0 + } +} + +/// Converts the AnyOfHashMapObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AnyOfHashMapObject { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnyOfHashMapObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AnyOfHashMapObject { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AnyOfHashMapObject is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnyOfHashMapObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnyOfHashMapObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnyOfHashMapObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnyOfHashMapObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Test a model containing an anyOf +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnyOfObject(swagger::AnyOf2); + +impl std::convert::From> for AnyOfObject { + fn from(x: swagger::AnyOf2) -> Self { + AnyOfObject(x) + } +} + +impl std::convert::From for swagger::AnyOf2 { + fn from(x: AnyOfObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for AnyOfObject { + type Target = swagger::AnyOf2; + fn deref(&self) -> &swagger::AnyOf2 { + &self.0 + } +} + +impl std::ops::DerefMut for AnyOfObject { + fn deref_mut(&mut self) -> &mut swagger::AnyOf2 { + &mut self.0 + } +} + +/// Converts the AnyOfObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AnyOfObject { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnyOfObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AnyOfObject { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AnyOfObject is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnyOfObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnyOfObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnyOfObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnyOfObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum AnyOfObjectAnyOf { + #[serde(rename = "FOO")] + Foo, + #[serde(rename = "BAR")] + Bar, +} + +impl std::fmt::Display for AnyOfObjectAnyOf { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + AnyOfObjectAnyOf::Foo => write!(f, "FOO"), + AnyOfObjectAnyOf::Bar => write!(f, "BAR"), + } + } +} + +impl std::str::FromStr for AnyOfObjectAnyOf { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "FOO" => std::result::Result::Ok(AnyOfObjectAnyOf::Foo), + "BAR" => std::result::Result::Ok(AnyOfObjectAnyOf::Bar), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnyOfObjectAnyOf - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnyOfObjectAnyOf - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnyOfObjectAnyOf - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnyOfObjectAnyOf { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Test containing an anyOf object +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnyOfProperty { + #[serde(rename = "requiredAnyOf")] + pub required_any_of: models::AnyOfObject, + + #[serde(rename = "optionalAnyOf")] + #[serde(skip_serializing_if="Option::is_none")] + pub optional_any_of: Option, + +} + + +impl AnyOfProperty { + #[allow(clippy::new_without_default)] + pub fn new(required_any_of: models::AnyOfObject, ) -> AnyOfProperty { + AnyOfProperty { + required_any_of, + optional_any_of: None, + } + } +} + +/// Converts the AnyOfProperty value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AnyOfProperty { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type requiredAnyOf in query parameter serialization + // Skipping non-primitive type optionalAnyOf in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnyOfProperty value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AnyOfProperty { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub required_any_of: Vec, + pub optional_any_of: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing AnyOfProperty".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "requiredAnyOf" => intermediate_rep.required_any_of.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "optionalAnyOf" => intermediate_rep.optional_any_of.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing AnyOfProperty".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(AnyOfProperty { + required_any_of: intermediate_rep.required_any_of.into_iter().next().ok_or_else(|| "requiredAnyOf missing in AnyOfProperty".to_string())?, + optional_any_of: intermediate_rep.optional_any_of.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnyOfProperty - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnyOfProperty - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnyOfProperty - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnyOfProperty { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// An XML object +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "camelDuplicateXmlObject")] +pub struct DuplicateXmlObject { + #[serde(rename = "inner_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub inner_string: Option, + + #[serde(rename = "inner_array")] + #[serde(serialize_with = "wrap_in_camelXmlInner")] + pub inner_array: models::XmlArray, + +} + + +impl DuplicateXmlObject { + #[allow(clippy::new_without_default)] + pub fn new(inner_array: models::XmlArray, ) -> DuplicateXmlObject { + DuplicateXmlObject { + inner_string: None, + inner_array, + } + } +} + +/// Converts the DuplicateXmlObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for DuplicateXmlObject { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.inner_string.as_ref().map(|inner_string| { + [ + "inner_string".to_string(), + inner_string.to_string(), + ].join(",") + }), + // Skipping non-primitive type inner_array in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a DuplicateXmlObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for DuplicateXmlObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub inner_string: Vec, + pub inner_array: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing DuplicateXmlObject".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "inner_string" => intermediate_rep.inner_string.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "inner_array" => intermediate_rep.inner_array.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing DuplicateXmlObject".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(DuplicateXmlObject { + inner_string: intermediate_rep.inner_string.into_iter().next(), + inner_array: intermediate_rep.inner_array.into_iter().next().ok_or_else(|| "inner_array missing in DuplicateXmlObject".to_string())?, + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for DuplicateXmlObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into DuplicateXmlObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into DuplicateXmlObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl DuplicateXmlObject { + /// Associated constant for this model's XML namespace. + #[allow(dead_code)] + pub const NAMESPACE: &'static str = "http://different.bar"; +} + +impl DuplicateXmlObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + let mut namespaces = std::collections::BTreeMap::new(); + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), Self::NAMESPACE.to_string()); + serde_xml_rs::to_string_with_namespaces(&self, namespaces).expect("impossible to fail to serialize") + } +} + +/// Test a model containing a special character in the enum +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumWithStarObject { + #[serde(rename = "FOO")] + Foo, + #[serde(rename = "BAR")] + Bar, + #[serde(rename = "*")] + Star, +} + +impl std::fmt::Display for EnumWithStarObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumWithStarObject::Foo => write!(f, "FOO"), + EnumWithStarObject::Bar => write!(f, "BAR"), + EnumWithStarObject::Star => write!(f, "*"), + } + } +} + +impl std::str::FromStr for EnumWithStarObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "FOO" => std::result::Result::Ok(EnumWithStarObject::Foo), + "BAR" => std::result::Result::Ok(EnumWithStarObject::Bar), + "*" => std::result::Result::Ok(EnumWithStarObject::Star), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumWithStarObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumWithStarObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumWithStarObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumWithStarObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Err(String); + +impl std::convert::From for Err { + fn from(x: String) -> Self { + Err(x) + } +} + +impl std::convert::From for String { + fn from(x: Err) -> Self { + x.0 + } +} + +impl std::ops::Deref for Err { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for Err { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for Err { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for Err { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(Err(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Err - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Err - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Err - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Err { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Error(String); + +impl std::convert::From for Error { + fn from(x: String) -> Self { + Error(x) + } +} + +impl std::convert::From for String { + fn from(x: Error) -> Self { + x.0 + } +} + +impl std::ops::Deref for Error { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for Error { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for Error { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for Error { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(Error(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Error - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Error - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Error - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Error { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Test a model containing an anyOf that starts with a number +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Model12345AnyOfObject(swagger::AnyOf2); + +impl std::convert::From> for Model12345AnyOfObject { + fn from(x: swagger::AnyOf2) -> Self { + Model12345AnyOfObject(x) + } +} + +impl std::convert::From for swagger::AnyOf2 { + fn from(x: Model12345AnyOfObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for Model12345AnyOfObject { + type Target = swagger::AnyOf2; + fn deref(&self) -> &swagger::AnyOf2 { + &self.0 + } +} + +impl std::ops::DerefMut for Model12345AnyOfObject { + fn deref_mut(&mut self) -> &mut swagger::AnyOf2 { + &mut self.0 + } +} + +/// Converts the Model12345AnyOfObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for Model12345AnyOfObject { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Model12345AnyOfObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for Model12345AnyOfObject { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing Model12345AnyOfObject is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Model12345AnyOfObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Model12345AnyOfObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Model12345AnyOfObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Model12345AnyOfObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum Model12345AnyOfObjectAnyOf { + #[serde(rename = "FOO")] + Foo, + #[serde(rename = "BAR")] + Bar, + #[serde(rename = "*")] + Star, +} + +impl std::fmt::Display for Model12345AnyOfObjectAnyOf { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Model12345AnyOfObjectAnyOf::Foo => write!(f, "FOO"), + Model12345AnyOfObjectAnyOf::Bar => write!(f, "BAR"), + Model12345AnyOfObjectAnyOf::Star => write!(f, "*"), + } + } +} + +impl std::str::FromStr for Model12345AnyOfObjectAnyOf { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "FOO" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Foo), + "BAR" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Bar), + "*" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Star), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Model12345AnyOfObjectAnyOf - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Model12345AnyOfObjectAnyOf - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Model12345AnyOfObjectAnyOf - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Model12345AnyOfObjectAnyOf { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MultigetGet201Response { + #[serde(rename = "foo")] + #[serde(skip_serializing_if="Option::is_none")] + pub foo: Option, + +} + + +impl MultigetGet201Response { + #[allow(clippy::new_without_default)] + pub fn new() -> MultigetGet201Response { + MultigetGet201Response { + foo: None, + } + } +} + +/// Converts the MultigetGet201Response value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MultigetGet201Response { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.foo.as_ref().map(|foo| { + [ + "foo".to_string(), + foo.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MultigetGet201Response value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MultigetGet201Response { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub foo: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MultigetGet201Response".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "foo" => intermediate_rep.foo.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing MultigetGet201Response".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MultigetGet201Response { + foo: intermediate_rep.foo.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MultigetGet201Response - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MultigetGet201Response - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MultigetGet201Response - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MultigetGet201Response { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MyId(i32); + +impl std::convert::From for MyId { + fn from(x: i32) -> Self { + MyId(x) + } +} + +impl std::convert::From for i32 { + fn from(x: MyId) -> Self { + x.0 + } +} + +impl std::ops::Deref for MyId { + type Target = i32; + fn deref(&self) -> &i32 { + &self.0 + } +} + +impl std::ops::DerefMut for MyId { + fn deref_mut(&mut self) -> &mut i32 { + &mut self.0 + } +} + +/// Converts the MyId value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for MyId { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MyId value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for MyId { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(MyId(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to MyId: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MyId - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MyId - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MyId - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MyId { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MyIdList( + Vec +); + +impl std::convert::From> for MyIdList { + fn from(x: Vec) -> Self { + MyIdList(x) + } +} + +impl std::convert::From for Vec { + fn from(x: MyIdList) -> Self { + x.0 + } +} + +impl std::iter::FromIterator for MyIdList { + fn from_iter>(u: U) -> Self { + MyIdList(Vec::::from_iter(u)) + } +} + +impl std::iter::IntoIterator for MyIdList { + type Item = i32; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a MyIdList { + type Item = &'a i32; + type IntoIter = std::slice::Iter<'a, i32>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a mut MyIdList { + type Item = &'a mut i32; + type IntoIter = std::slice::IterMut<'a, i32>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() + } +} + +impl std::ops::Deref for MyIdList { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for MyIdList { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Converts the MyIdList value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MyIdList { + fn to_string(&self) -> String { + self.iter().map(|x| x.to_string()).collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MyIdList value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MyIdList { + type Err = ::Err; + + fn from_str(s: &str) -> std::result::Result { + let mut items = vec![]; + for item in s.split(',') + { + items.push(item.parse()?); + } + std::result::Result::Ok(MyIdList(items)) + } +} + + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MyIdList - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MyIdList - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MyIdList - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MyIdList { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct NullableObject(String); + +impl std::convert::From for NullableObject { + fn from(x: String) -> Self { + NullableObject(x) + } +} + +impl std::convert::From for String { + fn from(x: NullableObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for NullableObject { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for NullableObject { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for NullableObject { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for NullableObject { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(NullableObject(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for NullableObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into NullableObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into NullableObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl NullableObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct NullableTest { + #[serde(rename = "nullable")] + pub nullable: swagger::Nullable, + + #[serde(rename = "nullableWithNullDefault")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_with_null_default: Option>, + + #[serde(rename = "nullableWithPresentDefault")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_with_present_default: Option>, + + #[serde(rename = "nullableWithNoDefault")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_with_no_default: Option>, + + #[serde(rename = "nullableArray")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_array: Option>>, + + #[serde(rename = "min_item_test")] + #[validate( + length(min = 1), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub min_item_test: Option>, + + #[serde(rename = "max_item_test")] + #[validate( + length(max = 2), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub max_item_test: Option>, + + #[serde(rename = "min_max_item_test")] + #[validate( + length(min = 1, max = 3), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub min_max_item_test: Option>, + +} + + +impl NullableTest { + #[allow(clippy::new_without_default)] + pub fn new(nullable: swagger::Nullable, ) -> NullableTest { + NullableTest { + nullable, + nullable_with_null_default: None, + nullable_with_present_default: Some(swagger::Nullable::Present("default".to_string())), + nullable_with_no_default: None, + nullable_array: None, + min_item_test: None, + max_item_test: None, + min_max_item_test: None, + } + } +} + +/// Converts the NullableTest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for NullableTest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("nullable".to_string()), + Some(self.nullable.as_ref().map_or("null".to_string(), |x| x.to_string())), + self.nullable_with_null_default.as_ref().map(|nullable_with_null_default| { + [ + "nullableWithNullDefault".to_string(), + nullable_with_null_default.as_ref().map_or("null".to_string(), |x| x.to_string()), + ].join(",") + }), + self.nullable_with_present_default.as_ref().map(|nullable_with_present_default| { + [ + "nullableWithPresentDefault".to_string(), + nullable_with_present_default.as_ref().map_or("null".to_string(), |x| x.to_string()), + ].join(",") + }), + self.nullable_with_no_default.as_ref().map(|nullable_with_no_default| { + [ + "nullableWithNoDefault".to_string(), + nullable_with_no_default.as_ref().map_or("null".to_string(), |x| x.to_string()), + ].join(",") + }), + self.nullable_array.as_ref().map(|nullable_array| { + [ + "nullableArray".to_string(), + nullable_array.as_ref().map_or("null".to_string(), |x| x.iter().map(|x| x.to_string()).collect::>().join(",")), + ].join(",") + }), + self.min_item_test.as_ref().map(|min_item_test| { + [ + "min_item_test".to_string(), + min_item_test.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + self.max_item_test.as_ref().map(|max_item_test| { + [ + "max_item_test".to_string(), + max_item_test.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + self.min_max_item_test.as_ref().map(|min_max_item_test| { + [ + "min_max_item_test".to_string(), + min_max_item_test.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a NullableTest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for NullableTest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub nullable: Vec>, + pub nullable_with_null_default: Vec>, + pub nullable_with_present_default: Vec>, + pub nullable_with_no_default: Vec>, + pub nullable_array: Vec>>, + pub min_item_test: Vec>, + pub max_item_test: Vec>, + pub min_max_item_test: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing NullableTest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "nullable" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in NullableTest".to_string()), + "nullableWithNullDefault" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in NullableTest".to_string()), + "nullableWithPresentDefault" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in NullableTest".to_string()), + "nullableWithNoDefault" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in NullableTest".to_string()), + "nullableArray" => return std::result::Result::Err("Parsing a container in this style is not supported in NullableTest".to_string()), + "min_item_test" => return std::result::Result::Err("Parsing a container in this style is not supported in NullableTest".to_string()), + "max_item_test" => return std::result::Result::Err("Parsing a container in this style is not supported in NullableTest".to_string()), + "min_max_item_test" => return std::result::Result::Err("Parsing a container in this style is not supported in NullableTest".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing NullableTest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(NullableTest { + nullable: std::result::Result::Err("Nullable types not supported in NullableTest".to_string())?, + nullable_with_null_default: std::result::Result::Err("Nullable types not supported in NullableTest".to_string())?, + nullable_with_present_default: std::result::Result::Err("Nullable types not supported in NullableTest".to_string())?, + nullable_with_no_default: std::result::Result::Err("Nullable types not supported in NullableTest".to_string())?, + nullable_array: std::result::Result::Err("Nullable types not supported in NullableTest".to_string())?, + min_item_test: intermediate_rep.min_item_test.into_iter().next(), + max_item_test: intermediate_rep.max_item_test.into_iter().next(), + min_max_item_test: intermediate_rep.min_max_item_test.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for NullableTest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into NullableTest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into NullableTest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl NullableTest { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectHeader { + #[serde(rename = "requiredObjectHeader")] + pub required_object_header: bool, + + #[serde(rename = "optionalObjectHeader")] + #[serde(skip_serializing_if="Option::is_none")] + pub optional_object_header: Option, + +} + + +impl ObjectHeader { + #[allow(clippy::new_without_default)] + pub fn new(required_object_header: bool, ) -> ObjectHeader { + ObjectHeader { + required_object_header, + optional_object_header: None, + } + } +} + +/// Converts the ObjectHeader value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectHeader { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("requiredObjectHeader".to_string()), + Some(self.required_object_header.to_string()), + self.optional_object_header.as_ref().map(|optional_object_header| { + [ + "optionalObjectHeader".to_string(), + optional_object_header.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectHeader value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectHeader { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub required_object_header: Vec, + pub optional_object_header: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectHeader".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "requiredObjectHeader" => intermediate_rep.required_object_header.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "optionalObjectHeader" => intermediate_rep.optional_object_header.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectHeader".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectHeader { + required_object_header: intermediate_rep.required_object_header.into_iter().next().ok_or_else(|| "requiredObjectHeader missing in ObjectHeader".to_string())?, + optional_object_header: intermediate_rep.optional_object_header.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectHeader - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectHeader - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectHeader - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectHeader { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectParam { + #[serde(rename = "requiredParam")] + pub required_param: bool, + + #[serde(rename = "optionalParam")] + #[serde(skip_serializing_if="Option::is_none")] + pub optional_param: Option, + +} + + +impl ObjectParam { + #[allow(clippy::new_without_default)] + pub fn new(required_param: bool, ) -> ObjectParam { + ObjectParam { + required_param, + optional_param: None, + } + } +} + +/// Converts the ObjectParam value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectParam { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("requiredParam".to_string()), + Some(self.required_param.to_string()), + self.optional_param.as_ref().map(|optional_param| { + [ + "optionalParam".to_string(), + optional_param.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectParam value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectParam { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub required_param: Vec, + pub optional_param: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectParam".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "requiredParam" => intermediate_rep.required_param.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "optionalParam" => intermediate_rep.optional_param.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectParam".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectParam { + required_param: intermediate_rep.required_param.into_iter().next().ok_or_else(|| "requiredParam missing in ObjectParam".to_string())?, + optional_param: intermediate_rep.optional_param.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectParam - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectParam - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectParam - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectParam { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectUntypedProps { + #[serde(rename = "required_untyped")] + pub required_untyped: serde_json::Value, + + #[serde(rename = "required_untyped_nullable")] + pub required_untyped_nullable: swagger::Nullable, + + #[serde(rename = "not_required_untyped")] + #[serde(skip_serializing_if="Option::is_none")] + pub not_required_untyped: Option, + + #[serde(rename = "not_required_untyped_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub not_required_untyped_nullable: Option, + +} + + +impl ObjectUntypedProps { + #[allow(clippy::new_without_default)] + pub fn new(required_untyped: serde_json::Value, required_untyped_nullable: swagger::Nullable, ) -> ObjectUntypedProps { + ObjectUntypedProps { + required_untyped, + required_untyped_nullable, + not_required_untyped: None, + not_required_untyped_nullable: None, + } + } +} + +/// Converts the ObjectUntypedProps value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectUntypedProps { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type required_untyped in query parameter serialization + // Skipping non-primitive type required_untyped_nullable in query parameter serialization + // Skipping non-primitive type not_required_untyped in query parameter serialization + // Skipping non-primitive type not_required_untyped_nullable in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectUntypedProps value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectUntypedProps { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub required_untyped: Vec, + pub required_untyped_nullable: Vec>, + pub not_required_untyped: Vec, + pub not_required_untyped_nullable: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectUntypedProps".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "required_untyped" => intermediate_rep.required_untyped.push(::from_str(val).map_err(|x| x.to_string())?), + "required_untyped_nullable" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in ObjectUntypedProps".to_string()), + #[allow(clippy::redundant_clone)] + "not_required_untyped" => intermediate_rep.not_required_untyped.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "not_required_untyped_nullable" => intermediate_rep.not_required_untyped_nullable.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectUntypedProps".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectUntypedProps { + required_untyped: intermediate_rep.required_untyped.into_iter().next().ok_or_else(|| "required_untyped missing in ObjectUntypedProps".to_string())?, + required_untyped_nullable: std::result::Result::Err("Nullable types not supported in ObjectUntypedProps".to_string())?, + not_required_untyped: intermediate_rep.not_required_untyped.into_iter().next(), + not_required_untyped_nullable: intermediate_rep.not_required_untyped_nullable.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectUntypedProps - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectUntypedProps - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectUntypedProps - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectUntypedProps { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectWithArrayOfObjects { + #[serde(rename = "objectArray")] + #[serde(skip_serializing_if="Option::is_none")] + pub object_array: Option>, + +} + + +impl ObjectWithArrayOfObjects { + #[allow(clippy::new_without_default)] + pub fn new() -> ObjectWithArrayOfObjects { + ObjectWithArrayOfObjects { + object_array: None, + } + } +} + +/// Converts the ObjectWithArrayOfObjects value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectWithArrayOfObjects { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.object_array.as_ref().map(|object_array| { + [ + "objectArray".to_string(), + object_array.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectWithArrayOfObjects value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectWithArrayOfObjects { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub object_array: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectWithArrayOfObjects".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "objectArray" => return std::result::Result::Err("Parsing a container in this style is not supported in ObjectWithArrayOfObjects".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectWithArrayOfObjects".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectWithArrayOfObjects { + object_array: intermediate_rep.object_array.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectWithArrayOfObjects - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectWithArrayOfObjects - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectWithArrayOfObjects - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectWithArrayOfObjects { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Ok(String); + +impl std::convert::From for Ok { + fn from(x: String) -> Self { + Ok(x) + } +} + +impl std::convert::From for String { + fn from(x: Ok) -> Self { + x.0 + } +} + +impl std::ops::Deref for Ok { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for Ok { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for Ok { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for Ok { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(Ok(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Ok - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Ok - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Ok - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Ok { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OneOfGet200Response(swagger::OneOf2>); + +impl std::convert::From>> for OneOfGet200Response { + fn from(x: swagger::OneOf2>) -> Self { + OneOfGet200Response(x) + } +} + +impl std::convert::From for swagger::OneOf2> { + fn from(x: OneOfGet200Response) -> Self { + x.0 + } +} + +impl std::ops::Deref for OneOfGet200Response { + type Target = swagger::OneOf2>; + fn deref(&self) -> &swagger::OneOf2> { + &self.0 + } +} + +impl std::ops::DerefMut for OneOfGet200Response { + fn deref_mut(&mut self) -> &mut swagger::OneOf2> { + &mut self.0 + } +} + +/// Converts the OneOfGet200Response value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for OneOfGet200Response { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OneOfGet200Response value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for OneOfGet200Response { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing OneOfGet200Response is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OneOfGet200Response - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OneOfGet200Response - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OneOfGet200Response - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OneOfGet200Response { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OptionalObjectHeader(i32); + +impl std::convert::From for OptionalObjectHeader { + fn from(x: i32) -> Self { + OptionalObjectHeader(x) + } +} + +impl std::convert::From for i32 { + fn from(x: OptionalObjectHeader) -> Self { + x.0 + } +} + +impl std::ops::Deref for OptionalObjectHeader { + type Target = i32; + fn deref(&self) -> &i32 { + &self.0 + } +} + +impl std::ops::DerefMut for OptionalObjectHeader { + fn deref_mut(&mut self) -> &mut i32 { + &mut self.0 + } +} + +/// Converts the OptionalObjectHeader value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for OptionalObjectHeader { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OptionalObjectHeader value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for OptionalObjectHeader { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(OptionalObjectHeader(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OptionalObjectHeader: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OptionalObjectHeader - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OptionalObjectHeader - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OptionalObjectHeader - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OptionalObjectHeader { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct RequiredObjectHeader(bool); + +impl std::convert::From for RequiredObjectHeader { + fn from(x: bool) -> Self { + RequiredObjectHeader(x) + } +} + +impl std::convert::From for bool { + fn from(x: RequiredObjectHeader) -> Self { + x.0 + } +} + +impl std::ops::Deref for RequiredObjectHeader { + type Target = bool; + fn deref(&self) -> &bool { + &self.0 + } +} + +impl std::ops::DerefMut for RequiredObjectHeader { + fn deref_mut(&mut self) -> &mut bool { + &mut self.0 + } +} + +/// Converts the RequiredObjectHeader value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for RequiredObjectHeader { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a RequiredObjectHeader value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for RequiredObjectHeader { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(RequiredObjectHeader(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to RequiredObjectHeader: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for RequiredObjectHeader - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into RequiredObjectHeader - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into RequiredObjectHeader - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl RequiredObjectHeader { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Result(String); + +impl std::convert::From for Result { + fn from(x: String) -> Self { + Result(x) + } +} + +impl std::convert::From for String { + fn from(x: Result) -> Self { + x.0 + } +} + +impl std::ops::Deref for Result { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for Result { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for Result { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for Result { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(Result(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Result - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Result - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Result - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Result { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum StringEnum { + #[serde(rename = "FOO")] + Foo, + #[serde(rename = "BAR")] + Bar, +} + +impl std::fmt::Display for StringEnum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + StringEnum::Foo => write!(f, "FOO"), + StringEnum::Bar => write!(f, "BAR"), + } + } +} + +impl std::str::FromStr for StringEnum { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "FOO" => std::result::Result::Ok(StringEnum::Foo), + "BAR" => std::result::Result::Ok(StringEnum::Bar), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for StringEnum - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into StringEnum - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into StringEnum - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl StringEnum { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct StringObject(String); + +impl std::convert::From for StringObject { + fn from(x: String) -> Self { + StringObject(x) + } +} + +impl std::convert::From for String { + fn from(x: StringObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for StringObject { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for StringObject { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for StringObject { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for StringObject { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(StringObject(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for StringObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into StringObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into StringObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl StringObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Test a model containing a UUID +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct UuidObject(uuid::Uuid); + +impl std::convert::From for UuidObject { + fn from(x: uuid::Uuid) -> Self { + UuidObject(x) + } +} + +impl std::convert::From for uuid::Uuid { + fn from(x: UuidObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for UuidObject { + type Target = uuid::Uuid; + fn deref(&self) -> &uuid::Uuid { + &self.0 + } +} + +impl std::ops::DerefMut for UuidObject { + fn deref_mut(&mut self) -> &mut uuid::Uuid { + &mut self.0 + } +} + +/// Converts the UuidObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for UuidObject { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a UuidObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for UuidObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(UuidObject(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to UuidObject: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for UuidObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into UuidObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into UuidObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl UuidObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +// Utility function for wrapping list elements when serializing xml +#[allow(non_snake_case)] +fn wrap_in_camelXmlInner(item: &Vec, serializer: S) -> std::result::Result +where + S: serde::ser::Serializer, +{ + serde_xml_rs::wrap_primitives(item, serializer, "camelXmlInner") +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct XmlArray( + #[serde(serialize_with = "wrap_in_camelXmlInner")] + Vec +); + +impl std::convert::From> for XmlArray { + fn from(x: Vec) -> Self { + XmlArray(x) + } +} + +impl std::convert::From for Vec { + fn from(x: XmlArray) -> Self { + x.0 + } +} + +impl std::iter::FromIterator for XmlArray { + fn from_iter>(u: U) -> Self { + XmlArray(Vec::::from_iter(u)) + } +} + +impl std::iter::IntoIterator for XmlArray { + type Item = String; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a XmlArray { + type Item = &'a String; + type IntoIter = std::slice::Iter<'a, String>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a mut XmlArray { + type Item = &'a mut String; + type IntoIter = std::slice::IterMut<'a, String>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() + } +} + +impl std::ops::Deref for XmlArray { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for XmlArray { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Converts the XmlArray value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for XmlArray { + fn to_string(&self) -> String { + self.iter().map(|x| x.to_string()).collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a XmlArray value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for XmlArray { + type Err = ::Err; + + fn from_str(s: &str) -> std::result::Result { + let mut items = vec![]; + for item in s.split(',') + { + items.push(item.parse()?); + } + std::result::Result::Ok(XmlArray(items)) + } +} + + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for XmlArray - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into XmlArray - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into XmlArray - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl XmlArray { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "camelXmlInner")] +pub struct XmlInner(String); + +impl std::convert::From for XmlInner { + fn from(x: String) -> Self { + XmlInner(x) + } +} + +impl std::convert::From for String { + fn from(x: XmlInner) -> Self { + x.0 + } +} + +impl std::ops::Deref for XmlInner { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for XmlInner { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for XmlInner { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for XmlInner { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(XmlInner(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for XmlInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into XmlInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into XmlInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl XmlInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// An XML object +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "camelXmlObject")] +pub struct XmlObject { + #[serde(rename = "innerString")] + #[serde(skip_serializing_if="Option::is_none")] + pub inner_string: Option, + + #[serde(rename = "other_inner_rename")] + #[serde(skip_serializing_if="Option::is_none")] + pub other_inner_rename: Option, + +} + + +impl XmlObject { + #[allow(clippy::new_without_default)] + pub fn new() -> XmlObject { + XmlObject { + inner_string: None, + other_inner_rename: None, + } + } +} + +/// Converts the XmlObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for XmlObject { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.inner_string.as_ref().map(|inner_string| { + [ + "innerString".to_string(), + inner_string.to_string(), + ].join(",") + }), + self.other_inner_rename.as_ref().map(|other_inner_rename| { + [ + "other_inner_rename".to_string(), + other_inner_rename.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a XmlObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for XmlObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub inner_string: Vec, + pub other_inner_rename: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing XmlObject".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "innerString" => intermediate_rep.inner_string.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "other_inner_rename" => intermediate_rep.other_inner_rename.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing XmlObject".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(XmlObject { + inner_string: intermediate_rep.inner_string.into_iter().next(), + other_inner_rename: intermediate_rep.other_inner_rename.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for XmlObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into XmlObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into XmlObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl XmlObject { + /// Associated constant for this model's XML namespace. + #[allow(dead_code)] + pub const NAMESPACE: &'static str = "http://foo.bar"; +} + +impl XmlObject { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + let mut namespaces = std::collections::BTreeMap::new(); + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), Self::NAMESPACE.to_string()); + serde_xml_rs::to_string_with_namespaces(&self, namespaces).expect("impossible to fail to serialize") + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/callbacks.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/callbacks.rs new file mode 100644 index 000000000000..d698a4f5b963 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/callbacks.rs @@ -0,0 +1,389 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::CallbackApi; +use crate::CallbackCallbackWithHeaderPostResponse; +use crate::CallbackCallbackPostResponse; + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client") + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `new_http`, `new_https` + /// and `new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn new_with_connector(connector: Connector) -> Self + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Self { + client_service, + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + pub fn new_http() -> Self { + let http_connector = Connector::builder().build(); + Self::new_with_connector(http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server. + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + pub fn new_https() -> Result + { + let https_connector = Connector::builder().https().build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a TLS connection to the server. + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https() -> Result + { + let https_connector = Connector::builder().https().build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a TLS connection to the server, pinning the certificate + /// + /// # Arguments + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https_pinned( + ca_certificate: CA, + ) -> Result where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build()?; + Ok(Self::new_with_connector(https_connector)) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn new_https_mutual( + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build()?; + Ok(Self::new_with_connector(https_connector)) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `swagger::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn new_with_client_service( + client_service: S, + ) -> Self { + Client { + client_service, + marker: PhantomData, + } + } +} + +#[async_trait] +impl CallbackApi for Client where + S: Service< + (Request, C), + Response=Response, + Error=hyper::Error> + Clone + Send + Sync, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Has> + Clone + Send + Sync, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn callback_callback_with_header_post( + &self, + callback_request_query_url: String, + param_information: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{request_query_url}/callback-with-header" + ,request_query_url=callback_request_query_url + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + // Header parameters + #[allow(clippy::single_match)] + match param_information { + Some(param_information) => { + request.headers_mut().append( + HeaderName::from_static("information"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_information.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header information - {e}"))); + }, + }); + }, + None => {} + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + CallbackCallbackWithHeaderPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn callback_callback_post( + &self, + callback_request_query_url: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{request_query_url}/callback" + ,request_query_url=callback_request_query_url + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + CallbackCallbackPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/mod.rs new file mode 100644 index 000000000000..102a1b85c530 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/mod.rs @@ -0,0 +1,2335 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + AnyOfGetResponse, + CallbackWithHeaderPostResponse, + ComplexQueryParamGetResponse, + ExamplesTestResponse, + FormTestResponse, + GetWithBooleanParameterResponse, + JsonComplexQueryParamGetResponse, + MandatoryRequestHeaderGetResponse, + MergePatchJsonGetResponse, + MultigetGetResponse, + MultipleAuthSchemeGetResponse, + OneOfGetResponse, + OverrideServerGetResponse, + ParamgetGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredOctetStreamPutResponse, + ResponsesWithHeadersGetResponse, + Rfc7807GetResponse, + TwoFirstLetterHeadersResponse, + UntypedPropertyGetResponse, + UuidGetResponse, + XmlExtraPostResponse, + XmlOtherPostResponse, + XmlOtherPutResponse, + XmlPostResponse, + XmlPutResponse, + EnumInPathPathParamGetResponse, + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse, + CreateRepoResponse, + GetRepoInfoResponse +}; + +mod server_auth; + +pub mod callbacks; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/any-of$", + r"^/callback-with-header$", + r"^/complex-query-param$", + r"^/enum_in_path/(?P[^/?#]*)$", + r"^/examples-test$", + r"^/form-test$", + r"^/get-with-bool$", + r"^/json-complex-query-param$", + r"^/mandatory-request-header$", + r"^/merge-patch-json$", + r"^/multiget$", + r"^/multiple-path-params-with-very-long-path-to-test-formatting/(?P[^/?#]*)/(?P[^/?#]*)$", + r"^/multiple_auth_scheme$", + r"^/one-of$", + r"^/operation-two-first-letter-headers$", + r"^/override-server$", + r"^/paramget$", + r"^/readonly_auth_scheme$", + r"^/register-callback$", + r"^/repos$", + r"^/repos/(?P[^/?#]*)$", + r"^/required_octet_stream$", + r"^/responses_with_headers$", + r"^/rfc7807$", + r"^/untyped_property$", + r"^/uuid$", + r"^/xml$", + r"^/xml_extra$", + r"^/xml_other$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_ANY_OF: usize = 0; + pub(crate) static ID_CALLBACK_WITH_HEADER: usize = 1; + pub(crate) static ID_COMPLEX_QUERY_PARAM: usize = 2; + pub(crate) static ID_ENUM_IN_PATH_PATH_PARAM: usize = 3; + lazy_static! { + pub static ref REGEX_ENUM_IN_PATH_PATH_PARAM: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/enum_in_path/(?P[^/?#]*)$") + .expect("Unable to create regex for ENUM_IN_PATH_PATH_PARAM"); + } + pub(crate) static ID_EXAMPLES_TEST: usize = 4; + pub(crate) static ID_FORM_TEST: usize = 5; + pub(crate) static ID_GET_WITH_BOOL: usize = 6; + pub(crate) static ID_JSON_COMPLEX_QUERY_PARAM: usize = 7; + pub(crate) static ID_MANDATORY_REQUEST_HEADER: usize = 8; + pub(crate) static ID_MERGE_PATCH_JSON: usize = 9; + pub(crate) static ID_MULTIGET: usize = 10; + pub(crate) static ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B: usize = 11; + lazy_static! { + pub static ref REGEX_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/multiple-path-params-with-very-long-path-to-test-formatting/(?P[^/?#]*)/(?P[^/?#]*)$") + .expect("Unable to create regex for MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B"); + } + pub(crate) static ID_MULTIPLE_AUTH_SCHEME: usize = 12; + pub(crate) static ID_ONE_OF: usize = 13; + pub(crate) static ID_OPERATION_TWO_FIRST_LETTER_HEADERS: usize = 14; + pub(crate) static ID_OVERRIDE_SERVER: usize = 15; + pub(crate) static ID_PARAMGET: usize = 16; + pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 17; + pub(crate) static ID_REGISTER_CALLBACK: usize = 18; + pub(crate) static ID_REPOS: usize = 19; + pub(crate) static ID_REPOS_REPOID: usize = 20; + lazy_static! { + pub static ref REGEX_REPOS_REPOID: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/repos/(?P[^/?#]*)$") + .expect("Unable to create regex for REPOS_REPOID"); + } + pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 21; + pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 22; + pub(crate) static ID_RFC7807: usize = 23; + pub(crate) static ID_UNTYPED_PROPERTY: usize = 24; + pub(crate) static ID_UUID: usize = 25; + pub(crate) static ID_XML: usize = 26; + pub(crate) static ID_XML_EXTRA: usize = 27; + pub(crate) static ID_XML_OTHER: usize = 28; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // AnyOfGet - GET /any-of + hyper::Method::GET if path.matched(paths::ID_ANY_OF) => { + // 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::>(); + let param_any_of = query_params.iter().filter(|e| e.0 == "any-of").map(|e| e.1.clone()) + .filter_map(|param_any_of| param_any_of.parse().ok()) + .collect::>(); + let param_any_of = if !param_any_of.is_empty() { + Some(param_any_of) + } else { + None + }; + + let result = api_impl.any_of_get( + param_any_of.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + AnyOfGetResponse::Success + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + AnyOfGetResponse::AlternateSuccess + (body) + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + AnyOfGetResponse::AnyOfSuccess + (body) + => { + *response.status_mut() = StatusCode::from_u16(202).expect("Unable to turn 202 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // CallbackWithHeaderPost - POST /callback-with-header + hyper::Method::POST if path.matched(paths::ID_CALLBACK_WITH_HEADER) => { + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.clone()) + .next(); + let param_url = match param_url { + Some(param_url) => { + let param_url = + ::from_str + (¶m_url); + match param_url { + Ok(param_url) => Some(param_url), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter url")), + } + }, + None => None, + }; + let param_url = match param_url { + Some(param_url) => param_url, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter url")) + .expect("Unable to create Bad Request response for missing query parameter url")), + }; + + let result = api_impl.callback_with_header_post( + param_url, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + CallbackWithHeaderPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // ComplexQueryParamGet - GET /complex-query-param + hyper::Method::GET if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => { + // 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::>(); + let param_list_of_strings = query_params.iter().filter(|e| e.0 == "list-of-strings").map(|e| e.1.clone()) + .filter_map(|param_list_of_strings| param_list_of_strings.parse().ok()) + .collect::>(); + let param_list_of_strings = if !param_list_of_strings.is_empty() { + Some(param_list_of_strings) + } else { + None + }; + + let result = api_impl.complex_query_param_get( + param_list_of_strings.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ComplexQueryParamGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // ExamplesTest - GET /examples-test + hyper::Method::GET if path.matched(paths::ID_EXAMPLES_TEST) => { + // 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::>(); + let param_ids = query_params.iter().filter(|e| e.0 == "ids").map(|e| e.1.clone()) + .filter_map(|param_ids| param_ids.parse().ok()) + .collect::>(); + let param_ids = if !param_ids.is_empty() { + Some(param_ids) + } else { + None + }; + + let result = api_impl.examples_test( + param_ids.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ExamplesTestResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // FormTest - POST /form-test + hyper::Method::POST if path.matched(paths::ID_FORM_TEST) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + // Form parameters + let param_required_array = + None; + + + let result = api_impl.form_test( + param_required_array.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + FormTestResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // GetWithBooleanParameter - GET /get-with-bool + hyper::Method::GET if path.matched(paths::ID_GET_WITH_BOOL) => { + // 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::>(); + let param_iambool = query_params.iter().filter(|e| e.0 == "iambool").map(|e| e.1.clone()) + .next(); + let param_iambool = match param_iambool { + Some(param_iambool) => { + let param_iambool = + ::from_str + (¶m_iambool); + match param_iambool { + Ok(param_iambool) => Some(param_iambool), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter iambool - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter iambool")), + } + }, + None => None, + }; + let param_iambool = match param_iambool { + Some(param_iambool) => param_iambool, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter iambool")) + .expect("Unable to create Bad Request response for missing query parameter iambool")), + }; + + let result = api_impl.get_with_boolean_parameter( + param_iambool, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetWithBooleanParameterResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // JsonComplexQueryParamGet - GET /json-complex-query-param + hyper::Method::GET if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => { + // 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::>(); + let param_list_of_strings = query_params.iter().filter(|e| e.0 == "list-of-strings").map(|e| e.1.clone()) + .next(); + let param_list_of_strings = match param_list_of_strings { + Some(param_list_of_strings) => { + let param_list_of_strings = + serde_json::from_str::> + (¶m_list_of_strings); + match param_list_of_strings { + Ok(param_list_of_strings) => Some(param_list_of_strings), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter list-of-strings - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter list-of-strings")), + } + }, + None => None, + }; + + let result = api_impl.json_complex_query_param_get( + param_list_of_strings.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + JsonComplexQueryParamGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // MandatoryRequestHeaderGet - GET /mandatory-request-header + hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => { + // Header parameters + let param_x_header = headers.get(HeaderName::from_static("x-header")); + + let param_x_header = match param_x_header { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + result.0, + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header X-Header - {err}"))) + .expect("Unable to create Bad Request response for invalid header X-Header")); + + }, + }, + None => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required header X-Header")) + .expect("Unable to create Bad Request response for missing required header X-Header")); + } + }; + + let result = api_impl.mandatory_request_header_get( + param_x_header, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MandatoryRequestHeaderGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // MergePatchJsonGet - GET /merge-patch-json + hyper::Method::GET if path.matched(paths::ID_MERGE_PATCH_JSON) => { + let result = api_impl.merge_patch_json_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MergePatchJsonGetResponse::Merge + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/merge-patch+json") + .expect("Unable to create Content-Type header for application/merge-patch+json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // MultigetGet - GET /multiget + hyper::Method::GET if path.matched(paths::ID_MULTIGET) => { + let result = api_impl.multiget_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MultigetGetResponse::JSONRsp + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::XMLRsp + (body) + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::OctetRsp + (body) + => { + *response.status_mut() = StatusCode::from_u16(202).expect("Unable to turn 202 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/octet-stream") + .expect("Unable to create Content-Type header for application/octet-stream")); + // Binary Body + let body = body.0; + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::StringRsp + (body) + => { + *response.status_mut() = StatusCode::from_u16(203).expect("Unable to turn 203 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("text/plain") + .expect("Unable to create Content-Type header for text/plain")); + // Plain text Body + let body = body; + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::DuplicateResponseLongText + (body) + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::DuplicateResponseLongText_2 + (body) + => { + *response.status_mut() = StatusCode::from_u16(205).expect("Unable to turn 205 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + MultigetGetResponse::DuplicateResponseLongText_3 + (body) + => { + *response.status_mut() = StatusCode::from_u16(206).expect("Unable to turn 206 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // MultipleAuthSchemeGet - GET /multiple_auth_scheme + hyper::Method::GET if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "test.read".to_string(), // Allowed to read state. + "test.write".to_string(), // Allowed to change state. + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + let result = api_impl.multiple_auth_scheme_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MultipleAuthSchemeGetResponse::CheckThatLimitingToMultipleRequiredAuthSchemesWorks + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // OneOfGet - GET /one-of + hyper::Method::GET if path.matched(paths::ID_ONE_OF) => { + let result = api_impl.one_of_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + OneOfGetResponse::Success + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // OverrideServerGet - GET /override-server + hyper::Method::GET if path.matched(paths::ID_OVERRIDE_SERVER) => { + let result = api_impl.override_server_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + OverrideServerGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // ParamgetGet - GET /paramget + hyper::Method::GET if path.matched(paths::ID_PARAMGET) => { + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_uuid = query_params.iter().filter(|e| e.0 == "uuid").map(|e| e.1.clone()) + .next(); + let param_uuid = match param_uuid { + Some(param_uuid) => { + let param_uuid = + ::from_str + (¶m_uuid); + match param_uuid { + Ok(param_uuid) => Some(param_uuid), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter uuid - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter uuid")), + } + }, + None => None, + }; + let param_some_object = query_params.iter().filter(|e| e.0 == "someObject").map(|e| e.1.clone()) + .next(); + let param_some_object = match param_some_object { + Some(param_some_object) => { + let param_some_object = + ::from_str + (¶m_some_object); + match param_some_object { + Ok(param_some_object) => Some(param_some_object), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter someObject - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter someObject")), + } + }, + None => None, + }; + let param_some_list = query_params.iter().filter(|e| e.0 == "someList").map(|e| e.1.clone()) + .filter_map(|param_some_list| param_some_list.parse().ok()) + .collect::>(); + let param_some_list = if !param_some_list.is_empty() { + Some(param_some_list) + } else { + None + }; + + let result = api_impl.paramget_get( + param_uuid, + param_some_object, + param_some_list.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ParamgetGetResponse::JSONRsp + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // ReadonlyAuthSchemeGet - GET /readonly_auth_scheme + hyper::Method::GET if path.matched(paths::ID_READONLY_AUTH_SCHEME) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "test.read".to_string(), // Allowed to read state. + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + let result = api_impl.readonly_auth_scheme_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ReadonlyAuthSchemeGetResponse::CheckThatLimitingToASingleRequiredAuthSchemeWorks + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // RegisterCallbackPost - POST /register-callback + hyper::Method::POST if path.matched(paths::ID_REGISTER_CALLBACK) => { + // Query parameters (note that non-required or collection query parameters will ignore garbage values, rather than causing a 400 response) + let query_params = form_urlencoded::parse(uri.query().unwrap_or_default().as_bytes()).collect::>(); + let param_url = query_params.iter().filter(|e| e.0 == "url").map(|e| e.1.clone()) + .next(); + let param_url = match param_url { + Some(param_url) => { + let param_url = + ::from_str + (¶m_url); + match param_url { + Ok(param_url) => Some(param_url), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter url")), + } + }, + None => None, + }; + let param_url = match param_url { + Some(param_url) => param_url, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter url")) + .expect("Unable to create Bad Request response for missing query parameter url")), + }; + + let result = api_impl.register_callback_post( + param_url, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + RegisterCallbackPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // RequiredOctetStreamPut - PUT /required_octet_stream + hyper::Method::PUT if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let param_body: Option = if !body.is_empty() { + Some(swagger::ByteArray(body.to_vec())) + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.required_octet_stream_put( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + RequiredOctetStreamPutResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // ResponsesWithHeadersGet - GET /responses_with_headers + hyper::Method::GET if path.matched(paths::ID_RESPONSES_WITH_HEADERS) => { + let result = api_impl.responses_with_headers_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ResponsesWithHeadersGetResponse::Success + { + body, + success_info, + bool_header, + object_header + } + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + let success_info = match header::IntoHeaderValue(success_info).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling success_info header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("success-info"), + success_info + ); + + if let Some(bool_header) = bool_header { + let bool_header = match header::IntoHeaderValue(bool_header).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling bool_header header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("bool-header"), + bool_header + ); + } + + if let Some(object_header) = object_header { + let object_header = match header::IntoHeaderValue(object_header).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling object_header header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("object-header"), + object_header + ); + } + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + ResponsesWithHeadersGetResponse::PreconditionFailed + { + further_info, + failure_info + } + => { + *response.status_mut() = StatusCode::from_u16(412).expect("Unable to turn 412 into a StatusCode"); + + if let Some(further_info) = further_info { + let further_info = match header::IntoHeaderValue(further_info).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling further_info header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("further-info"), + further_info + ); + } + + if let Some(failure_info) = failure_info { + let failure_info = match header::IntoHeaderValue(failure_info).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling failure_info header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("failure-info"), + failure_info + ); + } + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Rfc7807Get - GET /rfc7807 + hyper::Method::GET if path.matched(paths::ID_RFC7807) => { + let result = api_impl.rfc7807_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Rfc7807GetResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + Rfc7807GetResponse::NotFound + (body) + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/problem+json") + .expect("Unable to create Content-Type header for application/problem+json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + Rfc7807GetResponse::NotAcceptable + (body) + => { + *response.status_mut() = StatusCode::from_u16(406).expect("Unable to turn 406 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/problem+xml") + .expect("Unable to create Content-Type header for application/problem+xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // TwoFirstLetterHeaders - POST /operation-two-first-letter-headers + hyper::Method::POST if path.matched(paths::ID_OPERATION_TWO_FIRST_LETTER_HEADERS) => { + // Header parameters + let param_x_header_one = headers.get(HeaderName::from_static("x-header-one")); + + let param_x_header_one = match param_x_header_one { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header x-header-one - {err}"))) + .expect("Unable to create Bad Request response for invalid header x-header-one")); + + }, + }, + None => { + None + } + }; + let param_x_header_two = headers.get(HeaderName::from_static("x-header-two")); + + let param_x_header_two = match param_x_header_two { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header x-header-two - {err}"))) + .expect("Unable to create Bad Request response for invalid header x-header-two")); + + }, + }, + None => { + None + } + }; + + let result = api_impl.two_first_letter_headers( + param_x_header_one, + param_x_header_two, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + TwoFirstLetterHeadersResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // UntypedPropertyGet - GET /untyped_property + hyper::Method::GET if path.matched(paths::ID_UNTYPED_PROPERTY) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_object_untyped_props: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_object_untyped_props) => param_object_untyped_props, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.untyped_property_get( + param_object_untyped_props, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + UntypedPropertyGetResponse::CheckThatUntypedPropertiesWorks + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // UuidGet - GET /uuid + hyper::Method::GET if path.matched(paths::ID_UUID) => { + let result = api_impl.uuid_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + UuidGetResponse::DuplicateResponseLongText + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // XmlExtraPost - POST /xml_extra + hyper::Method::POST if path.matched(paths::ID_XML_EXTRA) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_duplicate_xml_object: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_duplicate_xml_object) => param_duplicate_xml_object, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.xml_extra_post( + param_duplicate_xml_object, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + XmlExtraPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + XmlExtraPostResponse::BadRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // XmlOtherPost - POST /xml_other + hyper::Method::POST if path.matched(paths::ID_XML_OTHER) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_another_xml_object: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_another_xml_object) => param_another_xml_object, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.xml_other_post( + param_another_xml_object, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + XmlOtherPostResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("text/xml") + .expect("Unable to create Content-Type header for text/xml")); + // XML Body + let mut namespaces = std::collections::BTreeMap::new(); + + // An empty string is used to indicate a global namespace in xmltree. + namespaces.insert("".to_string(), models::AnotherXmlObject::NAMESPACE.to_string()); + let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + XmlOtherPostResponse::BadRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // XmlOtherPut - PUT /xml_other + hyper::Method::PUT if path.matched(paths::ID_XML_OTHER) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_another_xml_array: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_another_xml_array) => param_another_xml_array, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.xml_other_put( + param_another_xml_array, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + XmlOtherPutResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + XmlOtherPutResponse::BadRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // XmlPost - POST /xml + hyper::Method::POST if path.matched(paths::ID_XML) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_xml_array: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_xml_array) => param_xml_array, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.xml_post( + param_xml_array, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + XmlPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + XmlPostResponse::BadRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // XmlPut - PUT /xml + hyper::Method::PUT if path.matched(paths::ID_XML) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_xml_object: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_xml_object) => param_xml_object, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.xml_put( + param_xml_object, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + XmlPutResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + XmlPutResponse::BadRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // EnumInPathPathParamGet - GET /enum_in_path/{path_param} + hyper::Method::GET if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_ENUM_IN_PATH_PATH_PARAM + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE ENUM_IN_PATH_PATH_PARAM in set but failed match against \"{}\"", path, paths::REGEX_ENUM_IN_PATH_PATH_PARAM.as_str()) + ); + + let param_path_param = match percent_encoding::percent_decode(path_params["path_param"].as_bytes()).decode_utf8() { + Ok(param_path_param) => match param_path_param.parse::() { + Ok(param_path_param) => param_path_param, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter path_param: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.enum_in_path_path_param_get( + param_path_param, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + EnumInPathPathParamGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet - GET /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b} + hyper::Method::GET if path.matched(paths::ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B in set but failed match against \"{}\"", path, paths::REGEX_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B.as_str()) + ); + + let param_path_param_a = match percent_encoding::percent_decode(path_params["path_param_a"].as_bytes()).decode_utf8() { + Ok(param_path_param_a) => match param_path_param_a.parse::() { + Ok(param_path_param_a) => param_path_param_a, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter path_param_a: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_a"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let param_path_param_b = match percent_encoding::percent_decode(path_params["path_param_b"].as_bytes()).decode_utf8() { + Ok(param_path_param_b) => match param_path_param_b.parse::() { + Ok(param_path_param_b) => param_path_param_b, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter path_param_b: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_b"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( + param_path_param_a, + param_path_param_b, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // CreateRepo - POST /repos + hyper::Method::POST if path.matched(paths::ID_REPOS) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_object_param: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_object_param) => param_object_param, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter ObjectParam - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter ObjectParam due to schema")), + } + } else { + None + }; + let param_object_param = match param_object_param { + Some(param_object_param) => param_object_param, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter ObjectParam")) + .expect("Unable to create Bad Request response for missing body parameter ObjectParam")), + }; + + + let result = api_impl.create_repo( + param_object_param, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + CreateRepoResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // GetRepoInfo - GET /repos/{repoId} + hyper::Method::GET if path.matched(paths::ID_REPOS_REPOID) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_REPOS_REPOID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE REPOS_REPOID in set but failed match against \"{}\"", path, paths::REGEX_REPOS_REPOID.as_str()) + ); + + let param_repo_id = match percent_encoding::percent_decode(path_params["repoId"].as_bytes()).decode_utf8() { + Ok(param_repo_id) => match param_repo_id.parse::() { + Ok(param_repo_id) => param_repo_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter repoId: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["repoId"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.get_repo_info( + param_repo_id, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetRepoInfoResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + _ if path.matched(paths::ID_ANY_OF) => method_not_allowed(), + _ if path.matched(paths::ID_CALLBACK_WITH_HEADER) => method_not_allowed(), + _ if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => method_not_allowed(), + _ if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => method_not_allowed(), + _ if path.matched(paths::ID_EXAMPLES_TEST) => method_not_allowed(), + _ if path.matched(paths::ID_FORM_TEST) => method_not_allowed(), + _ if path.matched(paths::ID_GET_WITH_BOOL) => method_not_allowed(), + _ if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => method_not_allowed(), + _ if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => method_not_allowed(), + _ if path.matched(paths::ID_MERGE_PATCH_JSON) => method_not_allowed(), + _ if path.matched(paths::ID_MULTIGET) => method_not_allowed(), + _ if path.matched(paths::ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B) => method_not_allowed(), + _ if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => method_not_allowed(), + _ if path.matched(paths::ID_ONE_OF) => method_not_allowed(), + _ if path.matched(paths::ID_OPERATION_TWO_FIRST_LETTER_HEADERS) => method_not_allowed(), + _ if path.matched(paths::ID_OVERRIDE_SERVER) => method_not_allowed(), + _ if path.matched(paths::ID_PARAMGET) => method_not_allowed(), + _ if path.matched(paths::ID_READONLY_AUTH_SCHEME) => method_not_allowed(), + _ if path.matched(paths::ID_REGISTER_CALLBACK) => method_not_allowed(), + _ if path.matched(paths::ID_REPOS) => method_not_allowed(), + _ if path.matched(paths::ID_REPOS_REPOID) => method_not_allowed(), + _ if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => method_not_allowed(), + _ if path.matched(paths::ID_RESPONSES_WITH_HEADERS) => method_not_allowed(), + _ if path.matched(paths::ID_RFC7807) => method_not_allowed(), + _ if path.matched(paths::ID_UNTYPED_PROPERTY) => method_not_allowed(), + _ if path.matched(paths::ID_UUID) => method_not_allowed(), + _ if path.matched(paths::ID_XML) => method_not_allowed(), + _ if path.matched(paths::ID_XML_EXTRA) => method_not_allowed(), + _ if path.matched(paths::ID_XML_OTHER) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // AnyOfGet - GET /any-of + hyper::Method::GET if path.matched(paths::ID_ANY_OF) => Some("AnyOfGet"), + // CallbackWithHeaderPost - POST /callback-with-header + hyper::Method::POST if path.matched(paths::ID_CALLBACK_WITH_HEADER) => Some("CallbackWithHeaderPost"), + // ComplexQueryParamGet - GET /complex-query-param + hyper::Method::GET if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => Some("ComplexQueryParamGet"), + // ExamplesTest - GET /examples-test + hyper::Method::GET if path.matched(paths::ID_EXAMPLES_TEST) => Some("ExamplesTest"), + // FormTest - POST /form-test + hyper::Method::POST if path.matched(paths::ID_FORM_TEST) => Some("FormTest"), + // GetWithBooleanParameter - GET /get-with-bool + hyper::Method::GET if path.matched(paths::ID_GET_WITH_BOOL) => Some("GetWithBooleanParameter"), + // JsonComplexQueryParamGet - GET /json-complex-query-param + hyper::Method::GET if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => Some("JsonComplexQueryParamGet"), + // MandatoryRequestHeaderGet - GET /mandatory-request-header + hyper::Method::GET if path.matched(paths::ID_MANDATORY_REQUEST_HEADER) => Some("MandatoryRequestHeaderGet"), + // MergePatchJsonGet - GET /merge-patch-json + hyper::Method::GET if path.matched(paths::ID_MERGE_PATCH_JSON) => Some("MergePatchJsonGet"), + // MultigetGet - GET /multiget + hyper::Method::GET if path.matched(paths::ID_MULTIGET) => Some("MultigetGet"), + // MultipleAuthSchemeGet - GET /multiple_auth_scheme + hyper::Method::GET if path.matched(paths::ID_MULTIPLE_AUTH_SCHEME) => Some("MultipleAuthSchemeGet"), + // OneOfGet - GET /one-of + hyper::Method::GET if path.matched(paths::ID_ONE_OF) => Some("OneOfGet"), + // OverrideServerGet - GET /override-server + hyper::Method::GET if path.matched(paths::ID_OVERRIDE_SERVER) => Some("OverrideServerGet"), + // ParamgetGet - GET /paramget + hyper::Method::GET if path.matched(paths::ID_PARAMGET) => Some("ParamgetGet"), + // ReadonlyAuthSchemeGet - GET /readonly_auth_scheme + hyper::Method::GET if path.matched(paths::ID_READONLY_AUTH_SCHEME) => Some("ReadonlyAuthSchemeGet"), + // RegisterCallbackPost - POST /register-callback + hyper::Method::POST if path.matched(paths::ID_REGISTER_CALLBACK) => Some("RegisterCallbackPost"), + // RequiredOctetStreamPut - PUT /required_octet_stream + hyper::Method::PUT if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => Some("RequiredOctetStreamPut"), + // ResponsesWithHeadersGet - GET /responses_with_headers + hyper::Method::GET if path.matched(paths::ID_RESPONSES_WITH_HEADERS) => Some("ResponsesWithHeadersGet"), + // Rfc7807Get - GET /rfc7807 + hyper::Method::GET if path.matched(paths::ID_RFC7807) => Some("Rfc7807Get"), + // TwoFirstLetterHeaders - POST /operation-two-first-letter-headers + hyper::Method::POST if path.matched(paths::ID_OPERATION_TWO_FIRST_LETTER_HEADERS) => Some("TwoFirstLetterHeaders"), + // UntypedPropertyGet - GET /untyped_property + hyper::Method::GET if path.matched(paths::ID_UNTYPED_PROPERTY) => Some("UntypedPropertyGet"), + // UuidGet - GET /uuid + hyper::Method::GET if path.matched(paths::ID_UUID) => Some("UuidGet"), + // XmlExtraPost - POST /xml_extra + hyper::Method::POST if path.matched(paths::ID_XML_EXTRA) => Some("XmlExtraPost"), + // XmlOtherPost - POST /xml_other + hyper::Method::POST if path.matched(paths::ID_XML_OTHER) => Some("XmlOtherPost"), + // XmlOtherPut - PUT /xml_other + hyper::Method::PUT if path.matched(paths::ID_XML_OTHER) => Some("XmlOtherPut"), + // XmlPost - POST /xml + hyper::Method::POST if path.matched(paths::ID_XML) => Some("XmlPost"), + // XmlPut - PUT /xml + hyper::Method::PUT if path.matched(paths::ID_XML) => Some("XmlPut"), + // EnumInPathPathParamGet - GET /enum_in_path/{path_param} + hyper::Method::GET if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => Some("EnumInPathPathParamGet"), + // MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet - GET /multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b} + hyper::Method::GET if path.matched(paths::ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B) => Some("MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet"), + // CreateRepo - POST /repos + hyper::Method::POST if path.matched(paths::ID_REPOS) => Some("CreateRepo"), + // GetRepoInfo - GET /repos/{repoId} + hyper::Method::GET if path.matched(paths::ID_REPOS_REPOID) => Some("GetRepoInfo"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/ops-v3/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/ops-v3/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/ops-v3/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/.gitignore b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/FILES new file mode 100644 index 000000000000..ce2109b1de2e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/FILES @@ -0,0 +1,23 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/default_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/ops-v3/Cargo.toml new file mode 100644 index 000000000000..0c33be7b5ea2 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/Cargo.toml @@ -0,0 +1,96 @@ +[package] +name = "ops-v3" +version = "0.0.1" +authors = ["OpenAPI Generator team and contributors"] +description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "ops-v3" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/README.md b/samples/server/petstore/rust-server-deprecated/output/ops-v3/README.md new file mode 100644 index 000000000000..4cb3f226baed --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/README.md @@ -0,0 +1,211 @@ +# Rust API for ops-v3 + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +## Overview + +This client/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: 0.0.1 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `ops-v3` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `ops-v3`: + +* The example server starts up a web server using the `ops-v3` + router, and supplies a trivial implementation of `Api` which returns failure + for every operation. +* The example client provides a CLI which lets you invoke + any single operation on the `ops-v3` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client Op10Get +cargo run --example client Op11Get +cargo run --example client Op12Get +cargo run --example client Op13Get +cargo run --example client Op14Get +cargo run --example client Op15Get +cargo run --example client Op16Get +cargo run --example client Op17Get +cargo run --example client Op18Get +cargo run --example client Op19Get +cargo run --example client Op1Get +cargo run --example client Op20Get +cargo run --example client Op21Get +cargo run --example client Op22Get +cargo run --example client Op23Get +cargo run --example client Op24Get +cargo run --example client Op25Get +cargo run --example client Op26Get +cargo run --example client Op27Get +cargo run --example client Op28Get +cargo run --example client Op29Get +cargo run --example client Op2Get +cargo run --example client Op30Get +cargo run --example client Op31Get +cargo run --example client Op32Get +cargo run --example client Op33Get +cargo run --example client Op34Get +cargo run --example client Op35Get +cargo run --example client Op36Get +cargo run --example client Op37Get +cargo run --example client Op3Get +cargo run --example client Op4Get +cargo run --example client Op5Get +cargo run --example client Op6Get +cargo run --example client Op7Get +cargo run --example client Op8Get +cargo run --example client Op9Get +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[****](docs/default_api.md#) | **GET** /op10 | +[****](docs/default_api.md#) | **GET** /op11 | +[****](docs/default_api.md#) | **GET** /op12 | +[****](docs/default_api.md#) | **GET** /op13 | +[****](docs/default_api.md#) | **GET** /op14 | +[****](docs/default_api.md#) | **GET** /op15 | +[****](docs/default_api.md#) | **GET** /op16 | +[****](docs/default_api.md#) | **GET** /op17 | +[****](docs/default_api.md#) | **GET** /op18 | +[****](docs/default_api.md#) | **GET** /op19 | +[****](docs/default_api.md#) | **GET** /op1 | +[****](docs/default_api.md#) | **GET** /op20 | +[****](docs/default_api.md#) | **GET** /op21 | +[****](docs/default_api.md#) | **GET** /op22 | +[****](docs/default_api.md#) | **GET** /op23 | +[****](docs/default_api.md#) | **GET** /op24 | +[****](docs/default_api.md#) | **GET** /op25 | +[****](docs/default_api.md#) | **GET** /op26 | +[****](docs/default_api.md#) | **GET** /op27 | +[****](docs/default_api.md#) | **GET** /op28 | +[****](docs/default_api.md#) | **GET** /op29 | +[****](docs/default_api.md#) | **GET** /op2 | +[****](docs/default_api.md#) | **GET** /op30 | +[****](docs/default_api.md#) | **GET** /op31 | +[****](docs/default_api.md#) | **GET** /op32 | +[****](docs/default_api.md#) | **GET** /op33 | +[****](docs/default_api.md#) | **GET** /op34 | +[****](docs/default_api.md#) | **GET** /op35 | +[****](docs/default_api.md#) | **GET** /op36 | +[****](docs/default_api.md#) | **GET** /op37 | +[****](docs/default_api.md#) | **GET** /op3 | +[****](docs/default_api.md#) | **GET** /op4 | +[****](docs/default_api.md#) | **GET** /op5 | +[****](docs/default_api.md#) | **GET** /op6 | +[****](docs/default_api.md#) | **GET** /op7 | +[****](docs/default_api.md#) | **GET** /op8 | +[****](docs/default_api.md#) | **GET** /op9 | + + +## Documentation For Models + + + +## Documentation For Authorization +Endpoints do not require authorization. + + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/ops-v3/api/openapi.yaml new file mode 100644 index 000000000000..c0129798aa6d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/api/openapi.yaml @@ -0,0 +1,195 @@ +openapi: 3.0.1 +info: + title: Regression test for large number of operations + version: 0.0.1 +servers: +- url: / +paths: + /op1: + get: + responses: + "200": + description: OK + /op2: + get: + responses: + "200": + description: OK + /op3: + get: + responses: + "200": + description: OK + /op4: + get: + responses: + "200": + description: OK + /op5: + get: + responses: + "200": + description: OK + /op6: + get: + responses: + "200": + description: OK + /op7: + get: + responses: + "200": + description: OK + /op8: + get: + responses: + "200": + description: OK + /op9: + get: + responses: + "200": + description: OK + /op10: + get: + responses: + "200": + description: OK + /op11: + get: + responses: + "200": + description: OK + /op12: + get: + responses: + "200": + description: OK + /op13: + get: + responses: + "200": + description: OK + /op14: + get: + responses: + "200": + description: OK + /op15: + get: + responses: + "200": + description: OK + /op16: + get: + responses: + "200": + description: OK + /op17: + get: + responses: + "200": + description: OK + /op18: + get: + responses: + "200": + description: OK + /op19: + get: + responses: + "200": + description: OK + /op20: + get: + responses: + "200": + description: OK + /op21: + get: + responses: + "200": + description: OK + /op22: + get: + responses: + "200": + description: OK + /op23: + get: + responses: + "200": + description: OK + /op24: + get: + responses: + "200": + description: OK + /op25: + get: + responses: + "200": + description: OK + /op26: + get: + responses: + "200": + description: OK + /op27: + get: + responses: + "200": + description: OK + /op28: + get: + responses: + "200": + description: OK + /op29: + get: + responses: + "200": + description: OK + /op30: + get: + responses: + "200": + description: OK + /op31: + get: + responses: + "200": + description: OK + /op32: + get: + responses: + "200": + description: OK + /op33: + get: + responses: + "200": + description: OK + /op34: + get: + responses: + "200": + description: OK + /op35: + get: + responses: + "200": + description: OK + /op36: + get: + responses: + "200": + description: OK + /op37: + get: + responses: + "200": + description: OK +components: + schemas: {} + diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/bin/cli.rs new file mode 100644 index 000000000000..39f3ad4646cd --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/bin/cli.rs @@ -0,0 +1,759 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use ops_v3::{ + models, ApiNoContext, Client, ContextWrapperExt, + Op10GetResponse, + Op11GetResponse, + Op12GetResponse, + Op13GetResponse, + Op14GetResponse, + Op15GetResponse, + Op16GetResponse, + Op17GetResponse, + Op18GetResponse, + Op19GetResponse, + Op1GetResponse, + Op20GetResponse, + Op21GetResponse, + Op22GetResponse, + Op23GetResponse, + Op24GetResponse, + Op25GetResponse, + Op26GetResponse, + Op27GetResponse, + Op28GetResponse, + Op29GetResponse, + Op2GetResponse, + Op30GetResponse, + Op31GetResponse, + Op32GetResponse, + Op33GetResponse, + Op34GetResponse, + Op35GetResponse, + Op36GetResponse, + Op37GetResponse, + Op3GetResponse, + Op4GetResponse, + Op5GetResponse, + Op6GetResponse, + Op7GetResponse, + Op8GetResponse, + Op9GetResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "Regression test for large number of operations", + version = "0.0.1", + about = "CLI access to Regression test for large number of operations" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, +} + +#[derive(StructOpt, Debug)] +enum Operation { + Op10Get { + }, + Op11Get { + }, + Op12Get { + }, + Op13Get { + }, + Op14Get { + }, + Op15Get { + }, + Op16Get { + }, + Op17Get { + }, + Op18Get { + }, + Op19Get { + }, + Op1Get { + }, + Op20Get { + }, + Op21Get { + }, + Op22Get { + }, + Op23Get { + }, + Op24Get { + }, + Op25Get { + }, + Op26Get { + }, + Op27Get { + }, + Op28Get { + }, + Op29Get { + }, + Op2Get { + }, + Op30Get { + }, + Op31Get { + }, + Op32Get { + }, + Op33Get { + }, + Op34Get { + }, + Op35Get { + }, + Op36Get { + }, + Op37Get { + }, + Op3Get { + }, + Op4Get { + }, + Op5Get { + }, + Op6Get { + }, + Op7Get { + }, + Op8Get { + }, + Op9Get { + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let auth_data: Option = None; + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::Op10Get { + } => { + info!("Performing a Op10Get request"); + + let result = client.op10_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op10GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op11Get { + } => { + info!("Performing a Op11Get request"); + + let result = client.op11_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op11GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op12Get { + } => { + info!("Performing a Op12Get request"); + + let result = client.op12_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op12GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op13Get { + } => { + info!("Performing a Op13Get request"); + + let result = client.op13_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op13GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op14Get { + } => { + info!("Performing a Op14Get request"); + + let result = client.op14_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op14GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op15Get { + } => { + info!("Performing a Op15Get request"); + + let result = client.op15_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op15GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op16Get { + } => { + info!("Performing a Op16Get request"); + + let result = client.op16_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op16GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op17Get { + } => { + info!("Performing a Op17Get request"); + + let result = client.op17_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op17GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op18Get { + } => { + info!("Performing a Op18Get request"); + + let result = client.op18_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op18GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op19Get { + } => { + info!("Performing a Op19Get request"); + + let result = client.op19_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op19GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op1Get { + } => { + info!("Performing a Op1Get request"); + + let result = client.op1_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op1GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op20Get { + } => { + info!("Performing a Op20Get request"); + + let result = client.op20_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op20GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op21Get { + } => { + info!("Performing a Op21Get request"); + + let result = client.op21_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op21GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op22Get { + } => { + info!("Performing a Op22Get request"); + + let result = client.op22_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op22GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op23Get { + } => { + info!("Performing a Op23Get request"); + + let result = client.op23_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op23GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op24Get { + } => { + info!("Performing a Op24Get request"); + + let result = client.op24_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op24GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op25Get { + } => { + info!("Performing a Op25Get request"); + + let result = client.op25_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op25GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op26Get { + } => { + info!("Performing a Op26Get request"); + + let result = client.op26_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op26GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op27Get { + } => { + info!("Performing a Op27Get request"); + + let result = client.op27_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op27GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op28Get { + } => { + info!("Performing a Op28Get request"); + + let result = client.op28_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op28GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op29Get { + } => { + info!("Performing a Op29Get request"); + + let result = client.op29_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op29GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op2Get { + } => { + info!("Performing a Op2Get request"); + + let result = client.op2_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op2GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op30Get { + } => { + info!("Performing a Op30Get request"); + + let result = client.op30_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op30GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op31Get { + } => { + info!("Performing a Op31Get request"); + + let result = client.op31_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op31GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op32Get { + } => { + info!("Performing a Op32Get request"); + + let result = client.op32_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op32GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op33Get { + } => { + info!("Performing a Op33Get request"); + + let result = client.op33_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op33GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op34Get { + } => { + info!("Performing a Op34Get request"); + + let result = client.op34_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op34GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op35Get { + } => { + info!("Performing a Op35Get request"); + + let result = client.op35_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op35GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op36Get { + } => { + info!("Performing a Op36Get request"); + + let result = client.op36_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op36GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op37Get { + } => { + info!("Performing a Op37Get request"); + + let result = client.op37_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op37GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op3Get { + } => { + info!("Performing a Op3Get request"); + + let result = client.op3_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op3GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op4Get { + } => { + info!("Performing a Op4Get request"); + + let result = client.op4_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op4GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op5Get { + } => { + info!("Performing a Op5Get request"); + + let result = client.op5_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op5GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op6Get { + } => { + info!("Performing a Op6Get request"); + + let result = client.op6_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op6GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op7Get { + } => { + info!("Performing a Op7Get request"); + + let result = client.op7_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op7GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op8Get { + } => { + info!("Performing a Op8Get request"); + + let result = client.op8_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op8GetResponse::OK + => "OK\n".to_string() + , + } + } + Operation::Op9Get { + } => { + info!("Performing a Op9Get request"); + + let result = client.op9_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + Op9GetResponse::OK + => "OK\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/ops-v3/docs/default_api.md new file mode 100644 index 000000000000..c76b59cefd39 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/docs/default_api.md @@ -0,0 +1,859 @@ +# default_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +****](default_api.md#) | **GET** /op10 | +****](default_api.md#) | **GET** /op11 | +****](default_api.md#) | **GET** /op12 | +****](default_api.md#) | **GET** /op13 | +****](default_api.md#) | **GET** /op14 | +****](default_api.md#) | **GET** /op15 | +****](default_api.md#) | **GET** /op16 | +****](default_api.md#) | **GET** /op17 | +****](default_api.md#) | **GET** /op18 | +****](default_api.md#) | **GET** /op19 | +****](default_api.md#) | **GET** /op1 | +****](default_api.md#) | **GET** /op20 | +****](default_api.md#) | **GET** /op21 | +****](default_api.md#) | **GET** /op22 | +****](default_api.md#) | **GET** /op23 | +****](default_api.md#) | **GET** /op24 | +****](default_api.md#) | **GET** /op25 | +****](default_api.md#) | **GET** /op26 | +****](default_api.md#) | **GET** /op27 | +****](default_api.md#) | **GET** /op28 | +****](default_api.md#) | **GET** /op29 | +****](default_api.md#) | **GET** /op2 | +****](default_api.md#) | **GET** /op30 | +****](default_api.md#) | **GET** /op31 | +****](default_api.md#) | **GET** /op32 | +****](default_api.md#) | **GET** /op33 | +****](default_api.md#) | **GET** /op34 | +****](default_api.md#) | **GET** /op35 | +****](default_api.md#) | **GET** /op36 | +****](default_api.md#) | **GET** /op37 | +****](default_api.md#) | **GET** /op3 | +****](default_api.md#) | **GET** /op4 | +****](default_api.md#) | **GET** /op5 | +****](default_api.md#) | **GET** /op6 | +****](default_api.md#) | **GET** /op7 | +****](default_api.md#) | **GET** /op8 | +****](default_api.md#) | **GET** /op9 | + + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **** +> () + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/client_auth.rs new file mode 100644 index 000000000000..3d5200a26bec --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use ops_v3::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/main.rs new file mode 100644 index 000000000000..9d9bfc6d9589 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/client/main.rs @@ -0,0 +1,367 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use ops_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + Op10GetResponse, + Op11GetResponse, + Op12GetResponse, + Op13GetResponse, + Op14GetResponse, + Op15GetResponse, + Op16GetResponse, + Op17GetResponse, + Op18GetResponse, + Op19GetResponse, + Op1GetResponse, + Op20GetResponse, + Op21GetResponse, + Op22GetResponse, + Op23GetResponse, + Op24GetResponse, + Op25GetResponse, + Op26GetResponse, + Op27GetResponse, + Op28GetResponse, + Op29GetResponse, + Op2GetResponse, + Op30GetResponse, + Op31GetResponse, + Op32GetResponse, + Op33GetResponse, + Op34GetResponse, + Op35GetResponse, + Op36GetResponse, + Op37GetResponse, + Op3GetResponse, + Op4GetResponse, + Op5GetResponse, + Op6GetResponse, + Op7GetResponse, + Op8GetResponse, + Op9GetResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "Op10Get", + "Op11Get", + "Op12Get", + "Op13Get", + "Op14Get", + "Op15Get", + "Op16Get", + "Op17Get", + "Op18Get", + "Op19Get", + "Op1Get", + "Op20Get", + "Op21Get", + "Op22Get", + "Op23Get", + "Op24Get", + "Op25Get", + "Op26Get", + "Op27Get", + "Op28Get", + "Op29Get", + "Op2Get", + "Op30Get", + "Op31Get", + "Op32Get", + "Op33Get", + "Op34Get", + "Op35Get", + "Op36Get", + "Op37Get", + "Op3Get", + "Op4Get", + "Op5Get", + "Op6Get", + "Op7Get", + "Op8Get", + "Op9Get", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + "".to_owned() + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + Some("Op10Get") => { + let result = rt.block_on(client.op10_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op11Get") => { + let result = rt.block_on(client.op11_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op12Get") => { + let result = rt.block_on(client.op12_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op13Get") => { + let result = rt.block_on(client.op13_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op14Get") => { + let result = rt.block_on(client.op14_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op15Get") => { + let result = rt.block_on(client.op15_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op16Get") => { + let result = rt.block_on(client.op16_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op17Get") => { + let result = rt.block_on(client.op17_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op18Get") => { + let result = rt.block_on(client.op18_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op19Get") => { + let result = rt.block_on(client.op19_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op1Get") => { + let result = rt.block_on(client.op1_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op20Get") => { + let result = rt.block_on(client.op20_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op21Get") => { + let result = rt.block_on(client.op21_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op22Get") => { + let result = rt.block_on(client.op22_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op23Get") => { + let result = rt.block_on(client.op23_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op24Get") => { + let result = rt.block_on(client.op24_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op25Get") => { + let result = rt.block_on(client.op25_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op26Get") => { + let result = rt.block_on(client.op26_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op27Get") => { + let result = rt.block_on(client.op27_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op28Get") => { + let result = rt.block_on(client.op28_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op29Get") => { + let result = rt.block_on(client.op29_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op2Get") => { + let result = rt.block_on(client.op2_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op30Get") => { + let result = rt.block_on(client.op30_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op31Get") => { + let result = rt.block_on(client.op31_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op32Get") => { + let result = rt.block_on(client.op32_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op33Get") => { + let result = rt.block_on(client.op33_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op34Get") => { + let result = rt.block_on(client.op34_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op35Get") => { + let result = rt.block_on(client.op35_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op36Get") => { + let result = rt.block_on(client.op36_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op37Get") => { + let result = rt.block_on(client.op37_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op3Get") => { + let result = rt.block_on(client.op3_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op4Get") => { + let result = rt.block_on(client.op4_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op5Get") => { + let result = rt.block_on(client.op5_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op6Get") => { + let result = rt.block_on(client.op6_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op7Get") => { + let result = rt.block_on(client.op7_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op8Get") => { + let result = rt.block_on(client.op8_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("Op9Get") => { + let result = rt.block_on(client.op9_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/main.rs new file mode 100644 index 000000000000..227fe7e73155 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for ops_v3 implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server.rs new file mode 100644 index 000000000000..d51ecdd70289 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server.rs @@ -0,0 +1,446 @@ +//! Main library entry point for ops_v3 implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use ops_v3::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + ops_v3::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use ops_v3::{ + Api, + Op10GetResponse, + Op11GetResponse, + Op12GetResponse, + Op13GetResponse, + Op14GetResponse, + Op15GetResponse, + Op16GetResponse, + Op17GetResponse, + Op18GetResponse, + Op19GetResponse, + Op1GetResponse, + Op20GetResponse, + Op21GetResponse, + Op22GetResponse, + Op23GetResponse, + Op24GetResponse, + Op25GetResponse, + Op26GetResponse, + Op27GetResponse, + Op28GetResponse, + Op29GetResponse, + Op2GetResponse, + Op30GetResponse, + Op31GetResponse, + Op32GetResponse, + Op33GetResponse, + Op34GetResponse, + Op35GetResponse, + Op36GetResponse, + Op37GetResponse, + Op3GetResponse, + Op4GetResponse, + Op5GetResponse, + Op6GetResponse, + Op7GetResponse, + Op8GetResponse, + Op9GetResponse, +}; +use ops_v3::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn op10_get( + &self, + context: &C) -> Result + { + info!("op10_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op11_get( + &self, + context: &C) -> Result + { + info!("op11_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op12_get( + &self, + context: &C) -> Result + { + info!("op12_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op13_get( + &self, + context: &C) -> Result + { + info!("op13_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op14_get( + &self, + context: &C) -> Result + { + info!("op14_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op15_get( + &self, + context: &C) -> Result + { + info!("op15_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op16_get( + &self, + context: &C) -> Result + { + info!("op16_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op17_get( + &self, + context: &C) -> Result + { + info!("op17_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op18_get( + &self, + context: &C) -> Result + { + info!("op18_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op19_get( + &self, + context: &C) -> Result + { + info!("op19_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op1_get( + &self, + context: &C) -> Result + { + info!("op1_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op20_get( + &self, + context: &C) -> Result + { + info!("op20_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op21_get( + &self, + context: &C) -> Result + { + info!("op21_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op22_get( + &self, + context: &C) -> Result + { + info!("op22_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op23_get( + &self, + context: &C) -> Result + { + info!("op23_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op24_get( + &self, + context: &C) -> Result + { + info!("op24_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op25_get( + &self, + context: &C) -> Result + { + info!("op25_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op26_get( + &self, + context: &C) -> Result + { + info!("op26_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op27_get( + &self, + context: &C) -> Result + { + info!("op27_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op28_get( + &self, + context: &C) -> Result + { + info!("op28_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op29_get( + &self, + context: &C) -> Result + { + info!("op29_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op2_get( + &self, + context: &C) -> Result + { + info!("op2_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op30_get( + &self, + context: &C) -> Result + { + info!("op30_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op31_get( + &self, + context: &C) -> Result + { + info!("op31_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op32_get( + &self, + context: &C) -> Result + { + info!("op32_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op33_get( + &self, + context: &C) -> Result + { + info!("op33_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op34_get( + &self, + context: &C) -> Result + { + info!("op34_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op35_get( + &self, + context: &C) -> Result + { + info!("op35_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op36_get( + &self, + context: &C) -> Result + { + info!("op36_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op37_get( + &self, + context: &C) -> Result + { + info!("op37_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op3_get( + &self, + context: &C) -> Result + { + info!("op3_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op4_get( + &self, + context: &C) -> Result + { + info!("op4_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op5_get( + &self, + context: &C) -> Result + { + info!("op5_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op6_get( + &self, + context: &C) -> Result + { + info!("op6_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op7_get( + &self, + context: &C) -> Result + { + info!("op7_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op8_get( + &self, + context: &C) -> Result + { + info!("op8_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn op9_get( + &self, + context: &C) -> Result + { + info!("op9_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server_auth.rs new file mode 100644 index 000000000000..19eb6c6add4a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/examples/server/server_auth.rs @@ -0,0 +1,127 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use ops_v3::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + "".to_owned() + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/client/mod.rs new file mode 100644 index 000000000000..683cc4d7c3e6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/client/mod.rs @@ -0,0 +1,2900 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + Op10GetResponse, + Op11GetResponse, + Op12GetResponse, + Op13GetResponse, + Op14GetResponse, + Op15GetResponse, + Op16GetResponse, + Op17GetResponse, + Op18GetResponse, + Op19GetResponse, + Op1GetResponse, + Op20GetResponse, + Op21GetResponse, + Op22GetResponse, + Op23GetResponse, + Op24GetResponse, + Op25GetResponse, + Op26GetResponse, + Op27GetResponse, + Op28GetResponse, + Op29GetResponse, + Op2GetResponse, + Op30GetResponse, + Op31GetResponse, + Op32GetResponse, + Op33GetResponse, + Op34GetResponse, + Op35GetResponse, + Op36GetResponse, + Op37GetResponse, + Op3GetResponse, + Op4GetResponse, + Op5GetResponse, + Op6GetResponse, + Op7GetResponse, + Op8GetResponse, + Op9GetResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn op10_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op10", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op10GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op11_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op11", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op11GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op12_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op12", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op12GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op13_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op13", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op13GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op14_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op14", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op14GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op15_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op15", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op15GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op16_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op16", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op16GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op17_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op17", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op17GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op18_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op18", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op18GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op19_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op19", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op19GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op1_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op1", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op1GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op20_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op20", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op20GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op21_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op21", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op21GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op22_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op22", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op22GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op23_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op23", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op23GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op24_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op24", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op24GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op25_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op25", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op25GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op26_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op26", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op26GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op27_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op27", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op27GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op28_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op28", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op28GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op29_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op29", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op29GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op2_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op2", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op2GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op30_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op30", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op30GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op31_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op31", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op31GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op32_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op32", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op32GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op33_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op33", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op33GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op34_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op34", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op34GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op35_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op35", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op35GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op36_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op36", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op36GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op37_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op37", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op37GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op3_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op3", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op3GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op4_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op4", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op4GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op5_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op5", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op5GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op6_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op6", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op6GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op7_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op7", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op7GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op8_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op8", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op8GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn op9_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/op9", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Op9GetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/context.rs new file mode 100644 index 000000000000..ee8e118587bb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/context.rs @@ -0,0 +1,114 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/lib.rs new file mode 100644 index 000000000000..866ce4e4654a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/lib.rs @@ -0,0 +1,904 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "0.0.1"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op10GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op11GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op12GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op13GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op14GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op15GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op16GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op17GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op18GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op19GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op1GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op20GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op21GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op22GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op23GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op24GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op25GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op26GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op27GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op28GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op29GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op2GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op30GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op31GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op32GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op33GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op34GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op35GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op36GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op37GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op3GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op4GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op5GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op6GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op7GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op8GetResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Op9GetResponse { + /// OK + OK +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn op10_get( + &self, + context: &C) -> Result; + + async fn op11_get( + &self, + context: &C) -> Result; + + async fn op12_get( + &self, + context: &C) -> Result; + + async fn op13_get( + &self, + context: &C) -> Result; + + async fn op14_get( + &self, + context: &C) -> Result; + + async fn op15_get( + &self, + context: &C) -> Result; + + async fn op16_get( + &self, + context: &C) -> Result; + + async fn op17_get( + &self, + context: &C) -> Result; + + async fn op18_get( + &self, + context: &C) -> Result; + + async fn op19_get( + &self, + context: &C) -> Result; + + async fn op1_get( + &self, + context: &C) -> Result; + + async fn op20_get( + &self, + context: &C) -> Result; + + async fn op21_get( + &self, + context: &C) -> Result; + + async fn op22_get( + &self, + context: &C) -> Result; + + async fn op23_get( + &self, + context: &C) -> Result; + + async fn op24_get( + &self, + context: &C) -> Result; + + async fn op25_get( + &self, + context: &C) -> Result; + + async fn op26_get( + &self, + context: &C) -> Result; + + async fn op27_get( + &self, + context: &C) -> Result; + + async fn op28_get( + &self, + context: &C) -> Result; + + async fn op29_get( + &self, + context: &C) -> Result; + + async fn op2_get( + &self, + context: &C) -> Result; + + async fn op30_get( + &self, + context: &C) -> Result; + + async fn op31_get( + &self, + context: &C) -> Result; + + async fn op32_get( + &self, + context: &C) -> Result; + + async fn op33_get( + &self, + context: &C) -> Result; + + async fn op34_get( + &self, + context: &C) -> Result; + + async fn op35_get( + &self, + context: &C) -> Result; + + async fn op36_get( + &self, + context: &C) -> Result; + + async fn op37_get( + &self, + context: &C) -> Result; + + async fn op3_get( + &self, + context: &C) -> Result; + + async fn op4_get( + &self, + context: &C) -> Result; + + async fn op5_get( + &self, + context: &C) -> Result; + + async fn op6_get( + &self, + context: &C) -> Result; + + async fn op7_get( + &self, + context: &C) -> Result; + + async fn op8_get( + &self, + context: &C) -> Result; + + async fn op9_get( + &self, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn op10_get( + &self, + ) -> Result; + + async fn op11_get( + &self, + ) -> Result; + + async fn op12_get( + &self, + ) -> Result; + + async fn op13_get( + &self, + ) -> Result; + + async fn op14_get( + &self, + ) -> Result; + + async fn op15_get( + &self, + ) -> Result; + + async fn op16_get( + &self, + ) -> Result; + + async fn op17_get( + &self, + ) -> Result; + + async fn op18_get( + &self, + ) -> Result; + + async fn op19_get( + &self, + ) -> Result; + + async fn op1_get( + &self, + ) -> Result; + + async fn op20_get( + &self, + ) -> Result; + + async fn op21_get( + &self, + ) -> Result; + + async fn op22_get( + &self, + ) -> Result; + + async fn op23_get( + &self, + ) -> Result; + + async fn op24_get( + &self, + ) -> Result; + + async fn op25_get( + &self, + ) -> Result; + + async fn op26_get( + &self, + ) -> Result; + + async fn op27_get( + &self, + ) -> Result; + + async fn op28_get( + &self, + ) -> Result; + + async fn op29_get( + &self, + ) -> Result; + + async fn op2_get( + &self, + ) -> Result; + + async fn op30_get( + &self, + ) -> Result; + + async fn op31_get( + &self, + ) -> Result; + + async fn op32_get( + &self, + ) -> Result; + + async fn op33_get( + &self, + ) -> Result; + + async fn op34_get( + &self, + ) -> Result; + + async fn op35_get( + &self, + ) -> Result; + + async fn op36_get( + &self, + ) -> Result; + + async fn op37_get( + &self, + ) -> Result; + + async fn op3_get( + &self, + ) -> Result; + + async fn op4_get( + &self, + ) -> Result; + + async fn op5_get( + &self, + ) -> Result; + + async fn op6_get( + &self, + ) -> Result; + + async fn op7_get( + &self, + ) -> Result; + + async fn op8_get( + &self, + ) -> Result; + + async fn op9_get( + &self, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn op10_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op10_get(&context).await + } + + async fn op11_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op11_get(&context).await + } + + async fn op12_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op12_get(&context).await + } + + async fn op13_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op13_get(&context).await + } + + async fn op14_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op14_get(&context).await + } + + async fn op15_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op15_get(&context).await + } + + async fn op16_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op16_get(&context).await + } + + async fn op17_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op17_get(&context).await + } + + async fn op18_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op18_get(&context).await + } + + async fn op19_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op19_get(&context).await + } + + async fn op1_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op1_get(&context).await + } + + async fn op20_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op20_get(&context).await + } + + async fn op21_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op21_get(&context).await + } + + async fn op22_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op22_get(&context).await + } + + async fn op23_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op23_get(&context).await + } + + async fn op24_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op24_get(&context).await + } + + async fn op25_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op25_get(&context).await + } + + async fn op26_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op26_get(&context).await + } + + async fn op27_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op27_get(&context).await + } + + async fn op28_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op28_get(&context).await + } + + async fn op29_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op29_get(&context).await + } + + async fn op2_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op2_get(&context).await + } + + async fn op30_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op30_get(&context).await + } + + async fn op31_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op31_get(&context).await + } + + async fn op32_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op32_get(&context).await + } + + async fn op33_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op33_get(&context).await + } + + async fn op34_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op34_get(&context).await + } + + async fn op35_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op35_get(&context).await + } + + async fn op36_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op36_get(&context).await + } + + async fn op37_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op37_get(&context).await + } + + async fn op3_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op3_get(&context).await + } + + async fn op4_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op4_get(&context).await + } + + async fn op5_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op5_get(&context).await + } + + async fn op6_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op6_get(&context).await + } + + async fn op7_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op7_get(&context).await + } + + async fn op8_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op8_get(&context).await + } + + async fn op9_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().op9_get(&context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/models.rs new file mode 100644 index 000000000000..d0763192cf7c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/models.rs @@ -0,0 +1,8 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/mod.rs new file mode 100644 index 000000000000..a0658a61ab85 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/mod.rs @@ -0,0 +1,1501 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + Op10GetResponse, + Op11GetResponse, + Op12GetResponse, + Op13GetResponse, + Op14GetResponse, + Op15GetResponse, + Op16GetResponse, + Op17GetResponse, + Op18GetResponse, + Op19GetResponse, + Op1GetResponse, + Op20GetResponse, + Op21GetResponse, + Op22GetResponse, + Op23GetResponse, + Op24GetResponse, + Op25GetResponse, + Op26GetResponse, + Op27GetResponse, + Op28GetResponse, + Op29GetResponse, + Op2GetResponse, + Op30GetResponse, + Op31GetResponse, + Op32GetResponse, + Op33GetResponse, + Op34GetResponse, + Op35GetResponse, + Op36GetResponse, + Op37GetResponse, + Op3GetResponse, + Op4GetResponse, + Op5GetResponse, + Op6GetResponse, + Op7GetResponse, + Op8GetResponse, + Op9GetResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/op1$", + r"^/op10$", + r"^/op11$", + r"^/op12$", + r"^/op13$", + r"^/op14$", + r"^/op15$", + r"^/op16$", + r"^/op17$", + r"^/op18$", + r"^/op19$", + r"^/op2$", + r"^/op20$", + r"^/op21$", + r"^/op22$", + r"^/op23$", + r"^/op24$", + r"^/op25$", + r"^/op26$", + r"^/op27$", + r"^/op28$", + r"^/op29$", + r"^/op3$", + r"^/op30$", + r"^/op31$", + r"^/op32$", + r"^/op33$", + r"^/op34$", + r"^/op35$", + r"^/op36$", + r"^/op37$", + r"^/op4$", + r"^/op5$", + r"^/op6$", + r"^/op7$", + r"^/op8$", + r"^/op9$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_OP1: usize = 0; + pub(crate) static ID_OP10: usize = 1; + pub(crate) static ID_OP11: usize = 2; + pub(crate) static ID_OP12: usize = 3; + pub(crate) static ID_OP13: usize = 4; + pub(crate) static ID_OP14: usize = 5; + pub(crate) static ID_OP15: usize = 6; + pub(crate) static ID_OP16: usize = 7; + pub(crate) static ID_OP17: usize = 8; + pub(crate) static ID_OP18: usize = 9; + pub(crate) static ID_OP19: usize = 10; + pub(crate) static ID_OP2: usize = 11; + pub(crate) static ID_OP20: usize = 12; + pub(crate) static ID_OP21: usize = 13; + pub(crate) static ID_OP22: usize = 14; + pub(crate) static ID_OP23: usize = 15; + pub(crate) static ID_OP24: usize = 16; + pub(crate) static ID_OP25: usize = 17; + pub(crate) static ID_OP26: usize = 18; + pub(crate) static ID_OP27: usize = 19; + pub(crate) static ID_OP28: usize = 20; + pub(crate) static ID_OP29: usize = 21; + pub(crate) static ID_OP3: usize = 22; + pub(crate) static ID_OP30: usize = 23; + pub(crate) static ID_OP31: usize = 24; + pub(crate) static ID_OP32: usize = 25; + pub(crate) static ID_OP33: usize = 26; + pub(crate) static ID_OP34: usize = 27; + pub(crate) static ID_OP35: usize = 28; + pub(crate) static ID_OP36: usize = 29; + pub(crate) static ID_OP37: usize = 30; + pub(crate) static ID_OP4: usize = 31; + pub(crate) static ID_OP5: usize = 32; + pub(crate) static ID_OP6: usize = 33; + pub(crate) static ID_OP7: usize = 34; + pub(crate) static ID_OP8: usize = 35; + pub(crate) static ID_OP9: usize = 36; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // Op10Get - GET /op10 + hyper::Method::GET if path.matched(paths::ID_OP10) => { + let result = api_impl.op10_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op10GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op11Get - GET /op11 + hyper::Method::GET if path.matched(paths::ID_OP11) => { + let result = api_impl.op11_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op11GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op12Get - GET /op12 + hyper::Method::GET if path.matched(paths::ID_OP12) => { + let result = api_impl.op12_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op12GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op13Get - GET /op13 + hyper::Method::GET if path.matched(paths::ID_OP13) => { + let result = api_impl.op13_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op13GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op14Get - GET /op14 + hyper::Method::GET if path.matched(paths::ID_OP14) => { + let result = api_impl.op14_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op14GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op15Get - GET /op15 + hyper::Method::GET if path.matched(paths::ID_OP15) => { + let result = api_impl.op15_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op15GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op16Get - GET /op16 + hyper::Method::GET if path.matched(paths::ID_OP16) => { + let result = api_impl.op16_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op16GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op17Get - GET /op17 + hyper::Method::GET if path.matched(paths::ID_OP17) => { + let result = api_impl.op17_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op17GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op18Get - GET /op18 + hyper::Method::GET if path.matched(paths::ID_OP18) => { + let result = api_impl.op18_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op18GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op19Get - GET /op19 + hyper::Method::GET if path.matched(paths::ID_OP19) => { + let result = api_impl.op19_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op19GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op1Get - GET /op1 + hyper::Method::GET if path.matched(paths::ID_OP1) => { + let result = api_impl.op1_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op1GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op20Get - GET /op20 + hyper::Method::GET if path.matched(paths::ID_OP20) => { + let result = api_impl.op20_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op20GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op21Get - GET /op21 + hyper::Method::GET if path.matched(paths::ID_OP21) => { + let result = api_impl.op21_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op21GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op22Get - GET /op22 + hyper::Method::GET if path.matched(paths::ID_OP22) => { + let result = api_impl.op22_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op22GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op23Get - GET /op23 + hyper::Method::GET if path.matched(paths::ID_OP23) => { + let result = api_impl.op23_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op23GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op24Get - GET /op24 + hyper::Method::GET if path.matched(paths::ID_OP24) => { + let result = api_impl.op24_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op24GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op25Get - GET /op25 + hyper::Method::GET if path.matched(paths::ID_OP25) => { + let result = api_impl.op25_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op25GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op26Get - GET /op26 + hyper::Method::GET if path.matched(paths::ID_OP26) => { + let result = api_impl.op26_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op26GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op27Get - GET /op27 + hyper::Method::GET if path.matched(paths::ID_OP27) => { + let result = api_impl.op27_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op27GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op28Get - GET /op28 + hyper::Method::GET if path.matched(paths::ID_OP28) => { + let result = api_impl.op28_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op28GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op29Get - GET /op29 + hyper::Method::GET if path.matched(paths::ID_OP29) => { + let result = api_impl.op29_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op29GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op2Get - GET /op2 + hyper::Method::GET if path.matched(paths::ID_OP2) => { + let result = api_impl.op2_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op2GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op30Get - GET /op30 + hyper::Method::GET if path.matched(paths::ID_OP30) => { + let result = api_impl.op30_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op30GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op31Get - GET /op31 + hyper::Method::GET if path.matched(paths::ID_OP31) => { + let result = api_impl.op31_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op31GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op32Get - GET /op32 + hyper::Method::GET if path.matched(paths::ID_OP32) => { + let result = api_impl.op32_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op32GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op33Get - GET /op33 + hyper::Method::GET if path.matched(paths::ID_OP33) => { + let result = api_impl.op33_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op33GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op34Get - GET /op34 + hyper::Method::GET if path.matched(paths::ID_OP34) => { + let result = api_impl.op34_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op34GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op35Get - GET /op35 + hyper::Method::GET if path.matched(paths::ID_OP35) => { + let result = api_impl.op35_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op35GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op36Get - GET /op36 + hyper::Method::GET if path.matched(paths::ID_OP36) => { + let result = api_impl.op36_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op36GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op37Get - GET /op37 + hyper::Method::GET if path.matched(paths::ID_OP37) => { + let result = api_impl.op37_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op37GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op3Get - GET /op3 + hyper::Method::GET if path.matched(paths::ID_OP3) => { + let result = api_impl.op3_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op3GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op4Get - GET /op4 + hyper::Method::GET if path.matched(paths::ID_OP4) => { + let result = api_impl.op4_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op4GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op5Get - GET /op5 + hyper::Method::GET if path.matched(paths::ID_OP5) => { + let result = api_impl.op5_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op5GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op6Get - GET /op6 + hyper::Method::GET if path.matched(paths::ID_OP6) => { + let result = api_impl.op6_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op6GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op7Get - GET /op7 + hyper::Method::GET if path.matched(paths::ID_OP7) => { + let result = api_impl.op7_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op7GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op8Get - GET /op8 + hyper::Method::GET if path.matched(paths::ID_OP8) => { + let result = api_impl.op8_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op8GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // Op9Get - GET /op9 + hyper::Method::GET if path.matched(paths::ID_OP9) => { + let result = api_impl.op9_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Op9GetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + _ if path.matched(paths::ID_OP1) => method_not_allowed(), + _ if path.matched(paths::ID_OP10) => method_not_allowed(), + _ if path.matched(paths::ID_OP11) => method_not_allowed(), + _ if path.matched(paths::ID_OP12) => method_not_allowed(), + _ if path.matched(paths::ID_OP13) => method_not_allowed(), + _ if path.matched(paths::ID_OP14) => method_not_allowed(), + _ if path.matched(paths::ID_OP15) => method_not_allowed(), + _ if path.matched(paths::ID_OP16) => method_not_allowed(), + _ if path.matched(paths::ID_OP17) => method_not_allowed(), + _ if path.matched(paths::ID_OP18) => method_not_allowed(), + _ if path.matched(paths::ID_OP19) => method_not_allowed(), + _ if path.matched(paths::ID_OP2) => method_not_allowed(), + _ if path.matched(paths::ID_OP20) => method_not_allowed(), + _ if path.matched(paths::ID_OP21) => method_not_allowed(), + _ if path.matched(paths::ID_OP22) => method_not_allowed(), + _ if path.matched(paths::ID_OP23) => method_not_allowed(), + _ if path.matched(paths::ID_OP24) => method_not_allowed(), + _ if path.matched(paths::ID_OP25) => method_not_allowed(), + _ if path.matched(paths::ID_OP26) => method_not_allowed(), + _ if path.matched(paths::ID_OP27) => method_not_allowed(), + _ if path.matched(paths::ID_OP28) => method_not_allowed(), + _ if path.matched(paths::ID_OP29) => method_not_allowed(), + _ if path.matched(paths::ID_OP3) => method_not_allowed(), + _ if path.matched(paths::ID_OP30) => method_not_allowed(), + _ if path.matched(paths::ID_OP31) => method_not_allowed(), + _ if path.matched(paths::ID_OP32) => method_not_allowed(), + _ if path.matched(paths::ID_OP33) => method_not_allowed(), + _ if path.matched(paths::ID_OP34) => method_not_allowed(), + _ if path.matched(paths::ID_OP35) => method_not_allowed(), + _ if path.matched(paths::ID_OP36) => method_not_allowed(), + _ if path.matched(paths::ID_OP37) => method_not_allowed(), + _ if path.matched(paths::ID_OP4) => method_not_allowed(), + _ if path.matched(paths::ID_OP5) => method_not_allowed(), + _ if path.matched(paths::ID_OP6) => method_not_allowed(), + _ if path.matched(paths::ID_OP7) => method_not_allowed(), + _ if path.matched(paths::ID_OP8) => method_not_allowed(), + _ if path.matched(paths::ID_OP9) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // Op10Get - GET /op10 + hyper::Method::GET if path.matched(paths::ID_OP10) => Some("Op10Get"), + // Op11Get - GET /op11 + hyper::Method::GET if path.matched(paths::ID_OP11) => Some("Op11Get"), + // Op12Get - GET /op12 + hyper::Method::GET if path.matched(paths::ID_OP12) => Some("Op12Get"), + // Op13Get - GET /op13 + hyper::Method::GET if path.matched(paths::ID_OP13) => Some("Op13Get"), + // Op14Get - GET /op14 + hyper::Method::GET if path.matched(paths::ID_OP14) => Some("Op14Get"), + // Op15Get - GET /op15 + hyper::Method::GET if path.matched(paths::ID_OP15) => Some("Op15Get"), + // Op16Get - GET /op16 + hyper::Method::GET if path.matched(paths::ID_OP16) => Some("Op16Get"), + // Op17Get - GET /op17 + hyper::Method::GET if path.matched(paths::ID_OP17) => Some("Op17Get"), + // Op18Get - GET /op18 + hyper::Method::GET if path.matched(paths::ID_OP18) => Some("Op18Get"), + // Op19Get - GET /op19 + hyper::Method::GET if path.matched(paths::ID_OP19) => Some("Op19Get"), + // Op1Get - GET /op1 + hyper::Method::GET if path.matched(paths::ID_OP1) => Some("Op1Get"), + // Op20Get - GET /op20 + hyper::Method::GET if path.matched(paths::ID_OP20) => Some("Op20Get"), + // Op21Get - GET /op21 + hyper::Method::GET if path.matched(paths::ID_OP21) => Some("Op21Get"), + // Op22Get - GET /op22 + hyper::Method::GET if path.matched(paths::ID_OP22) => Some("Op22Get"), + // Op23Get - GET /op23 + hyper::Method::GET if path.matched(paths::ID_OP23) => Some("Op23Get"), + // Op24Get - GET /op24 + hyper::Method::GET if path.matched(paths::ID_OP24) => Some("Op24Get"), + // Op25Get - GET /op25 + hyper::Method::GET if path.matched(paths::ID_OP25) => Some("Op25Get"), + // Op26Get - GET /op26 + hyper::Method::GET if path.matched(paths::ID_OP26) => Some("Op26Get"), + // Op27Get - GET /op27 + hyper::Method::GET if path.matched(paths::ID_OP27) => Some("Op27Get"), + // Op28Get - GET /op28 + hyper::Method::GET if path.matched(paths::ID_OP28) => Some("Op28Get"), + // Op29Get - GET /op29 + hyper::Method::GET if path.matched(paths::ID_OP29) => Some("Op29Get"), + // Op2Get - GET /op2 + hyper::Method::GET if path.matched(paths::ID_OP2) => Some("Op2Get"), + // Op30Get - GET /op30 + hyper::Method::GET if path.matched(paths::ID_OP30) => Some("Op30Get"), + // Op31Get - GET /op31 + hyper::Method::GET if path.matched(paths::ID_OP31) => Some("Op31Get"), + // Op32Get - GET /op32 + hyper::Method::GET if path.matched(paths::ID_OP32) => Some("Op32Get"), + // Op33Get - GET /op33 + hyper::Method::GET if path.matched(paths::ID_OP33) => Some("Op33Get"), + // Op34Get - GET /op34 + hyper::Method::GET if path.matched(paths::ID_OP34) => Some("Op34Get"), + // Op35Get - GET /op35 + hyper::Method::GET if path.matched(paths::ID_OP35) => Some("Op35Get"), + // Op36Get - GET /op36 + hyper::Method::GET if path.matched(paths::ID_OP36) => Some("Op36Get"), + // Op37Get - GET /op37 + hyper::Method::GET if path.matched(paths::ID_OP37) => Some("Op37Get"), + // Op3Get - GET /op3 + hyper::Method::GET if path.matched(paths::ID_OP3) => Some("Op3Get"), + // Op4Get - GET /op4 + hyper::Method::GET if path.matched(paths::ID_OP4) => Some("Op4Get"), + // Op5Get - GET /op5 + hyper::Method::GET if path.matched(paths::ID_OP5) => Some("Op5Get"), + // Op6Get - GET /op6 + hyper::Method::GET if path.matched(paths::ID_OP6) => Some("Op6Get"), + // Op7Get - GET /op7 + hyper::Method::GET if path.matched(paths::ID_OP7) => Some("Op7Get"), + // Op8Get - GET /op8 + hyper::Method::GET if path.matched(paths::ID_OP8) => Some("Op8Get"), + // Op9Get - GET /op9 + hyper::Method::GET if path.matched(paths::ID_OP9) => Some("Op9Get"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ops-v3/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.gitignore b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES new file mode 100644 index 000000000000..6d35ed812fa6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES @@ -0,0 +1,80 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/AdditionalPropertiesClass.md +docs/Animal.md +docs/AnimalFarm.md +docs/ApiResponse.md +docs/ArrayOfArrayOfNumberOnly.md +docs/ArrayOfNumberOnly.md +docs/ArrayTest.md +docs/Capitalization.md +docs/Cat.md +docs/Category.md +docs/ClassModel.md +docs/Client.md +docs/Dog.md +docs/DollarSpecialLeftSquareBracketModelNameRightSquareBracket.md +docs/EnumArrays.md +docs/EnumArraysArrayArrayEnumInnerInner.md +docs/EnumArraysArrayEnumInner.md +docs/EnumArraysJustSymbol.md +docs/EnumClass.md +docs/EnumTest.md +docs/EnumTestEnumInteger.md +docs/EnumTestEnumString.md +docs/FindPetsByStatusStatusParameterInner.md +docs/FormatTest.md +docs/HasOnlyReadOnly.md +docs/List.md +docs/MapTest.md +docs/MapTestMapMapOfEnumValueValue.md +docs/MixedPropertiesAndAdditionalPropertiesClass.md +docs/Model200Response.md +docs/Name.md +docs/NumberOnly.md +docs/ObjectContainingObjectWithOnlyAdditionalProperties.md +docs/ObjectWithOnlyAdditionalProperties.md +docs/Order.md +docs/OrderStatus.md +docs/OuterBoolean.md +docs/OuterComposite.md +docs/OuterEnum.md +docs/OuterNumber.md +docs/OuterString.md +docs/Pet.md +docs/PetStatus.md +docs/ReadOnlyFirst.md +docs/Return.md +docs/Tag.md +docs/TestEnumParametersEnumHeaderStringArrayParameterInner.md +docs/TestEnumParametersEnumHeaderStringParameter.md +docs/TestEnumParametersEnumQueryDoubleParameter.md +docs/TestEnumParametersEnumQueryIntegerParameter.md +docs/TestEnumParametersRequestEnumFormString.md +docs/User.md +docs/another_fake_api.md +docs/fake_api.md +docs/fake_classname_tags123_api.md +docs/pet_api.md +docs/store_api.md +docs/user_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml new file mode 100644 index 000000000000..0c809c91fdd6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml @@ -0,0 +1,110 @@ +[package] +name = "petstore-with-fake-endpoints-models-for-testing" +version = "1.0.0" +authors = ["OpenAPI Generator team and contributors"] +description = "This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\" +license = "Apache-2.0" +edition = "2018" +publish = ["crates-io"] + +[features] +default = ["client", "server"] +client = [ + "mime_0_2", + "multipart", "multipart/client", "swagger/multipart_form", + "serde_urlencoded", + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "mime_0_2", + "multipart", "multipart/server", "swagger/multipart_form", + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "dialoguer", + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition +# TODO: this should be updated to point at the official crate once +# https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream +serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} +mime_0_2 = { package = "mime", version = "0.2.6", optional = true } +multipart = { version = "0.16", default-features = false, optional = true } +uuid = {version = "1.3.1", features = ["serde", "v4"]} + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific +serde_urlencoded = {version = "0.6.1", optional = true} + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +dialoguer = { version = "0.8", optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "petstore-with-fake-endpoints-models-for-testing" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/README.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/README.md new file mode 100644 index 000000000000..a3100d49e208 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/README.md @@ -0,0 +1,282 @@ +# Rust API for petstore-with-fake-endpoints-models-for-testing + +This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ + +## Overview + +This client/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: 1.0.0 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `petstore-with-fake-endpoints-models-for-testing` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `petstore-with-fake-endpoints-models-for-testing`: + +* The example server starts up a web server using the `petstore-with-fake-endpoints-models-for-testing` + router, and supplies a trivial implementation of `Api` which returns failure + for every operation. +* The example client provides a CLI which lets you invoke + any single operation on the `petstore-with-fake-endpoints-models-for-testing` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client Call123example +cargo run --example client FakeOuterBooleanSerialize +cargo run --example client FakeOuterCompositeSerialize +cargo run --example client FakeOuterNumberSerialize +cargo run --example client FakeOuterStringSerialize +cargo run --example client FakeResponseWithNumericalDescription +cargo run --example client TestEndpointParameters +cargo run --example client TestEnumParameters +cargo run --example client TestJsonFormData +cargo run --example client HyphenParam +cargo run --example client FindPetsByStatus +cargo run --example client FindPetsByTags +cargo run --example client DeletePet +cargo run --example client GetPetById +cargo run --example client UpdatePetWithForm +cargo run --example client UploadFile +cargo run --example client GetInventory +cargo run --example client DeleteOrder +cargo run --example client GetOrderById +cargo run --example client CreateUsersWithArrayInput +cargo run --example client CreateUsersWithListInput +cargo run --example client LoginUser +cargo run --example client LogoutUser +cargo run --example client DeleteUser +cargo run --example client GetUserByName +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**test_special_tags**](docs/another_fake_api.md#test_special_tags) | **PATCH** /another-fake/dummy | To test special tags +[**123example**](docs/fake_api.md#123example) | **GET** /fake/operation-with-numeric-id | +[**fakeOuterBooleanSerialize**](docs/fake_api.md#fakeOuterBooleanSerialize) | **POST** /fake/outer/boolean | +[**fakeOuterCompositeSerialize**](docs/fake_api.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite | +[**fakeOuterNumberSerialize**](docs/fake_api.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number | +[**fakeOuterStringSerialize**](docs/fake_api.md#fakeOuterStringSerialize) | **POST** /fake/outer/string | +[**fake_response_with_numerical_description**](docs/fake_api.md#fake_response_with_numerical_description) | **GET** /fake/response-with-numerical-description | +[**testBodyWithQueryParams**](docs/fake_api.md#testBodyWithQueryParams) | **PUT** /fake/body-with-query-params | +[**testClientModel**](docs/fake_api.md#testClientModel) | **PATCH** /fake | To test \"client\" model +[**testEndpointParameters**](docs/fake_api.md#testEndpointParameters) | **POST** /fake | Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 +[**testEnumParameters**](docs/fake_api.md#testEnumParameters) | **GET** /fake | To test enum parameters +[**testInlineAdditionalProperties**](docs/fake_api.md#testInlineAdditionalProperties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties +[**testJsonFormData**](docs/fake_api.md#testJsonFormData) | **GET** /fake/jsonFormData | test json serialization of form data +[**hyphenParam**](docs/fake_api.md#hyphenParam) | **GET** /fake/hyphenParam/{hyphen-param} | +[**testClassname**](docs/fake_classname_tags123_api.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case +[**addPet**](docs/pet_api.md#addPet) | **POST** /pet | Add a new pet to the store +[**findPetsByStatus**](docs/pet_api.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status +[**findPetsByTags**](docs/pet_api.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags +[**updatePet**](docs/pet_api.md#updatePet) | **PUT** /pet | Update an existing pet +[**deletePet**](docs/pet_api.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet +[**getPetById**](docs/pet_api.md#getPetById) | **GET** /pet/{petId} | Find pet by ID +[**updatePetWithForm**](docs/pet_api.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data +[**uploadFile**](docs/pet_api.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image +[**getInventory**](docs/store_api.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status +[**placeOrder**](docs/store_api.md#placeOrder) | **POST** /store/order | Place an order for a pet +[**deleteOrder**](docs/store_api.md#deleteOrder) | **DELETE** /store/order/{order_id} | Delete purchase order by ID +[**getOrderById**](docs/store_api.md#getOrderById) | **GET** /store/order/{order_id} | Find purchase order by ID +[**createUser**](docs/user_api.md#createUser) | **POST** /user | Create user +[**createUsersWithArrayInput**](docs/user_api.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array +[**createUsersWithListInput**](docs/user_api.md#createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array +[**loginUser**](docs/user_api.md#loginUser) | **GET** /user/login | Logs user into the system +[**logoutUser**](docs/user_api.md#logoutUser) | **GET** /user/logout | Logs out current logged in user session +[**deleteUser**](docs/user_api.md#deleteUser) | **DELETE** /user/{username} | Delete user +[**getUserByName**](docs/user_api.md#getUserByName) | **GET** /user/{username} | Get user by user name +[**updateUser**](docs/user_api.md#updateUser) | **PUT** /user/{username} | Updated user + + +## Documentation For Models + + - [AdditionalPropertiesClass](docs/AdditionalPropertiesClass.md) + - [Animal](docs/Animal.md) + - [AnimalFarm](docs/AnimalFarm.md) + - [ApiResponse](docs/ApiResponse.md) + - [ArrayOfArrayOfNumberOnly](docs/ArrayOfArrayOfNumberOnly.md) + - [ArrayOfNumberOnly](docs/ArrayOfNumberOnly.md) + - [ArrayTest](docs/ArrayTest.md) + - [Capitalization](docs/Capitalization.md) + - [Cat](docs/Cat.md) + - [Category](docs/Category.md) + - [ClassModel](docs/ClassModel.md) + - [Client](docs/Client.md) + - [Dog](docs/Dog.md) + - [DollarSpecialLeftSquareBracketModelNameRightSquareBracket](docs/DollarSpecialLeftSquareBracketModelNameRightSquareBracket.md) + - [EnumArrays](docs/EnumArrays.md) + - [EnumArraysArrayArrayEnumInnerInner](docs/EnumArraysArrayArrayEnumInnerInner.md) + - [EnumArraysArrayEnumInner](docs/EnumArraysArrayEnumInner.md) + - [EnumArraysJustSymbol](docs/EnumArraysJustSymbol.md) + - [EnumClass](docs/EnumClass.md) + - [EnumTest](docs/EnumTest.md) + - [EnumTestEnumInteger](docs/EnumTestEnumInteger.md) + - [EnumTestEnumString](docs/EnumTestEnumString.md) + - [FindPetsByStatusStatusParameterInner](docs/FindPetsByStatusStatusParameterInner.md) + - [FormatTest](docs/FormatTest.md) + - [HasOnlyReadOnly](docs/HasOnlyReadOnly.md) + - [List](docs/List.md) + - [MapTest](docs/MapTest.md) + - [MapTestMapMapOfEnumValueValue](docs/MapTestMapMapOfEnumValueValue.md) + - [MixedPropertiesAndAdditionalPropertiesClass](docs/MixedPropertiesAndAdditionalPropertiesClass.md) + - [Model200Response](docs/Model200Response.md) + - [Name](docs/Name.md) + - [NumberOnly](docs/NumberOnly.md) + - [ObjectContainingObjectWithOnlyAdditionalProperties](docs/ObjectContainingObjectWithOnlyAdditionalProperties.md) + - [ObjectWithOnlyAdditionalProperties](docs/ObjectWithOnlyAdditionalProperties.md) + - [Order](docs/Order.md) + - [OrderStatus](docs/OrderStatus.md) + - [OuterBoolean](docs/OuterBoolean.md) + - [OuterComposite](docs/OuterComposite.md) + - [OuterEnum](docs/OuterEnum.md) + - [OuterNumber](docs/OuterNumber.md) + - [OuterString](docs/OuterString.md) + - [Pet](docs/Pet.md) + - [PetStatus](docs/PetStatus.md) + - [ReadOnlyFirst](docs/ReadOnlyFirst.md) + - [Return](docs/Return.md) + - [Tag](docs/Tag.md) + - [TestEnumParametersEnumHeaderStringArrayParameterInner](docs/TestEnumParametersEnumHeaderStringArrayParameterInner.md) + - [TestEnumParametersEnumHeaderStringParameter](docs/TestEnumParametersEnumHeaderStringParameter.md) + - [TestEnumParametersEnumQueryDoubleParameter](docs/TestEnumParametersEnumQueryDoubleParameter.md) + - [TestEnumParametersEnumQueryIntegerParameter](docs/TestEnumParametersEnumQueryIntegerParameter.md) + - [TestEnumParametersRequestEnumFormString](docs/TestEnumParametersRequestEnumFormString.md) + - [User](docs/User.md) + + +## Documentation For Authorization + +Authentication schemes defined for the API: +### petstore_auth +- **Type**: OAuth +- **Flow**: implicit +- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog +- **Scopes**: + - **write:pets**: modify pets in your account + - **read:pets**: read your pets + +Example +``` +``` + +Or via OAuth2 module to automatically refresh tokens and perform user authentication. +``` +``` +### api_key +- **Type**: API key + +Example +``` +``` +### api_key_query +- **Type**: API key + +Example +``` +``` +### http_basic_test +- **Type**: HTTP basic authentication + +Example +``` +``` + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/api/openapi.yaml new file mode 100644 index 000000000000..c9cac8905821 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/api/openapi.yaml @@ -0,0 +1,1611 @@ +openapi: 3.0.1 +info: + description: "This spec is mainly for testing Petstore server and contains fake\ + \ endpoints, models. Please do not use this for any other purpose. Special characters:\ + \ \" \\" + license: + name: Apache-2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + title: OpenAPI Petstore + version: 1.0.0 +servers: +- url: http://petstore.swagger.io:80/v2 +tags: +- description: Everything about your Pets + name: pet +- description: Access to Petstore orders + name: store +- description: Operations about user + name: user +paths: + /pet: + post: + operationId: addPet + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + application/xml: + schema: + $ref: "#/components/schemas/Pet" + description: Pet object that needs to be added to the store + required: true + responses: + "405": + content: {} + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + summary: Add a new pet to the store + tags: + - pet + x-codegen-request-body-name: body + put: + operationId: updatePet + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + application/xml: + schema: + $ref: "#/components/schemas/Pet" + description: Pet object that needs to be added to the store + required: true + responses: + "400": + content: {} + description: Invalid ID supplied + "404": + content: {} + description: Pet not found + "405": + content: {} + description: Validation exception + security: + - petstore_auth: + - write:pets + - read:pets + summary: Update an existing pet + tags: + - pet + x-codegen-request-body-name: body + /pet/findByStatus: + get: + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - description: Status values that need to be considered for filter + explode: false + in: query + name: status + required: true + schema: + items: + $ref: "#/components/schemas/findPetsByStatus_status_parameter_inner" + type: array + style: form + responses: + "200": + content: + application/xml: + schema: + items: + $ref: "#/components/schemas/Pet" + type: array + application/json: + schema: + items: + $ref: "#/components/schemas/Pet" + type: array + description: successful operation + "400": + content: {} + description: Invalid status value + security: + - petstore_auth: + - write:pets + - read:pets + summary: Finds Pets by status + tags: + - pet + /pet/findByTags: + get: + deprecated: true + description: "Multiple tags can be provided with comma separated strings. Use\ + \ tag1, tag2, tag3 for testing." + operationId: findPetsByTags + parameters: + - description: Tags to filter by + explode: false + in: query + name: tags + required: true + schema: + items: + type: string + type: array + style: form + responses: + "200": + content: + application/xml: + schema: + items: + $ref: "#/components/schemas/Pet" + type: array + application/json: + schema: + items: + $ref: "#/components/schemas/Pet" + type: array + description: successful operation + "400": + content: {} + description: Invalid tag value + security: + - petstore_auth: + - write:pets + - read:pets + summary: Finds Pets by tags + tags: + - pet + /pet/{petId}: + delete: + operationId: deletePet + parameters: + - in: header + name: api_key + schema: + type: string + - description: Pet id to delete + in: path + name: petId + required: true + schema: + format: int64 + type: integer + responses: + "400": + content: {} + description: Invalid pet value + security: + - petstore_auth: + - write:pets + - read:pets + summary: Deletes a pet + tags: + - pet + get: + description: Returns a single pet + operationId: getPetById + parameters: + - description: ID of pet to return + in: path + name: petId + required: true + schema: + format: int64 + type: integer + responses: + "200": + content: + application/xml: + schema: + $ref: "#/components/schemas/Pet" + application/json: + schema: + $ref: "#/components/schemas/Pet" + description: successful operation + "400": + content: {} + description: Invalid ID supplied + "404": + content: {} + description: Pet not found + security: + - api_key: [] + summary: Find pet by ID + tags: + - pet + post: + operationId: updatePetWithForm + parameters: + - description: ID of pet that needs to be updated + in: path + name: petId + required: true + schema: + format: int64 + type: integer + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/updatePetWithForm_request" + responses: + "405": + content: {} + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + summary: Updates a pet in the store with form data + tags: + - pet + /pet/{petId}/uploadImage: + post: + operationId: uploadFile + parameters: + - description: ID of pet to update + in: path + name: petId + required: true + schema: + format: int64 + type: integer + requestBody: + content: + multipart/form-data: + schema: + $ref: "#/components/schemas/uploadFile_request" + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/ApiResponse" + description: successful operation + security: + - petstore_auth: + - write:pets + - read:pets + summary: uploads an image + tags: + - pet + /store/inventory: + get: + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + "200": + content: + application/json: + schema: + additionalProperties: + format: int32 + type: integer + type: object + description: successful operation + security: + - api_key: [] + summary: Returns pet inventories by status + tags: + - store + /store/order: + post: + operationId: placeOrder + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/Order" + description: order placed for purchasing the pet + required: true + responses: + "200": + content: + application/xml: + schema: + $ref: "#/components/schemas/Order" + application/json: + schema: + $ref: "#/components/schemas/Order" + description: successful operation + "400": + content: {} + description: Invalid Order + summary: Place an order for a pet + tags: + - store + x-codegen-request-body-name: body + /store/order/{order_id}: + delete: + description: For valid response try integer IDs with value < 1000. Anything + above 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - description: ID of the order that needs to be deleted + in: path + name: order_id + required: true + schema: + type: string + responses: + "400": + content: {} + description: Invalid ID supplied + "404": + content: {} + description: Order not found + summary: Delete purchase order by ID + tags: + - store + get: + description: For valid response try integer IDs with value <= 5 or > 10. Other + values will generate exceptions + operationId: getOrderById + parameters: + - description: ID of pet that needs to be fetched + in: path + name: order_id + required: true + schema: + format: int64 + maximum: 5 + minimum: 1 + type: integer + responses: + "200": + content: + application/xml: + schema: + $ref: "#/components/schemas/Order" + application/json: + schema: + $ref: "#/components/schemas/Order" + description: successful operation + "400": + content: {} + description: Invalid ID supplied + "404": + content: {} + description: Order not found + summary: Find purchase order by ID + tags: + - store + /user: + post: + description: This can only be done by the logged in user. + operationId: createUser + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/User" + description: Created user object + required: true + responses: + default: + content: {} + description: successful operation + summary: Create user + tags: + - user + x-codegen-request-body-name: body + /user/createWithArray: + post: + operationId: createUsersWithArrayInput + requestBody: + content: + '*/*': + schema: + items: + $ref: "#/components/schemas/User" + type: array + description: List of user object + required: true + responses: + default: + content: {} + description: successful operation + summary: Creates list of users with given input array + tags: + - user + x-codegen-request-body-name: body + /user/createWithList: + post: + operationId: createUsersWithListInput + requestBody: + content: + '*/*': + schema: + items: + $ref: "#/components/schemas/User" + type: array + description: List of user object + required: true + responses: + default: + content: {} + description: successful operation + summary: Creates list of users with given input array + tags: + - user + x-codegen-request-body-name: body + /user/login: + get: + operationId: loginUser + parameters: + - description: The user name for login + in: query + name: username + required: true + schema: + type: string + - description: The password for login in clear text + in: query + name: password + required: true + schema: + type: string + responses: + "200": + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + description: successful operation + headers: + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + format: int32 + type: integer + X-Expires-After: + description: date in UTC when token expires + schema: + format: date-time + type: string + "400": + content: {} + description: Invalid username/password supplied + summary: Logs user into the system + tags: + - user + /user/logout: + get: + operationId: logoutUser + responses: + default: + content: {} + description: successful operation + summary: Logs out current logged in user session + tags: + - user + /user/{username}: + delete: + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - description: The name that needs to be deleted + in: path + name: username + required: true + schema: + type: string + responses: + "400": + content: {} + description: Invalid username supplied + "404": + content: {} + description: User not found + summary: Delete user + tags: + - user + get: + operationId: getUserByName + parameters: + - description: The name that needs to be fetched. Use user1 for testing. + in: path + name: username + required: true + schema: + type: string + responses: + "200": + content: + application/xml: + schema: + $ref: "#/components/schemas/User" + application/json: + schema: + $ref: "#/components/schemas/User" + description: successful operation + "400": + content: {} + description: Invalid username supplied + "404": + content: {} + description: User not found + summary: Get user by user name + tags: + - user + put: + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - description: name that need to be deleted + in: path + name: username + required: true + schema: + type: string + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/User" + description: Updated user object + required: true + responses: + "400": + content: {} + description: Invalid user supplied + "404": + content: {} + description: User not found + summary: Updated user + tags: + - user + x-codegen-request-body-name: body + /fake_classname_test: + patch: + description: To test class name in snake case + operationId: testClassname + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: client model + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: successful operation + security: + - api_key_query: [] + summary: To test class name in snake case + tags: + - fake_classname_tags 123#$%^ + x-codegen-request-body-name: body + /fake: + get: + description: To test enum parameters + operationId: testEnumParameters + parameters: + - description: Header parameter enum test (string array) + explode: false + in: header + name: enum_header_string_array + schema: + items: + $ref: "#/components/schemas/testEnumParameters_enum_header_string_array_parameter_inner" + type: array + style: simple + - description: Header parameter enum test (string) + in: header + name: enum_header_string + schema: + $ref: "#/components/schemas/testEnumParameters_enum_header_string_parameter" + - description: Query parameter enum test (string array) + explode: false + in: query + name: enum_query_string_array + schema: + items: + $ref: "#/components/schemas/testEnumParameters_enum_header_string_array_parameter_inner" + type: array + style: form + - description: Query parameter enum test (string) + in: query + name: enum_query_string + schema: + $ref: "#/components/schemas/testEnumParameters_enum_header_string_parameter" + - description: Query parameter enum test (double) + in: query + name: enum_query_integer + schema: + $ref: "#/components/schemas/testEnumParameters_enum_query_integer_parameter" + - description: Query parameter enum test (double) + in: query + name: enum_query_double + schema: + $ref: "#/components/schemas/testEnumParameters_enum_query_double_parameter" + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/testEnumParameters_request" + responses: + "400": + content: {} + description: Invalid request + "404": + content: {} + description: Not found + summary: To test enum parameters + tags: + - fake + patch: + description: To test "client" model + operationId: testClientModel + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: client model + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: successful operation + summary: To test "client" model + tags: + - fake + x-codegen-request-body-name: body + post: + description: |- + Fake endpoint for testing various parameters + 假端點 + 偽のエンドポイント + 가짜 엔드 포인트 + operationId: testEndpointParameters + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/testEndpointParameters_request" + required: true + responses: + "400": + content: {} + description: Invalid username supplied + "404": + content: {} + description: User not found + security: + - http_basic_test: [] + summary: |- + Fake endpoint for testing various parameters + 假端點 + 偽のエンドポイント + 가짜 엔드 포인트 + tags: + - fake + /fake/outer/number: + post: + description: Test serialization of outer number types + operationId: fakeOuterNumberSerialize + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterNumber" + description: Input number as post body + required: false + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterNumber" + description: Output number + tags: + - fake + x-codegen-request-body-name: body + /fake/outer/string: + post: + description: Test serialization of outer string types + operationId: fakeOuterStringSerialize + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterString" + description: Input string as post body + required: false + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterString" + description: Output string + tags: + - fake + x-codegen-request-body-name: body + /fake/outer/boolean: + post: + description: Test serialization of outer boolean types + operationId: fakeOuterBooleanSerialize + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterBoolean" + description: Input boolean as post body + required: false + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterBoolean" + description: Output boolean + tags: + - fake + x-codegen-request-body-name: body + /fake/outer/composite: + post: + description: Test serialization of object with outer number type + operationId: fakeOuterCompositeSerialize + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterComposite" + description: Input composite as post body + required: false + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/OuterComposite" + description: Output composite + tags: + - fake + x-codegen-request-body-name: body + /fake/jsonFormData: + get: + operationId: testJsonFormData + requestBody: + content: + application/x-www-form-urlencoded: + schema: + $ref: "#/components/schemas/testJsonFormData_request" + required: true + responses: + "200": + content: {} + description: successful operation + summary: test json serialization of form data + tags: + - fake + /fake/inline-additionalProperties: + post: + operationId: testInlineAdditionalProperties + requestBody: + content: + application/json: + schema: + additionalProperties: + type: string + type: object + description: request body + required: true + responses: + "200": + content: {} + description: successful operation + summary: test inline additionalProperties + tags: + - fake + x-codegen-request-body-name: param + /fake/body-with-query-params: + put: + operationId: testBodyWithQueryParams + parameters: + - in: query + name: query + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/User" + required: true + responses: + "200": + content: {} + description: Success + tags: + - fake + x-codegen-request-body-name: body + /another-fake/dummy: + patch: + description: To test special tags + operationId: test_special_tags + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: client model + required: true + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/Client" + description: successful operation + summary: To test special tags + tags: + - $another-fake? + x-codegen-request-body-name: body + /fake/hyphenParam/{hyphen-param}: + get: + description: To test hyphen in path parameter name + operationId: hyphenParam + parameters: + - description: Parameter with hyphen in name + in: path + name: hyphen-param + required: true + schema: + type: string + responses: + "200": + content: {} + description: Success + tags: + - fake + /fake/operation-with-numeric-id: + get: + operationId: 123example + responses: + "200": + content: {} + description: success + tags: + - fake + /fake/response-with-numerical-description: + get: + operationId: fake_response_with_numerical_description + responses: + "200": + content: {} + description: "1234" + tags: + - fake +components: + schemas: + Order: + example: + petId: 6 + quantity: 1 + id: 0 + shipDate: 2000-01-23T04:56:07.000+00:00 + complete: false + status: placed + properties: + id: + format: int64 + type: integer + petId: + format: int64 + type: integer + quantity: + format: int32 + type: integer + shipDate: + format: date-time + type: string + status: + $ref: "#/components/schemas/Order_status" + complete: + default: false + type: boolean + type: object + xml: + name: Order + Category: + example: + name: name + id: 6 + properties: + id: + format: int64 + type: integer + name: + type: string + type: object + xml: + name: Category + User: + example: + firstName: firstName + lastName: lastName + password: password + userStatus: 6 + phone: phone + id: 0 + email: email + username: username + properties: + id: + format: int64 + type: integer + x-is-unique: true + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + description: User Status + format: int32 + type: integer + type: object + xml: + name: User + Tag: + example: + name: name + id: 1 + properties: + id: + format: int64 + type: integer + name: + type: string + type: object + xml: + name: Tag + Pet: + example: + photoUrls: + - photoUrls + - photoUrls + name: doggie + id: 0 + category: + name: name + id: 6 + tags: + - name: name + id: 1 + - name: name + id: 1 + status: available + properties: + id: + format: int64 + type: integer + x-is-unique: true + category: + $ref: "#/components/schemas/Category" + name: + example: doggie + type: string + photoUrls: + items: + type: string + type: array + xml: + name: photoUrl + wrapped: true + tags: + items: + $ref: "#/components/schemas/Tag" + type: array + xml: + name: tag + wrapped: true + status: + $ref: "#/components/schemas/Pet_status" + required: + - name + - photoUrls + type: object + xml: + name: Pet + ApiResponse: + example: + code: 0 + type: type + message: message + properties: + code: + format: int32 + type: integer + type: + type: string + message: + type: string + type: object + $special[model.name]: + properties: + $special[property.name]: + format: int64 + type: integer + type: object + xml: + name: "$special[model.name]" + Return: + description: Model for testing reserved words + properties: + return: + format: int32 + type: integer + type: object + xml: + name: Return + Name: + description: Model for testing model name same as property name + properties: + name: + format: int32 + type: integer + snake_case: + format: int32 + readOnly: true + type: integer + property: + type: string + "123Number": + readOnly: true + type: integer + required: + - name + type: object + xml: + name: Name + "200_response": + description: Model for testing model name starting with number + properties: + name: + format: int32 + type: integer + class: + type: string + type: object + xml: + name: Name + ClassModel: + description: Model for testing model with "_class" property + properties: + _class: + type: string + type: object + Dog: + allOf: + - $ref: "#/components/schemas/Animal" + - properties: + breed: + type: string + type: object + Cat: + allOf: + - $ref: "#/components/schemas/Animal" + - properties: + declawed: + type: boolean + type: object + Animal: + discriminator: + propertyName: className + properties: + className: + type: string + color: + default: red + type: string + required: + - className + type: object + AnimalFarm: + items: + $ref: "#/components/schemas/Animal" + type: array + format_test: + properties: + integer: + maximum: 100 + minimum: 10 + type: integer + int32: + format: int32 + maximum: 200 + minimum: 20 + type: integer + int64: + format: int64 + type: integer + number: + maximum: 543.2 + minimum: 32.1 + type: number + float: + format: float + maximum: 987.6 + minimum: 54.3 + type: number + double: + format: double + maximum: 123.4 + minimum: 67.8 + type: number + string: + pattern: "/[a-z]/i" + type: string + byte: + format: byte + pattern: "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$" + type: string + binary: + format: binary + type: string + date: + format: date + type: string + dateTime: + format: date-time + type: string + uuid: + format: uuid + type: string + password: + format: password + maxLength: 64 + minLength: 10 + type: string + required: + - byte + - date + - number + - password + type: object + EnumClass: + default: -efg + enum: + - _abc + - -efg + - (xyz) + type: string + Enum_Test: + properties: + enum_string: + $ref: "#/components/schemas/Enum_Test_enum_string" + enum_string_required: + $ref: "#/components/schemas/Enum_Test_enum_string" + enum_integer: + $ref: "#/components/schemas/Enum_Test_enum_integer" + enum_number: + $ref: "#/components/schemas/testEnumParameters_enum_query_double_parameter" + outerEnum: + $ref: "#/components/schemas/OuterEnum" + required: + - enum_string_required + type: object + AdditionalPropertiesClass: + properties: + map_property: + additionalProperties: + type: string + type: object + map_of_map_property: + additionalProperties: + additionalProperties: + type: string + type: object + type: object + type: object + MixedPropertiesAndAdditionalPropertiesClass: + properties: + uuid: + format: uuid + type: string + dateTime: + format: date-time + type: string + map: + additionalProperties: + $ref: "#/components/schemas/Animal" + type: object + type: object + ObjectContainingObjectWithOnlyAdditionalProperties: + properties: + inner: + $ref: "#/components/schemas/ObjectWithOnlyAdditionalProperties" + type: object + ObjectWithOnlyAdditionalProperties: + additionalProperties: + type: string + type: object + List: + properties: + "123-list": + type: string + type: object + Client: + example: + client: client + properties: + client: + type: string + type: object + ReadOnlyFirst: + properties: + bar: + readOnly: true + type: string + baz: + type: string + type: object + hasOnlyReadOnly: + properties: + bar: + readOnly: true + type: string + foo: + readOnly: true + type: string + type: object + Capitalization: + properties: + smallCamel: + type: string + CapitalCamel: + type: string + small_Snake: + type: string + Capital_Snake: + type: string + SCA_ETH_Flow_Points: + type: string + ATT_NAME: + description: | + Name of the pet + type: string + type: object + MapTest: + properties: + map_map_of_string: + additionalProperties: + additionalProperties: + type: string + type: object + type: object + map_map_of_enum: + additionalProperties: + additionalProperties: + $ref: "#/components/schemas/MapTest_map_map_of_enum_value_value" + type: object + type: object + map_of_enum_string: + additionalProperties: + $ref: "#/components/schemas/MapTest_map_map_of_enum_value_value" + type: object + type: object + ArrayTest: + properties: + array_of_string: + items: + type: string + type: array + array_array_of_integer: + items: + items: + format: int64 + type: integer + type: array + type: array + array_array_of_model: + items: + items: + $ref: "#/components/schemas/ReadOnlyFirst" + type: array + type: array + array_of_enum: + items: + $ref: "#/components/schemas/MapTest_map_map_of_enum_value_value" + type: array + type: object + NumberOnly: + properties: + JustNumber: + type: number + type: object + ArrayOfNumberOnly: + properties: + ArrayNumber: + items: + type: number + type: array + type: object + ArrayOfArrayOfNumberOnly: + properties: + ArrayArrayNumber: + items: + items: + type: number + type: array + type: array + type: object + EnumArrays: + properties: + just_symbol: + $ref: "#/components/schemas/EnumArrays_just_symbol" + array_enum: + items: + $ref: "#/components/schemas/EnumArrays_array_enum_inner" + type: array + array_array_enum: + items: + items: + $ref: "#/components/schemas/EnumArrays_array_array_enum_inner_inner" + type: array + type: array + type: object + OuterEnum: + enum: + - placed + - approved + - delivered + type: string + OuterComposite: + example: + my_string: my_string + my_number: 0.8008281904610115 + my_boolean: true + properties: + my_number: + type: number + my_string: + type: string + my_boolean: + type: boolean + x-codegen-body-parameter-name: boolean_post_body + type: object + OuterNumber: + type: number + OuterString: + type: string + OuterBoolean: + type: boolean + x-codegen-body-parameter-name: boolean_post_body + findPetsByStatus_status_parameter_inner: + default: available + enum: + - available + - pending + - sold + type: string + updatePetWithForm_request: + properties: + name: + description: Updated name of the pet + type: string + status: + description: Updated status of the pet + type: string + type: object + uploadFile_request: + properties: + additionalMetadata: + description: Additional data to pass to server + type: string + file: + description: file to upload + format: binary + type: string + type: object + testEnumParameters_request_enum_form_string: + default: -efg + description: Form parameter enum test (string) + enum: + - _abc + - -efg + - (xyz) + type: string + testEnumParameters_request: + properties: + enum_form_string: + $ref: "#/components/schemas/testEnumParameters_request_enum_form_string" + type: object + testEnumParameters_enum_header_string_array_parameter_inner: + default: $ + enum: + - '>' + - $ + type: string + testEnumParameters_enum_header_string_parameter: + default: -efg + enum: + - _abc + - -efg + - (xyz) + type: string + testEnumParameters_enum_query_integer_parameter: + enum: + - 1 + - -2 + format: int32 + type: integer + testEnumParameters_enum_query_double_parameter: + enum: + - 1.1 + - -1.2 + format: double + type: number + testEndpointParameters_request: + properties: + integer: + description: None + format: int32 + maximum: 100 + minimum: 10 + type: integer + int32: + description: None + format: int32 + maximum: 200 + minimum: 20 + type: integer + int64: + description: None + format: int64 + type: integer + number: + description: None + maximum: 543.2 + minimum: 32.1 + type: number + float: + description: None + format: float + maximum: 987.6 + type: number + double: + description: None + format: double + maximum: 123.4 + minimum: 67.8 + type: number + string: + description: None + pattern: "/[a-z]/i" + type: string + pattern_without_delimiter: + description: None + pattern: "^[A-Z].*" + type: string + byte: + description: None + format: byte + type: string + binary: + description: None + format: binary + type: string + date: + description: None + format: date + type: string + dateTime: + description: None + format: date-time + type: string + password: + description: None + format: password + maxLength: 64 + minLength: 10 + type: string + callback: + description: None + type: string + required: + - byte + - double + - number + - pattern_without_delimiter + type: object + testJsonFormData_request: + properties: + param: + description: field1 + type: string + param2: + description: field2 + type: string + required: + - param + - param2 + type: object + Order_status: + description: Order Status + enum: + - placed + - approved + - delivered + type: string + Pet_status: + description: pet status in the store + enum: + - available + - pending + - sold + type: string + Enum_Test_enum_string: + enum: + - UPPER + - lower + - "" + type: string + Enum_Test_enum_integer: + enum: + - 1 + - -1 + format: int32 + type: integer + MapTest_map_map_of_enum_value_value: + enum: + - UPPER + - lower + type: string + EnumArrays_just_symbol: + enum: + - '>=' + - $ + type: string + EnumArrays_array_enum_inner: + enum: + - fish + - crab + type: string + EnumArrays_array_array_enum_inner_inner: + enum: + - Cat + - Dog + type: string + securitySchemes: + petstore_auth: + flows: + implicit: + authorizationUrl: http://petstore.swagger.io/api/oauth/dialog + scopes: + write:pets: modify pets in your account + read:pets: read your pets + type: oauth2 + api_key: + in: header + name: api_key + type: apiKey + api_key_query: + in: query + name: api_key_query + type: apiKey + http_basic_test: + scheme: basic + type: http +x-original-swagger-version: "2.0" + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs new file mode 100644 index 000000000000..9141802f5891 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs @@ -0,0 +1,1153 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use dialoguer::Confirm; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use petstore_with_fake_endpoints_models_for_testing::{ + models, ApiNoContext, Client, ContextWrapperExt, + TestSpecialTagsResponse, + Call123exampleResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + FakeResponseWithNumericalDescriptionResponse, + TestBodyWithQueryParamsResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + HyphenParamResponse, + TestClassnameResponse, + AddPetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + UpdatePetResponse, + DeletePetResponse, + GetPetByIdResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + GetInventoryResponse, + PlaceOrderResponse, + DeleteOrderResponse, + GetOrderByIdResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + LoginUserResponse, + LogoutUserResponse, + DeleteUserResponse, + GetUserByNameResponse, + UpdateUserResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "OpenAPI Petstore", + version = "1.0.0", + about = "CLI access to OpenAPI Petstore" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, + + /// Don't ask for any confirmation prompts + #[allow(dead_code)] + #[structopt(short, long)] + force: bool, + + /// Bearer token if used for authentication + #[structopt(env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_BEARER_TOKEN", hide_env_values = true)] + bearer_token: Option, +} + +#[derive(StructOpt, Debug)] +enum Operation { + /// To test special tags + TestSpecialTags { + /// client model + #[structopt(parse(try_from_str = parse_json))] + body: models::Client, + }, + Call123example { + }, + FakeOuterBooleanSerialize { + /// Input boolean as post body + #[structopt(parse(try_from_str = parse_json))] + body: Option, + }, + FakeOuterCompositeSerialize { + /// Input composite as post body + #[structopt(parse(try_from_str = parse_json))] + body: Option, + }, + FakeOuterNumberSerialize { + /// Input number as post body + #[structopt(parse(try_from_str = parse_json))] + body: Option, + }, + FakeOuterStringSerialize { + /// Input string as post body + #[structopt(parse(try_from_str = parse_json))] + body: Option, + }, + FakeResponseWithNumericalDescription { + }, + TestBodyWithQueryParams { + query: String, + #[structopt(parse(try_from_str = parse_json))] + body: models::User, + }, + /// To test \"client\" model + TestClientModel { + /// client model + #[structopt(parse(try_from_str = parse_json))] + body: models::Client, + }, + /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + TestEndpointParameters { + /// None + number: f64, + /// None + double: f64, + /// None + pattern_without_delimiter: String, + /// None + #[structopt(parse(try_from_str = parse_json))] + byte: swagger::ByteArray, + /// None + integer: Option, + /// None + int32: Option, + /// None + int64: Option, + /// None + float: Option, + /// None + string: Option, + /// None + #[structopt(parse(try_from_str = parse_json))] + binary: Option, + /// None + date: Option, + /// None + date_time: Option>, + /// None + password: Option, + /// None + callback: Option, + }, + /// To test enum parameters + TestEnumParameters { + /// Header parameter enum test (string array) + #[structopt(parse(try_from_str = parse_json), long)] + enum_header_string_array: Option>, + /// Header parameter enum test (string) + #[structopt(parse(try_from_str = parse_json))] + enum_header_string: Option, + /// Query parameter enum test (string array) + #[structopt(parse(try_from_str = parse_json), long)] + enum_query_string_array: Option>, + /// Query parameter enum test (string) + #[structopt(parse(try_from_str = parse_json))] + enum_query_string: Option, + /// Query parameter enum test (double) + #[structopt(parse(try_from_str = parse_json))] + enum_query_integer: Option, + /// Query parameter enum test (double) + #[structopt(parse(try_from_str = parse_json))] + enum_query_double: Option, + #[structopt(parse(try_from_str = parse_json))] + enum_form_string: Option, + }, + /// test inline additionalProperties + TestInlineAdditionalProperties { + /// request body + #[structopt(parse(try_from_str = parse_json))] + param: std::collections::HashMap, + }, + /// test json serialization of form data + TestJsonFormData { + /// field1 + param: String, + /// field2 + param2: String, + }, + HyphenParam { + /// Parameter with hyphen in name + hyphen_param: String, + }, + /// To test class name in snake case + TestClassname { + /// client model + #[structopt(parse(try_from_str = parse_json))] + body: models::Client, + }, + /// Add a new pet to the store + AddPet { + /// Pet object that needs to be added to the store + #[structopt(parse(try_from_str = parse_json))] + body: models::Pet, + }, + /// Finds Pets by status + FindPetsByStatus { + /// Status values that need to be considered for filter + #[structopt(parse(try_from_str = parse_json), long)] + status: Vec, + }, + /// Finds Pets by tags + FindPetsByTags { + /// Tags to filter by + #[structopt(parse(try_from_str = parse_json), long)] + tags: Vec, + }, + /// Update an existing pet + UpdatePet { + /// Pet object that needs to be added to the store + #[structopt(parse(try_from_str = parse_json))] + body: models::Pet, + }, + /// Deletes a pet + DeletePet { + /// Pet id to delete + pet_id: i64, + api_key: Option, + }, + /// Find pet by ID + GetPetById { + /// ID of pet to return + pet_id: i64, + }, + /// Updates a pet in the store with form data + UpdatePetWithForm { + /// ID of pet that needs to be updated + pet_id: i64, + /// Updated name of the pet + name: Option, + /// Updated status of the pet + status: Option, + }, + /// uploads an image + UploadFile { + /// ID of pet to update + pet_id: i64, + /// Additional data to pass to server + additional_metadata: Option, + /// file to upload + #[structopt(parse(try_from_str = parse_json))] + file: Option, + }, + /// Returns pet inventories by status + GetInventory { + }, + /// Place an order for a pet + PlaceOrder { + /// order placed for purchasing the pet + #[structopt(parse(try_from_str = parse_json))] + body: models::Order, + }, + /// Delete purchase order by ID + DeleteOrder { + /// ID of the order that needs to be deleted + order_id: String, + }, + /// Find purchase order by ID + GetOrderById { + /// ID of pet that needs to be fetched + order_id: i64, + }, + /// Create user + CreateUser { + /// Created user object + #[structopt(parse(try_from_str = parse_json))] + body: models::User, + }, + /// Creates list of users with given input array + CreateUsersWithArrayInput { + /// List of user object + #[structopt(parse(try_from_str = parse_json), long)] + body: Vec, + }, + /// Creates list of users with given input array + CreateUsersWithListInput { + /// List of user object + #[structopt(parse(try_from_str = parse_json), long)] + body: Vec, + }, + /// Logs user into the system + LoginUser { + /// The user name for login + username: String, + /// The password for login in clear text + password: String, + }, + /// Logs out current logged in user session + LogoutUser { + }, + /// Delete user + DeleteUser { + /// The name that needs to be deleted + username: String, + }, + /// Get user by user name + GetUserByName { + /// The name that needs to be fetched. Use user1 for testing. + username: String, + }, + /// Updated user + UpdateUser { + /// name that need to be deleted + username: String, + /// Updated user object + #[structopt(parse(try_from_str = parse_json))] + body: models::User, + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let mut auth_data: Option = None; + + if let Some(ref bearer_token) = args.bearer_token { + debug!("Using bearer token"); + auth_data = Some(AuthData::bearer(bearer_token)); + } + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::TestSpecialTags { + body, + } => { + info!("Performing a TestSpecialTags request"); + + let result = client.test_special_tags( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestSpecialTagsResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::Call123example { + } => { + info!("Performing a Call123example request"); + + let result = client.call123example( + ).await?; + debug!("Result: {:?}", result); + + match result { + Call123exampleResponse::Success + => "Success\n".to_string() + , + } + } + Operation::FakeOuterBooleanSerialize { + body, + } => { + info!("Performing a FakeOuterBooleanSerialize request"); + + let result = client.fake_outer_boolean_serialize( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + FakeOuterBooleanSerializeResponse::OutputBoolean + (body) + => "OutputBoolean\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::FakeOuterCompositeSerialize { + body, + } => { + info!("Performing a FakeOuterCompositeSerialize request"); + + let result = client.fake_outer_composite_serialize( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + FakeOuterCompositeSerializeResponse::OutputComposite + (body) + => "OutputComposite\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::FakeOuterNumberSerialize { + body, + } => { + info!("Performing a FakeOuterNumberSerialize request"); + + let result = client.fake_outer_number_serialize( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + FakeOuterNumberSerializeResponse::OutputNumber + (body) + => "OutputNumber\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::FakeOuterStringSerialize { + body, + } => { + info!("Performing a FakeOuterStringSerialize request"); + + let result = client.fake_outer_string_serialize( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + FakeOuterStringSerializeResponse::OutputString + (body) + => "OutputString\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::FakeResponseWithNumericalDescription { + } => { + info!("Performing a FakeResponseWithNumericalDescription request"); + + let result = client.fake_response_with_numerical_description( + ).await?; + debug!("Result: {:?}", result); + + match result { + FakeResponseWithNumericalDescriptionResponse::Status200 + => "Status200\n".to_string() + , + } + } + Operation::TestBodyWithQueryParams { + query, + body, + } => { + info!("Performing a TestBodyWithQueryParams request"); + + let result = client.test_body_with_query_params( + query, + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestBodyWithQueryParamsResponse::Success + => "Success\n".to_string() + , + } + } + Operation::TestClientModel { + body, + } => { + info!("Performing a TestClientModel request"); + + let result = client.test_client_model( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestClientModelResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::TestEndpointParameters { + number, + double, + pattern_without_delimiter, + byte, + integer, + int32, + int64, + float, + string, + binary, + date, + date_time, + password, + callback, + } => { + info!("Performing a TestEndpointParameters request"); + + let result = client.test_endpoint_parameters( + number, + double, + pattern_without_delimiter, + byte, + integer, + int32, + int64, + float, + string, + binary, + date, + date_time, + password, + callback, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestEndpointParametersResponse::InvalidUsernameSupplied + => "InvalidUsernameSupplied\n".to_string() + , + TestEndpointParametersResponse::UserNotFound + => "UserNotFound\n".to_string() + , + } + } + Operation::TestEnumParameters { + enum_header_string_array, + enum_header_string, + enum_query_string_array, + enum_query_string, + enum_query_integer, + enum_query_double, + enum_form_string, + } => { + info!("Performing a TestEnumParameters request"); + + let result = client.test_enum_parameters( + enum_header_string_array.as_ref(), + enum_header_string, + enum_query_string_array.as_ref(), + enum_query_string, + enum_query_integer, + enum_query_double, + enum_form_string, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestEnumParametersResponse::InvalidRequest + => "InvalidRequest\n".to_string() + , + TestEnumParametersResponse::NotFound + => "NotFound\n".to_string() + , + } + } + Operation::TestInlineAdditionalProperties { + param, + } => { + info!("Performing a TestInlineAdditionalProperties request"); + + let result = client.test_inline_additional_properties( + param, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::TestJsonFormData { + param, + param2, + } => { + info!("Performing a TestJsonFormData request"); + + let result = client.test_json_form_data( + param, + param2, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestJsonFormDataResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::HyphenParam { + hyphen_param, + } => { + info!("Performing a HyphenParam request on {:?}", ( + &hyphen_param + )); + + let result = client.hyphen_param( + hyphen_param, + ).await?; + debug!("Result: {:?}", result); + + match result { + HyphenParamResponse::Success + => "Success\n".to_string() + , + } + } + Operation::TestClassname { + body, + } => { + info!("Performing a TestClassname request"); + + let result = client.test_classname( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + TestClassnameResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::AddPet { + body, + } => { + info!("Performing a AddPet request"); + + let result = client.add_pet( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + AddPetResponse::InvalidInput + => "InvalidInput\n".to_string() + , + } + } + Operation::FindPetsByStatus { + status, + } => { + info!("Performing a FindPetsByStatus request"); + + let result = client.find_pets_by_status( + status.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + FindPetsByStatusResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + FindPetsByStatusResponse::InvalidStatusValue + => "InvalidStatusValue\n".to_string() + , + } + } + Operation::FindPetsByTags { + tags, + } => { + info!("Performing a FindPetsByTags request"); + + let result = client.find_pets_by_tags( + tags.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + FindPetsByTagsResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + FindPetsByTagsResponse::InvalidTagValue + => "InvalidTagValue\n".to_string() + , + } + } + Operation::UpdatePet { + body, + } => { + info!("Performing a UpdatePet request"); + + let result = client.update_pet( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + UpdatePetResponse::InvalidIDSupplied + => "InvalidIDSupplied\n".to_string() + , + UpdatePetResponse::PetNotFound + => "PetNotFound\n".to_string() + , + UpdatePetResponse::ValidationException + => "ValidationException\n".to_string() + , + } + } + Operation::DeletePet { + pet_id, + api_key, + } => { + prompt(args.force, "This will delete the given entry, are you sure?")?; + info!("Performing a DeletePet request on {:?}", ( + &pet_id + )); + + let result = client.delete_pet( + pet_id, + api_key, + ).await?; + debug!("Result: {:?}", result); + + match result { + DeletePetResponse::InvalidPetValue + => "InvalidPetValue\n".to_string() + , + } + } + Operation::GetPetById { + pet_id, + } => { + info!("Performing a GetPetById request on {:?}", ( + &pet_id + )); + + let result = client.get_pet_by_id( + pet_id, + ).await?; + debug!("Result: {:?}", result); + + match result { + GetPetByIdResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + GetPetByIdResponse::InvalidIDSupplied + => "InvalidIDSupplied\n".to_string() + , + GetPetByIdResponse::PetNotFound + => "PetNotFound\n".to_string() + , + } + } + Operation::UpdatePetWithForm { + pet_id, + name, + status, + } => { + info!("Performing a UpdatePetWithForm request on {:?}", ( + &pet_id + )); + + let result = client.update_pet_with_form( + pet_id, + name, + status, + ).await?; + debug!("Result: {:?}", result); + + match result { + UpdatePetWithFormResponse::InvalidInput + => "InvalidInput\n".to_string() + , + } + } + Operation::UploadFile { + pet_id, + additional_metadata, + file, + } => { + info!("Performing a UploadFile request on {:?}", ( + &pet_id + )); + + let result = client.upload_file( + pet_id, + additional_metadata, + file, + ).await?; + debug!("Result: {:?}", result); + + match result { + UploadFileResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::GetInventory { + } => { + info!("Performing a GetInventory request"); + + let result = client.get_inventory( + ).await?; + debug!("Result: {:?}", result); + + match result { + GetInventoryResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::PlaceOrder { + body, + } => { + info!("Performing a PlaceOrder request"); + + let result = client.place_order( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + PlaceOrderResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + PlaceOrderResponse::InvalidOrder + => "InvalidOrder\n".to_string() + , + } + } + Operation::DeleteOrder { + order_id, + } => { + prompt(args.force, "This will delete the given entry, are you sure?")?; + info!("Performing a DeleteOrder request on {:?}", ( + &order_id + )); + + let result = client.delete_order( + order_id, + ).await?; + debug!("Result: {:?}", result); + + match result { + DeleteOrderResponse::InvalidIDSupplied + => "InvalidIDSupplied\n".to_string() + , + DeleteOrderResponse::OrderNotFound + => "OrderNotFound\n".to_string() + , + } + } + Operation::GetOrderById { + order_id, + } => { + info!("Performing a GetOrderById request on {:?}", ( + &order_id + )); + + let result = client.get_order_by_id( + order_id, + ).await?; + debug!("Result: {:?}", result); + + match result { + GetOrderByIdResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + GetOrderByIdResponse::InvalidIDSupplied + => "InvalidIDSupplied\n".to_string() + , + GetOrderByIdResponse::OrderNotFound + => "OrderNotFound\n".to_string() + , + } + } + Operation::CreateUser { + body, + } => { + info!("Performing a CreateUser request"); + + let result = client.create_user( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + CreateUserResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::CreateUsersWithArrayInput { + body, + } => { + info!("Performing a CreateUsersWithArrayInput request"); + + let result = client.create_users_with_array_input( + body.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + CreateUsersWithArrayInputResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::CreateUsersWithListInput { + body, + } => { + info!("Performing a CreateUsersWithListInput request"); + + let result = client.create_users_with_list_input( + body.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + CreateUsersWithListInputResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::LoginUser { + username, + password, + } => { + info!("Performing a LoginUser request"); + + let result = client.login_user( + username, + password, + ).await?; + debug!("Result: {:?}", result); + + match result { + LoginUserResponse::SuccessfulOperation + { + body, + x_rate_limit, + x_expires_after, + } + => "SuccessfulOperation\n".to_string() + + + &format!("body: {}\n", serde_json::to_string_pretty(&body)?) + + &format!( + "x_rate_limit: {}\n", + serde_json::to_string_pretty(&x_rate_limit)? + ) + + &format!( + "x_expires_after: {}\n", + serde_json::to_string_pretty(&x_expires_after)? + ), + LoginUserResponse::InvalidUsername + => "InvalidUsername\n".to_string() + , + } + } + Operation::LogoutUser { + } => { + info!("Performing a LogoutUser request"); + + let result = client.logout_user( + ).await?; + debug!("Result: {:?}", result); + + match result { + LogoutUserResponse::SuccessfulOperation + => "SuccessfulOperation\n".to_string() + , + } + } + Operation::DeleteUser { + username, + } => { + prompt(args.force, "This will delete the given entry, are you sure?")?; + info!("Performing a DeleteUser request on {:?}", ( + &username + )); + + let result = client.delete_user( + username, + ).await?; + debug!("Result: {:?}", result); + + match result { + DeleteUserResponse::InvalidUsernameSupplied + => "InvalidUsernameSupplied\n".to_string() + , + DeleteUserResponse::UserNotFound + => "UserNotFound\n".to_string() + , + } + } + Operation::GetUserByName { + username, + } => { + info!("Performing a GetUserByName request on {:?}", ( + &username + )); + + let result = client.get_user_by_name( + username, + ).await?; + debug!("Result: {:?}", result); + + match result { + GetUserByNameResponse::SuccessfulOperation + (body) + => "SuccessfulOperation\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + GetUserByNameResponse::InvalidUsernameSupplied + => "InvalidUsernameSupplied\n".to_string() + , + GetUserByNameResponse::UserNotFound + => "UserNotFound\n".to_string() + , + } + } + Operation::UpdateUser { + username, + body, + } => { + info!("Performing a UpdateUser request on {:?}", ( + &username + )); + + let result = client.update_user( + username, + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + UpdateUserResponse::InvalidUserSupplied + => "InvalidUserSupplied\n".to_string() + , + UpdateUserResponse::UserNotFound + => "UserNotFound\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +fn prompt(force: bool, text: &str) -> Result<()> { + if force || Confirm::new().with_prompt(text).interact()? { + Ok(()) + } else { + Err(anyhow!("Aborting")) + } +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AdditionalPropertiesClass.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AdditionalPropertiesClass.md new file mode 100644 index 000000000000..2d62aa0fba99 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AdditionalPropertiesClass.md @@ -0,0 +1,11 @@ +# AdditionalPropertiesClass + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**map_property** | **std::collections::HashMap** | | [optional] [default to None] +**map_of_map_property** | [**std::collections::HashMap>**](map.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Animal.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Animal.md new file mode 100644 index 000000000000..d745c9d79e73 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Animal.md @@ -0,0 +1,11 @@ +# Animal + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**class_name** | **String** | | +**color** | **String** | | [optional] [default to Some("red".to_string())] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AnimalFarm.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AnimalFarm.md new file mode 100644 index 000000000000..df6bab21dae8 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/AnimalFarm.md @@ -0,0 +1,9 @@ +# AnimalFarm + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/multipart-v3/docs/InlineRequest.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ApiResponse.md similarity index 59% rename from samples/server/petstore/rust-server/output/multipart-v3/docs/InlineRequest.md rename to samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ApiResponse.md index 36896e0eec68..de9b8f1d1199 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/docs/InlineRequest.md +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ApiResponse.md @@ -1,10 +1,11 @@ -# InlineRequest +# ApiResponse ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**binary1** | [***swagger::ByteArray**](file.md) | | [optional] [default to None] -**binary2** | [***swagger::ByteArray**](file.md) | | [optional] [default to None] +**code** | **i32** | | [optional] [default to None] +**r#type** | **String** | | [optional] [default to None] +**message** | **String** | | [optional] [default to None] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfArrayOfNumberOnly.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfArrayOfNumberOnly.md new file mode 100644 index 000000000000..47bc63435582 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfArrayOfNumberOnly.md @@ -0,0 +1,10 @@ +# ArrayOfArrayOfNumberOnly + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**array_array_number** | [**Vec>**](array.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfNumberOnly.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfNumberOnly.md new file mode 100644 index 000000000000..ceb5c38f40db --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayOfNumberOnly.md @@ -0,0 +1,10 @@ +# ArrayOfNumberOnly + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**array_number** | **Vec** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayTest.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayTest.md new file mode 100644 index 000000000000..b563bd578c86 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ArrayTest.md @@ -0,0 +1,13 @@ +# ArrayTest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**array_of_string** | **Vec** | | [optional] [default to None] +**array_array_of_integer** | [**Vec>**](array.md) | | [optional] [default to None] +**array_array_of_model** | [**Vec>**](array.md) | | [optional] [default to None] +**array_of_enum** | [**Vec**](MapTest_map_map_of_enum_value_value.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Capitalization.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Capitalization.md new file mode 100644 index 000000000000..1ab61d603c67 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Capitalization.md @@ -0,0 +1,15 @@ +# Capitalization + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**small_camel** | **String** | | [optional] [default to None] +**capital_camel** | **String** | | [optional] [default to None] +**small_snake** | **String** | | [optional] [default to None] +**capital_snake** | **String** | | [optional] [default to None] +**sca_eth_flow_points** | **String** | | [optional] [default to None] +**att_name** | **String** | Name of the pet | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Cat.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Cat.md new file mode 100644 index 000000000000..23e9617aa5e0 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Cat.md @@ -0,0 +1,12 @@ +# Cat + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**class_name** | **String** | | +**color** | **String** | | [optional] [default to Some("red".to_string())] +**declawed** | **bool** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Category.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Category.md new file mode 100644 index 000000000000..69cdf581c1a1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Category.md @@ -0,0 +1,11 @@ +# Category + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **i64** | | [optional] [default to None] +**name** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ClassModel.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ClassModel.md new file mode 100644 index 000000000000..5fabf1947491 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ClassModel.md @@ -0,0 +1,10 @@ +# ClassModel + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_class** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Client.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Client.md new file mode 100644 index 000000000000..314f9a1e3d34 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Client.md @@ -0,0 +1,10 @@ +# Client + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**client** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Dog.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Dog.md new file mode 100644 index 000000000000..792fb2f9a281 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Dog.md @@ -0,0 +1,12 @@ +# Dog + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**class_name** | **String** | | +**color** | **String** | | [optional] [default to Some("red".to_string())] +**breed** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelNameRightSquareBracket.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelNameRightSquareBracket.md new file mode 100644 index 000000000000..6719abdbbfd6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelNameRightSquareBracket.md @@ -0,0 +1,10 @@ +# DollarSpecialLeftSquareBracketModelNameRightSquareBracket + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**dollar_special_left_square_bracket_property_name_right_square_bracket** | **i64** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket.md new file mode 100644 index 000000000000..082df970a270 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket.md @@ -0,0 +1,10 @@ +# DollarSpecialLeftSquareBracketModelPeriodNameRightSquareBracket + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**dollar_special_left_square_bracket_property_period_name_right_square_bracket** | **i64** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArrays.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArrays.md new file mode 100644 index 000000000000..f829bdd18ce1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArrays.md @@ -0,0 +1,12 @@ +# EnumArrays + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**just_symbol** | [***models::EnumArraysJustSymbol**](EnumArrays_just_symbol.md) | | [optional] [default to None] +**array_enum** | [**Vec**](EnumArrays_array_enum_inner.md) | | [optional] [default to None] +**array_array_enum** | [**Vec>**](array.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayArrayEnumInnerInner.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayArrayEnumInnerInner.md new file mode 100644 index 000000000000..e811ef49a7b2 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayArrayEnumInnerInner.md @@ -0,0 +1,9 @@ +# EnumArraysArrayArrayEnumInnerInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayEnumInner.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayEnumInner.md new file mode 100644 index 000000000000..c976bdf93495 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysArrayEnumInner.md @@ -0,0 +1,9 @@ +# EnumArraysArrayEnumInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysJustSymbol.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysJustSymbol.md new file mode 100644 index 000000000000..ebdd890812bd --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumArraysJustSymbol.md @@ -0,0 +1,9 @@ +# EnumArraysJustSymbol + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumClass.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumClass.md new file mode 100644 index 000000000000..67f017becd0c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumClass.md @@ -0,0 +1,9 @@ +# EnumClass + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTest.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTest.md new file mode 100644 index 000000000000..cf89b12718d7 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTest.md @@ -0,0 +1,14 @@ +# EnumTest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**enum_string** | [***models::EnumTestEnumString**](Enum_Test_enum_string.md) | | [optional] [default to None] +**enum_string_required** | [***models::EnumTestEnumString**](Enum_Test_enum_string.md) | | +**enum_integer** | [***models::EnumTestEnumInteger**](Enum_Test_enum_integer.md) | | [optional] [default to None] +**enum_number** | [***models::TestEnumParametersEnumQueryDoubleParameter**](testEnumParameters_enum_query_double_parameter.md) | | [optional] [default to None] +**outer_enum** | [***models::OuterEnum**](OuterEnum.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumInteger.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumInteger.md new file mode 100644 index 000000000000..888dc92561e9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumInteger.md @@ -0,0 +1,9 @@ +# EnumTestEnumInteger + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumString.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumString.md new file mode 100644 index 000000000000..9c8ada5e8f52 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/EnumTestEnumString.md @@ -0,0 +1,9 @@ +# EnumTestEnumString + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FindPetsByStatusStatusParameterInner.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FindPetsByStatusStatusParameterInner.md new file mode 100644 index 000000000000..eb650a9da349 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FindPetsByStatusStatusParameterInner.md @@ -0,0 +1,9 @@ +# FindPetsByStatusStatusParameterInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FormatTest.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FormatTest.md new file mode 100644 index 000000000000..ec568846bcbf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/FormatTest.md @@ -0,0 +1,22 @@ +# FormatTest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**integer** | **u8** | | [optional] [default to None] +**int32** | **u32** | | [optional] [default to None] +**int64** | **i64** | | [optional] [default to None] +**number** | **f64** | | +**float** | **f32** | | [optional] [default to None] +**double** | **f64** | | [optional] [default to None] +**string** | **String** | | [optional] [default to None] +**byte** | [***swagger::ByteArray**](ByteArray.md) | | +**binary** | [***swagger::ByteArray**](file.md) | | [optional] [default to None] +**date** | [***chrono::naive::NaiveDate**](date.md) | | +**date_time** | [**chrono::DateTime::**](DateTime.md) | | [optional] [default to None] +**uuid** | [***uuid::Uuid**](UUID.md) | | [optional] [default to None] +**password** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/HasOnlyReadOnly.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/HasOnlyReadOnly.md new file mode 100644 index 000000000000..0cbfaa812718 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/HasOnlyReadOnly.md @@ -0,0 +1,11 @@ +# HasOnlyReadOnly + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bar** | **String** | | [optional] [readonly] [default to None] +**foo** | **String** | | [optional] [readonly] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/List.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/List.md new file mode 100644 index 000000000000..6d44dfc5a56e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/List.md @@ -0,0 +1,10 @@ +# List + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**param_123_list** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTest.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTest.md new file mode 100644 index 000000000000..590eae909b98 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTest.md @@ -0,0 +1,12 @@ +# MapTest + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**map_map_of_string** | [**std::collections::HashMap>**](map.md) | | [optional] [default to None] +**map_map_of_enum** | [**std::collections::HashMap>**](map.md) | | [optional] [default to None] +**map_of_enum_string** | [**std::collections::HashMap**](MapTest_map_map_of_enum_value_value.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTestMapMapOfEnumValueValue.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTestMapMapOfEnumValueValue.md new file mode 100644 index 000000000000..98f437d887b9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MapTestMapMapOfEnumValueValue.md @@ -0,0 +1,9 @@ +# MapTestMapMapOfEnumValueValue + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MixedPropertiesAndAdditionalPropertiesClass.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MixedPropertiesAndAdditionalPropertiesClass.md new file mode 100644 index 000000000000..7ef09baf7a2e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/MixedPropertiesAndAdditionalPropertiesClass.md @@ -0,0 +1,12 @@ +# MixedPropertiesAndAdditionalPropertiesClass + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**uuid** | [***uuid::Uuid**](UUID.md) | | [optional] [default to None] +**date_time** | [**chrono::DateTime::**](DateTime.md) | | [optional] [default to None] +**map** | [**std::collections::HashMap**](Animal.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Model200Response.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Model200Response.md new file mode 100644 index 000000000000..8f908f2940b7 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Model200Response.md @@ -0,0 +1,11 @@ +# Model200Response + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **i32** | | [optional] [default to None] +**class** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Name.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Name.md new file mode 100644 index 000000000000..506a2c288015 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Name.md @@ -0,0 +1,13 @@ +# Name + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**name** | **i32** | | +**snake_case** | **i32** | | [optional] [readonly] [default to None] +**property** | **String** | | [optional] [default to None] +**param_123_number** | **i32** | | [optional] [readonly] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/NumberOnly.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/NumberOnly.md new file mode 100644 index 000000000000..0738b5655ea1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/NumberOnly.md @@ -0,0 +1,10 @@ +# NumberOnly + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**just_number** | **f64** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectContainingObjectWithOnlyAdditionalProperties.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectContainingObjectWithOnlyAdditionalProperties.md new file mode 100644 index 000000000000..a1789bfff99b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectContainingObjectWithOnlyAdditionalProperties.md @@ -0,0 +1,10 @@ +# ObjectContainingObjectWithOnlyAdditionalProperties + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**inner** | [***models::ObjectWithOnlyAdditionalProperties**](ObjectWithOnlyAdditionalProperties.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectWithOnlyAdditionalProperties.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectWithOnlyAdditionalProperties.md new file mode 100644 index 000000000000..69bfa7af35d6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ObjectWithOnlyAdditionalProperties.md @@ -0,0 +1,9 @@ +# ObjectWithOnlyAdditionalProperties + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Order.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Order.md new file mode 100644 index 000000000000..ab8ebad2cefc --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Order.md @@ -0,0 +1,15 @@ +# Order + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **i64** | | [optional] [default to None] +**pet_id** | **i64** | | [optional] [default to None] +**quantity** | **i32** | | [optional] [default to None] +**ship_date** | [**chrono::DateTime::**](DateTime.md) | | [optional] [default to None] +**status** | [***models::OrderStatus**](Order_status.md) | | [optional] [default to None] +**complete** | **bool** | | [optional] [default to Some(false)] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OrderStatus.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OrderStatus.md new file mode 100644 index 000000000000..bf3cc64b90e6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OrderStatus.md @@ -0,0 +1,9 @@ +# OrderStatus + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterBoolean.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterBoolean.md new file mode 100644 index 000000000000..8b2433994745 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterBoolean.md @@ -0,0 +1,9 @@ +# OuterBoolean + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterComposite.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterComposite.md new file mode 100644 index 000000000000..2c59baaad62d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterComposite.md @@ -0,0 +1,12 @@ +# OuterComposite + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**my_number** | **f64** | | [optional] [default to None] +**my_string** | **String** | | [optional] [default to None] +**my_boolean** | **bool** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterEnum.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterEnum.md new file mode 100644 index 000000000000..06d413b01680 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterEnum.md @@ -0,0 +1,9 @@ +# OuterEnum + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterNumber.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterNumber.md new file mode 100644 index 000000000000..8aa37f329bd4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterNumber.md @@ -0,0 +1,9 @@ +# OuterNumber + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterString.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterString.md new file mode 100644 index 000000000000..9ccaadaf98df --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/OuterString.md @@ -0,0 +1,9 @@ +# OuterString + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Pet.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Pet.md new file mode 100644 index 000000000000..b82e37a480ed --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Pet.md @@ -0,0 +1,15 @@ +# Pet + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **i64** | | [optional] [default to None] +**category** | [***models::Category**](Category.md) | | [optional] [default to None] +**name** | **String** | | +**photo_urls** | **Vec** | | +**tags** | [**Vec**](Tag.md) | | [optional] [default to None] +**status** | [***models::PetStatus**](Pet_status.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/PetStatus.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/PetStatus.md new file mode 100644 index 000000000000..a052000ba751 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/PetStatus.md @@ -0,0 +1,9 @@ +# PetStatus + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ReadOnlyFirst.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ReadOnlyFirst.md new file mode 100644 index 000000000000..f2a31640b25b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/ReadOnlyFirst.md @@ -0,0 +1,11 @@ +# ReadOnlyFirst + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**bar** | **String** | | [optional] [readonly] [default to None] +**baz** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Return.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Return.md new file mode 100644 index 000000000000..f3ed30f889f4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Return.md @@ -0,0 +1,10 @@ +# Return + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**r#return** | **i32** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Tag.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Tag.md new file mode 100644 index 000000000000..2a2a97d3a78e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/Tag.md @@ -0,0 +1,11 @@ +# Tag + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **i64** | | [optional] [default to None] +**name** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringArrayParameterInner.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringArrayParameterInner.md new file mode 100644 index 000000000000..0035e028ccaf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringArrayParameterInner.md @@ -0,0 +1,9 @@ +# TestEnumParametersEnumHeaderStringArrayParameterInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringParameter.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringParameter.md new file mode 100644 index 000000000000..2fae5705bd58 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumHeaderStringParameter.md @@ -0,0 +1,9 @@ +# TestEnumParametersEnumHeaderStringParameter + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryDoubleParameter.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryDoubleParameter.md new file mode 100644 index 000000000000..2945c91e223c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryDoubleParameter.md @@ -0,0 +1,9 @@ +# TestEnumParametersEnumQueryDoubleParameter + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryIntegerParameter.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryIntegerParameter.md new file mode 100644 index 000000000000..95ad64f68da6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersEnumQueryIntegerParameter.md @@ -0,0 +1,9 @@ +# TestEnumParametersEnumQueryIntegerParameter + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersRequestEnumFormString.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersRequestEnumFormString.md new file mode 100644 index 000000000000..63a0cf68d6a9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/TestEnumParametersRequestEnumFormString.md @@ -0,0 +1,9 @@ +# TestEnumParametersRequestEnumFormString + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/User.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/User.md new file mode 100644 index 000000000000..77f476fe3c80 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/User.md @@ -0,0 +1,17 @@ +# User + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **i64** | | [optional] [default to None] +**username** | **String** | | [optional] [default to None] +**first_name** | **String** | | [optional] [default to None] +**last_name** | **String** | | [optional] [default to None] +**email** | **String** | | [optional] [default to None] +**password** | **String** | | [optional] [default to None] +**phone** | **String** | | [optional] [default to None] +**user_status** | **i32** | User Status | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/another_fake_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/another_fake_api.md new file mode 100644 index 000000000000..72ff87f1a313 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/another_fake_api.md @@ -0,0 +1,36 @@ +# another_fake_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**test_special_tags**](another_fake_api.md#test_special_tags) | **PATCH** /another-fake/dummy | To test special tags + + +# **test_special_tags** +> models::Client test_special_tags(body) +To test special tags + +To test special tags + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**Client**](Client.md)| client model | + +### Return type + +[**models::Client**](Client.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_api.md new file mode 100644 index 000000000000..27c59de54b24 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_api.md @@ -0,0 +1,424 @@ +# fake_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**123example**](fake_api.md#123example) | **GET** /fake/operation-with-numeric-id | +**fakeOuterBooleanSerialize**](fake_api.md#fakeOuterBooleanSerialize) | **POST** /fake/outer/boolean | +**fakeOuterCompositeSerialize**](fake_api.md#fakeOuterCompositeSerialize) | **POST** /fake/outer/composite | +**fakeOuterNumberSerialize**](fake_api.md#fakeOuterNumberSerialize) | **POST** /fake/outer/number | +**fakeOuterStringSerialize**](fake_api.md#fakeOuterStringSerialize) | **POST** /fake/outer/string | +**fake_response_with_numerical_description**](fake_api.md#fake_response_with_numerical_description) | **GET** /fake/response-with-numerical-description | +**testBodyWithQueryParams**](fake_api.md#testBodyWithQueryParams) | **PUT** /fake/body-with-query-params | +**testClientModel**](fake_api.md#testClientModel) | **PATCH** /fake | To test \"client\" model +**testEndpointParameters**](fake_api.md#testEndpointParameters) | **POST** /fake | Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 +**testEnumParameters**](fake_api.md#testEnumParameters) | **GET** /fake | To test enum parameters +**testInlineAdditionalProperties**](fake_api.md#testInlineAdditionalProperties) | **POST** /fake/inline-additionalProperties | test inline additionalProperties +**testJsonFormData**](fake_api.md#testJsonFormData) | **GET** /fake/jsonFormData | test json serialization of form data +**hyphenParam**](fake_api.md#hyphenParam) | **GET** /fake/hyphenParam/{hyphen-param} | + + +# **123example** +> 123example() + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **fakeOuterBooleanSerialize** +> bool fakeOuterBooleanSerialize(optional) + + +Test serialization of outer boolean types + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**boolean**](boolean.md)| Input boolean as post body | + +### Return type + +[**bool**](boolean.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **fakeOuterCompositeSerialize** +> models::OuterComposite fakeOuterCompositeSerialize(optional) + + +Test serialization of object with outer number type + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**OuterComposite**](OuterComposite.md)| Input composite as post body | + +### Return type + +[**models::OuterComposite**](OuterComposite.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **fakeOuterNumberSerialize** +> f64 fakeOuterNumberSerialize(optional) + + +Test serialization of outer number types + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**number**](number.md)| Input number as post body | + +### Return type + +[**f64**](number.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **fakeOuterStringSerialize** +> String fakeOuterStringSerialize(optional) + + +Test serialization of outer string types + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**string**](string.md)| Input string as post body | + +### Return type + +[**String**](string.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **fake_response_with_numerical_description** +> fake_response_with_numerical_description() + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testBodyWithQueryParams** +> testBodyWithQueryParams(query, body) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **query** | **String**| | + **body** | [**User**](User.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testClientModel** +> models::Client testClientModel(body) +To test \"client\" model + +To test \"client\" model + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**Client**](Client.md)| client model | + +### Return type + +[**models::Client**](Client.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testEndpointParameters** +> testEndpointParameters(ctx, number, double, pattern_without_delimiter, byte, optional) +Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + +Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **number** | **f64**| None | + **double** | **f64**| None | + **pattern_without_delimiter** | **String**| None | + **byte** | **swagger::ByteArray**| None | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **number** | **f64**| None | + **double** | **f64**| None | + **pattern_without_delimiter** | **String**| None | + **byte** | **swagger::ByteArray**| None | + **integer** | **i32**| None | + **int32** | **i32**| None | + **int64** | **i64**| None | + **float** | **f32**| None | + **string** | **String**| None | + **binary** | **swagger::ByteArray**| None | + **date** | **chrono::naive::NaiveDate**| None | + **date_time** | **chrono::DateTime::**| None | + **password** | **String**| None | + **callback** | **String**| None | + +### Return type + + (empty response body) + +### Authorization + +[http_basic_test](../README.md#http_basic_test) + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testEnumParameters** +> testEnumParameters(optional) +To test enum parameters + +To test enum parameters + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **enum_header_string_array** | [**models::TestEnumParametersEnumHeaderStringArrayParameterInner**](models::TestEnumParametersEnumHeaderStringArrayParameterInner.md)| Header parameter enum test (string array) | + **enum_header_string** | [****](.md)| Header parameter enum test (string) | + **enum_query_string_array** | [**models::TestEnumParametersEnumHeaderStringArrayParameterInner**](models::TestEnumParametersEnumHeaderStringArrayParameterInner.md)| Query parameter enum test (string array) | + **enum_query_string** | [****](.md)| Query parameter enum test (string) | + **enum_query_integer** | [****](.md)| Query parameter enum test (double) | + **enum_query_double** | [****](.md)| Query parameter enum test (double) | + **enum_form_string** | [**testEnumParameters_request_enum_form_string**](testEnumParameters_request_enum_form_string.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testInlineAdditionalProperties** +> testInlineAdditionalProperties(param) +test inline additionalProperties + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **param** | [**string**](string.md)| request body | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **testJsonFormData** +> testJsonFormData(param, param2) +test json serialization of form data + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **param** | **String**| field1 | + **param2** | **String**| field2 | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **hyphenParam** +> hyphenParam(hyphen_param) + + +To test hyphen in path parameter name + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **hyphen_param** | **String**| Parameter with hyphen in name | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_classname_tags123_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_classname_tags123_api.md new file mode 100644 index 000000000000..99f32c327cc4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/fake_classname_tags123_api.md @@ -0,0 +1,37 @@ +# fake_classname_tags123_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**testClassname**](fake_classname_tags123_api.md#testClassname) | **PATCH** /fake_classname_test | To test class name in snake case + + +# **testClassname** +> models::Client testClassname(ctx, body) +To test class name in snake case + +To test class name in snake case + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **body** | [**Client**](Client.md)| client model | + +### Return type + +[**models::Client**](Client.md) + +### Authorization + +[api_key_query](../README.md#api_key_query) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/pet_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/pet_api.md new file mode 100644 index 000000000000..26e6a98d32f4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/pet_api.md @@ -0,0 +1,259 @@ +# pet_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**addPet**](pet_api.md#addPet) | **POST** /pet | Add a new pet to the store +**findPetsByStatus**](pet_api.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status +**findPetsByTags**](pet_api.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags +**updatePet**](pet_api.md#updatePet) | **PUT** /pet | Update an existing pet +**deletePet**](pet_api.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet +**getPetById**](pet_api.md#getPetById) | **GET** /pet/{petId} | Find pet by ID +**updatePetWithForm**](pet_api.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data +**uploadFile**](pet_api.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image + + +# **addPet** +> addPet(ctx, body) +Add a new pet to the store + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **body** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | + +### Return type + + (empty response body) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: application/json, application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **findPetsByStatus** +> Vec findPetsByStatus(ctx, status) +Finds Pets by status + +Multiple status values can be provided with comma separated strings + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **status** | [**models::FindPetsByStatusStatusParameterInner**](models::FindPetsByStatusStatusParameterInner.md)| Status values that need to be considered for filter | + +### Return type + +[**Vec**](Pet.md) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **findPetsByTags** +> Vec findPetsByTags(ctx, tags) +Finds Pets by tags + +Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **tags** | [**String**](String.md)| Tags to filter by | + +### Return type + +[**Vec**](Pet.md) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updatePet** +> updatePet(ctx, body) +Update an existing pet + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **body** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | + +### Return type + + (empty response body) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: application/json, application/xml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **deletePet** +> deletePet(ctx, pet_id, optional) +Deletes a pet + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **pet_id** | **i64**| Pet id to delete | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **pet_id** | **i64**| Pet id to delete | + **api_key** | **String**| | + +### Return type + + (empty response body) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getPetById** +> models::Pet getPetById(ctx, pet_id) +Find pet by ID + +Returns a single pet + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **pet_id** | **i64**| ID of pet to return | + +### Return type + +[**models::Pet**](Pet.md) + +### Authorization + +[api_key](../README.md#api_key) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updatePetWithForm** +> updatePetWithForm(ctx, pet_id, optional) +Updates a pet in the store with form data + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **pet_id** | **i64**| ID of pet that needs to be updated | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **pet_id** | **i64**| ID of pet that needs to be updated | + **name** | **String**| Updated name of the pet | + **status** | **String**| Updated status of the pet | + +### Return type + + (empty response body) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: application/x-www-form-urlencoded + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **uploadFile** +> models::ApiResponse uploadFile(ctx, pet_id, optional) +uploads an image + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context containing the authentication | nil if no authentication + **pet_id** | **i64**| ID of pet to update | + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **pet_id** | **i64**| ID of pet to update | + **additional_metadata** | **String**| Additional data to pass to server | + **file** | **swagger::ByteArray**| file to upload | + +### Return type + +[**models::ApiResponse**](ApiResponse.md) + +### Authorization + +[petstore_auth](../README.md#petstore_auth) + +### HTTP request headers + + - **Content-Type**: multipart/form-data + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/store_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/store_api.md new file mode 100644 index 000000000000..f8e633abd83e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/store_api.md @@ -0,0 +1,115 @@ +# store_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**getInventory**](store_api.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status +**placeOrder**](store_api.md#placeOrder) | **POST** /store/order | Place an order for a pet +**deleteOrder**](store_api.md#deleteOrder) | **DELETE** /store/order/{order_id} | Delete purchase order by ID +**getOrderById**](store_api.md#getOrderById) | **GET** /store/order/{order_id} | Find purchase order by ID + + +# **getInventory** +> std::collections::HashMap getInventory(ctx, ) +Returns pet inventories by status + +Returns a map of status codes to quantities + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**std::collections::HashMap**](integer.md) + +### Authorization + +[api_key](../README.md#api_key) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **placeOrder** +> models::Order placeOrder(body) +Place an order for a pet + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**Order**](Order.md)| order placed for purchasing the pet | + +### Return type + +[**models::Order**](Order.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **deleteOrder** +> deleteOrder(order_id) +Delete purchase order by ID + +For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **order_id** | **String**| ID of the order that needs to be deleted | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getOrderById** +> models::Order getOrderById(order_id) +Find purchase order by ID + +For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **order_id** | **i64**| ID of pet that needs to be fetched | + +### Return type + +[**models::Order**](Order.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/user_api.md b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/user_api.md new file mode 100644 index 000000000000..9518a5d031c5 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/docs/user_api.md @@ -0,0 +1,221 @@ +# user_api + +All URIs are relative to *http://petstore.swagger.io:80/v2* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**createUser**](user_api.md#createUser) | **POST** /user | Create user +**createUsersWithArrayInput**](user_api.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array +**createUsersWithListInput**](user_api.md#createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array +**loginUser**](user_api.md#loginUser) | **GET** /user/login | Logs user into the system +**logoutUser**](user_api.md#logoutUser) | **GET** /user/logout | Logs out current logged in user session +**deleteUser**](user_api.md#deleteUser) | **DELETE** /user/{username} | Delete user +**getUserByName**](user_api.md#getUserByName) | **GET** /user/{username} | Get user by user name +**updateUser**](user_api.md#updateUser) | **PUT** /user/{username} | Updated user + + +# **createUser** +> createUser(body) +Create user + +This can only be done by the logged in user. + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**User**](User.md)| Created user object | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **createUsersWithArrayInput** +> createUsersWithArrayInput(body) +Creates list of users with given input array + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**User**](User.md)| List of user object | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **createUsersWithListInput** +> createUsersWithListInput(body) +Creates list of users with given input array + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | [**User**](User.md)| List of user object | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **loginUser** +> String loginUser(username, password) +Logs user into the system + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **username** | **String**| The user name for login | + **password** | **String**| The password for login in clear text | + +### Return type + +[**String**](string.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **logoutUser** +> logoutUser() +Logs out current logged in user session + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **deleteUser** +> deleteUser(username) +Delete user + +This can only be done by the logged in user. + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **username** | **String**| The name that needs to be deleted | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getUserByName** +> models::User getUserByName(username) +Get user by user name + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **username** | **String**| The name that needs to be fetched. Use user1 for testing. | + +### Return type + +[**models::User**](User.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/xml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **updateUser** +> updateUser(username, body) +Updated user + +This can only be done by the logged in user. + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **username** | **String**| name that need to be deleted | + **body** | [**User**](User.md)| Updated user object | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/client_auth.rs new file mode 100644 index 000000000000..7fc915f98b1b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use petstore_with_fake_endpoints_models_for_testing::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs new file mode 100644 index 000000000000..62b1a8c1389b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs @@ -0,0 +1,425 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + TestSpecialTagsResponse, + Call123exampleResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + FakeResponseWithNumericalDescriptionResponse, + TestBodyWithQueryParamsResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + HyphenParamResponse, + TestClassnameResponse, + AddPetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + UpdatePetResponse, + DeletePetResponse, + GetPetByIdResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + GetInventoryResponse, + PlaceOrderResponse, + DeleteOrderResponse, + GetOrderByIdResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + LoginUserResponse, + LogoutUserResponse, + DeleteUserResponse, + GetUserByNameResponse, + UpdateUserResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "Call123example", + "FakeOuterBooleanSerialize", + "FakeOuterCompositeSerialize", + "FakeOuterNumberSerialize", + "FakeOuterStringSerialize", + "FakeResponseWithNumericalDescription", + "TestEndpointParameters", + "TestEnumParameters", + "TestJsonFormData", + "HyphenParam", + "FindPetsByStatus", + "FindPetsByTags", + "DeletePet", + "GetPetById", + "UpdatePetWithForm", + "UploadFile", + "GetInventory", + "DeleteOrder", + "GetOrderById", + "CreateUsersWithArrayInput", + "CreateUsersWithListInput", + "LoginUser", + "LogoutUser", + "DeleteUser", + "GetUserByName", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("petstore.swagger.io") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("80") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + [ + "write:pets", + "read:pets", + ].join::<&str>(", ") + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + /* Disabled because there's no example. + Some("TestSpecialTags") => { + let result = rt.block_on(client.test_special_tags( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("Call123example") => { + let result = rt.block_on(client.call123example( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FakeOuterBooleanSerialize") => { + let result = rt.block_on(client.fake_outer_boolean_serialize( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FakeOuterCompositeSerialize") => { + let result = rt.block_on(client.fake_outer_composite_serialize( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FakeOuterNumberSerialize") => { + let result = rt.block_on(client.fake_outer_number_serialize( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FakeOuterStringSerialize") => { + let result = rt.block_on(client.fake_outer_string_serialize( + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FakeResponseWithNumericalDescription") => { + let result = rt.block_on(client.fake_response_with_numerical_description( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("TestBodyWithQueryParams") => { + let result = rt.block_on(client.test_body_with_query_params( + "query_example".to_string(), + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + /* Disabled because there's no example. + Some("TestClientModel") => { + let result = rt.block_on(client.test_client_model( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("TestEndpointParameters") => { + let result = rt.block_on(client.test_endpoint_parameters( + 8.14, + 1.2, + "pattern_without_delimiter_example".to_string(), + swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")), + Some(56), + Some(56), + Some(789), + Some(3.4), + Some("string_example".to_string()), + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))), + None, + None, + Some("password_example".to_string()), + Some("callback_example".to_string()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("TestEnumParameters") => { + let result = rt.block_on(client.test_enum_parameters( + Some(&Vec::new()), + None, + Some(&Vec::new()), + None, + None, + None, + None + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("TestInlineAdditionalProperties") => { + let result = rt.block_on(client.test_inline_additional_properties( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("TestJsonFormData") => { + let result = rt.block_on(client.test_json_form_data( + "param_example".to_string(), + "param2_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("HyphenParam") => { + let result = rt.block_on(client.hyphen_param( + "hyphen_param_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("TestClassname") => { + let result = rt.block_on(client.test_classname( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + /* Disabled because there's no example. + Some("AddPet") => { + let result = rt.block_on(client.add_pet( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("FindPetsByStatus") => { + let result = rt.block_on(client.find_pets_by_status( + &Vec::new() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("FindPetsByTags") => { + let result = rt.block_on(client.find_pets_by_tags( + &Vec::new() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("UpdatePet") => { + let result = rt.block_on(client.update_pet( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("DeletePet") => { + let result = rt.block_on(client.delete_pet( + 789, + Some("api_key_example".to_string()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetPetById") => { + let result = rt.block_on(client.get_pet_by_id( + 789 + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("UpdatePetWithForm") => { + let result = rt.block_on(client.update_pet_with_form( + 789, + Some("name_example".to_string()), + Some("status_example".to_string()) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("UploadFile") => { + let result = rt.block_on(client.upload_file( + 789, + Some("additional_metadata_example".to_string()), + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetInventory") => { + let result = rt.block_on(client.get_inventory( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("PlaceOrder") => { + let result = rt.block_on(client.place_order( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("DeleteOrder") => { + let result = rt.block_on(client.delete_order( + "order_id_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetOrderById") => { + let result = rt.block_on(client.get_order_by_id( + 789 + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("CreateUser") => { + let result = rt.block_on(client.create_user( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("CreateUsersWithArrayInput") => { + let result = rt.block_on(client.create_users_with_array_input( + &Vec::new() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("CreateUsersWithListInput") => { + let result = rt.block_on(client.create_users_with_list_input( + &Vec::new() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("LoginUser") => { + let result = rt.block_on(client.login_user( + "username_example".to_string(), + "password_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("LogoutUser") => { + let result = rt.block_on(client.logout_user( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("DeleteUser") => { + let result = rt.block_on(client.delete_user( + "username_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetUserByName") => { + let result = rt.block_on(client.get_user_by_name( + "username_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("UpdateUser") => { + let result = rt.block_on(client.update_user( + "username_example".to_string(), + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs new file mode 100644 index 000000000000..63e175c3dc90 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for petstore_with_fake_endpoints_models_for_testing implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:80"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs new file mode 100644 index 000000000000..2920da486195 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs @@ -0,0 +1,514 @@ +//! Main library entry point for petstore_with_fake_endpoints_models_for_testing implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use petstore_with_fake_endpoints_models_for_testing::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + petstore_with_fake_endpoints_models_for_testing::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use petstore_with_fake_endpoints_models_for_testing::{ + Api, + TestSpecialTagsResponse, + Call123exampleResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + FakeResponseWithNumericalDescriptionResponse, + TestBodyWithQueryParamsResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + HyphenParamResponse, + TestClassnameResponse, + AddPetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + UpdatePetResponse, + DeletePetResponse, + GetPetByIdResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + GetInventoryResponse, + PlaceOrderResponse, + DeleteOrderResponse, + GetOrderByIdResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + LoginUserResponse, + LogoutUserResponse, + DeleteUserResponse, + GetUserByNameResponse, + UpdateUserResponse, +}; +use petstore_with_fake_endpoints_models_for_testing::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + /// To test special tags + async fn test_special_tags( + &self, + body: models::Client, + context: &C) -> Result + { + info!("test_special_tags({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn call123example( + &self, + context: &C) -> Result + { + info!("call123example() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn fake_outer_boolean_serialize( + &self, + body: Option, + context: &C) -> Result + { + info!("fake_outer_boolean_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn fake_outer_composite_serialize( + &self, + body: Option, + context: &C) -> Result + { + info!("fake_outer_composite_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn fake_outer_number_serialize( + &self, + body: Option, + context: &C) -> Result + { + info!("fake_outer_number_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn fake_outer_string_serialize( + &self, + body: Option, + context: &C) -> Result + { + info!("fake_outer_string_serialize({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn fake_response_with_numerical_description( + &self, + context: &C) -> Result + { + info!("fake_response_with_numerical_description() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn test_body_with_query_params( + &self, + query: String, + body: models::User, + context: &C) -> Result + { + info!("test_body_with_query_params(\"{}\", {:?}) - X-Span-ID: {:?}", query, body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// To test \"client\" model + async fn test_client_model( + &self, + body: models::Client, + context: &C) -> Result + { + info!("test_client_model({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + async fn test_endpoint_parameters( + &self, + number: f64, + double: f64, + pattern_without_delimiter: String, + byte: swagger::ByteArray, + integer: Option, + int32: Option, + int64: Option, + float: Option, + string: Option, + binary: Option, + date: Option, + date_time: Option>, + password: Option, + callback: Option, + context: &C) -> Result + { + info!("test_endpoint_parameters({}, {}, \"{}\", {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// To test enum parameters + async fn test_enum_parameters( + &self, + enum_header_string_array: Option<&Vec>, + enum_header_string: Option, + enum_query_string_array: Option<&Vec>, + enum_query_string: Option, + enum_query_integer: Option, + enum_query_double: Option, + enum_form_string: Option, + context: &C) -> Result + { + info!("test_enum_parameters({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}) - X-Span-ID: {:?}", enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// test inline additionalProperties + async fn test_inline_additional_properties( + &self, + param: std::collections::HashMap, + context: &C) -> Result + { + info!("test_inline_additional_properties({:?}) - X-Span-ID: {:?}", param, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// test json serialization of form data + async fn test_json_form_data( + &self, + param: String, + param2: String, + context: &C) -> Result + { + info!("test_json_form_data(\"{}\", \"{}\") - X-Span-ID: {:?}", param, param2, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn hyphen_param( + &self, + hyphen_param: String, + context: &C) -> Result + { + info!("hyphen_param(\"{}\") - X-Span-ID: {:?}", hyphen_param, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// To test class name in snake case + async fn test_classname( + &self, + body: models::Client, + context: &C) -> Result + { + info!("test_classname({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Add a new pet to the store + async fn add_pet( + &self, + body: models::Pet, + context: &C) -> Result + { + info!("add_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Finds Pets by status + async fn find_pets_by_status( + &self, + status: &Vec, + context: &C) -> Result + { + info!("find_pets_by_status({:?}) - X-Span-ID: {:?}", status, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Finds Pets by tags + async fn find_pets_by_tags( + &self, + tags: &Vec, + context: &C) -> Result + { + info!("find_pets_by_tags({:?}) - X-Span-ID: {:?}", tags, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Update an existing pet + async fn update_pet( + &self, + body: models::Pet, + context: &C) -> Result + { + info!("update_pet({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Deletes a pet + async fn delete_pet( + &self, + pet_id: i64, + api_key: Option, + context: &C) -> Result + { + info!("delete_pet({}, {:?}) - X-Span-ID: {:?}", pet_id, api_key, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Find pet by ID + async fn get_pet_by_id( + &self, + pet_id: i64, + context: &C) -> Result + { + info!("get_pet_by_id({}) - X-Span-ID: {:?}", pet_id, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Updates a pet in the store with form data + async fn update_pet_with_form( + &self, + pet_id: i64, + name: Option, + status: Option, + context: &C) -> Result + { + info!("update_pet_with_form({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, name, status, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// uploads an image + async fn upload_file( + &self, + pet_id: i64, + additional_metadata: Option, + file: Option, + context: &C) -> Result + { + info!("upload_file({}, {:?}, {:?}) - X-Span-ID: {:?}", pet_id, additional_metadata, file, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Returns pet inventories by status + async fn get_inventory( + &self, + context: &C) -> Result + { + info!("get_inventory() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Place an order for a pet + async fn place_order( + &self, + body: models::Order, + context: &C) -> Result + { + info!("place_order({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Delete purchase order by ID + async fn delete_order( + &self, + order_id: String, + context: &C) -> Result + { + info!("delete_order(\"{}\") - X-Span-ID: {:?}", order_id, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Find purchase order by ID + async fn get_order_by_id( + &self, + order_id: i64, + context: &C) -> Result + { + info!("get_order_by_id({}) - X-Span-ID: {:?}", order_id, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Create user + async fn create_user( + &self, + body: models::User, + context: &C) -> Result + { + info!("create_user({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Creates list of users with given input array + async fn create_users_with_array_input( + &self, + body: &Vec, + context: &C) -> Result + { + info!("create_users_with_array_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Creates list of users with given input array + async fn create_users_with_list_input( + &self, + body: &Vec, + context: &C) -> Result + { + info!("create_users_with_list_input({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Logs user into the system + async fn login_user( + &self, + username: String, + password: String, + context: &C) -> Result + { + info!("login_user(\"{}\", \"{}\") - X-Span-ID: {:?}", username, password, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Logs out current logged in user session + async fn logout_user( + &self, + context: &C) -> Result + { + info!("logout_user() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Delete user + async fn delete_user( + &self, + username: String, + context: &C) -> Result + { + info!("delete_user(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Get user by user name + async fn get_user_by_name( + &self, + username: String, + context: &C) -> Result + { + info!("get_user_by_name(\"{}\") - X-Span-ID: {:?}", username, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Updated user + async fn update_user( + &self, + username: String, + body: models::User, + context: &C) -> Result + { + info!("update_user(\"{}\", {:?}) - X-Span-ID: {:?}", username, body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs new file mode 100644 index 000000000000..1593a36e2c41 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs @@ -0,0 +1,130 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use petstore_with_fake_endpoints_models_for_testing::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + [ + "write:pets", + "read:pets", + ].join::<&str>(", ") + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs new file mode 100644 index 000000000000..7019561622d6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs @@ -0,0 +1,3788 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + +use mime::Mime; +use std::io::Cursor; +use multipart::client::lazy::Multipart; + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + TestSpecialTagsResponse, + Call123exampleResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + FakeResponseWithNumericalDescriptionResponse, + TestBodyWithQueryParamsResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + HyphenParamResponse, + TestClassnameResponse, + AddPetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + UpdatePetResponse, + DeletePetResponse, + GetPetByIdResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + GetInventoryResponse, + PlaceOrderResponse, + DeleteOrderResponse, + GetOrderByIdResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + LoginUserResponse, + LogoutUserResponse, + DeleteUserResponse, + GetUserByNameResponse, + UpdateUserResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Has> + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn test_special_tags( + &self, + param_body: models::Client, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/another-fake/dummy", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PATCH") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(TestSpecialTagsResponse::SuccessfulOperation + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn call123example( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/operation-with-numeric-id", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + Call123exampleResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn fake_outer_boolean_serialize( + &self, + param_body: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/outer/boolean", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_body) = param_body { + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + } + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FakeOuterBooleanSerializeResponse::OutputBoolean + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn fake_outer_composite_serialize( + &self, + param_body: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/outer/composite", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_body) = param_body { + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + } + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FakeOuterCompositeSerializeResponse::OutputComposite + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn fake_outer_number_serialize( + &self, + param_body: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/outer/number", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_body) = param_body { + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + } + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FakeOuterNumberSerializeResponse::OutputNumber + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn fake_outer_string_serialize( + &self, + param_body: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/outer/string", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + if let Some(param_body) = param_body { + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + } + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FakeOuterStringSerializeResponse::OutputString + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn fake_response_with_numerical_description( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/response-with-numerical-description", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + FakeResponseWithNumericalDescriptionResponse::Status200 + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_body_with_query_params( + &self, + param_query: String, + param_body: models::User, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/body-with-query-params", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("query", + ¶m_query); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + TestBodyWithQueryParamsResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_client_model( + &self, + param_body: models::Client, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PATCH") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(TestClientModelResponse::SuccessfulOperation + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_endpoint_parameters( + &self, + param_number: f64, + param_double: f64, + param_pattern_without_delimiter: String, + param_byte: swagger::ByteArray, + param_integer: Option, + param_int32: Option, + param_int64: Option, + param_float: Option, + param_string: Option, + param_binary: Option, + param_date: Option, + param_date_time: Option>, + param_password: Option, + param_callback: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes form body + let mut params = vec![]; + if let Some(param_integer) = param_integer { + #[allow(clippy::uninlined_format_args)] + params.push(("integer", + format!("{:?}", param_integer) + )); + } + if let Some(param_int32) = param_int32 { + #[allow(clippy::uninlined_format_args)] + params.push(("int32", + format!("{:?}", param_int32) + )); + } + if let Some(param_int64) = param_int64 { + #[allow(clippy::uninlined_format_args)] + params.push(("int64", + format!("{:?}", param_int64) + )); + } + #[allow(clippy::uninlined_format_args)] + params.push(("number", + format!("{}", param_number) + )); + if let Some(param_float) = param_float { + #[allow(clippy::uninlined_format_args)] + params.push(("float", + format!("{:?}", param_float) + )); + } + #[allow(clippy::uninlined_format_args)] + params.push(("double", + format!("{}", param_double) + )); + if let Some(param_string) = param_string { + #[allow(clippy::uninlined_format_args)] + params.push(("string", + param_string + )); + } + #[allow(clippy::uninlined_format_args)] + params.push(("pattern_without_delimiter", + param_pattern_without_delimiter + )); + #[allow(clippy::uninlined_format_args)] + params.push(("byte", + format!("{:?}", param_byte) + )); + if let Some(param_binary) = param_binary { + #[allow(clippy::uninlined_format_args)] + params.push(("binary", + format!("{:?}", param_binary) + )); + } + if let Some(param_date) = param_date { + #[allow(clippy::uninlined_format_args)] + params.push(("date", + format!("{:?}", param_date) + )); + } + if let Some(param_date_time) = param_date_time { + #[allow(clippy::uninlined_format_args)] + params.push(("dateTime", + format!("{:?}", param_date_time) + )); + } + if let Some(param_password) = param_password { + #[allow(clippy::uninlined_format_args)] + params.push(("password", + param_password + )); + } + if let Some(param_callback) = param_callback { + #[allow(clippy::uninlined_format_args)] + params.push(("callback", + param_callback + )); + } + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "application/x-www-form-urlencoded"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Basic(basic_header) => { + let auth = swagger::auth::Header(basic_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + TestEndpointParametersResponse::InvalidUsernameSupplied + ) + } + 404 => { + Ok( + TestEndpointParametersResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_enum_parameters( + &self, + param_enum_header_string_array: Option<&Vec>, + param_enum_header_string: Option, + param_enum_query_string_array: Option<&Vec>, + param_enum_query_string: Option, + param_enum_query_integer: Option, + param_enum_query_double: Option, + param_enum_form_string: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_enum_query_string_array) = param_enum_query_string_array { + query_string.append_pair("enum_query_string_array", + ¶m_enum_query_string_array.iter().map(ToString::to_string).collect::>().join(",")); + } + if let Some(param_enum_query_string) = param_enum_query_string { + query_string.append_pair("enum_query_string", + ¶m_enum_query_string.to_string()); + } + if let Some(param_enum_query_integer) = param_enum_query_integer { + query_string.append_pair("enum_query_integer", + ¶m_enum_query_integer.to_string()); + } + if let Some(param_enum_query_double) = param_enum_query_double { + query_string.append_pair("enum_query_double", + ¶m_enum_query_double.to_string()); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes form body + let mut params = vec![]; + if let Some(param_enum_form_string) = param_enum_form_string { + #[allow(clippy::uninlined_format_args)] + params.push(("enum_form_string", + format!("{:?}", param_enum_form_string) + )); + } + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "application/x-www-form-urlencoded"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + // Header parameters + #[allow(clippy::single_match)] + match param_enum_header_string_array { + Some(param_enum_header_string_array) => { + request.headers_mut().append( + HeaderName::from_static("enum_header_string_array"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_enum_header_string_array.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header enum_header_string_array - {e}"))); + }, + }); + }, + None => {} + } + + #[allow(clippy::single_match)] + match param_enum_header_string { + Some(param_enum_header_string) => { + request.headers_mut().append( + HeaderName::from_static("enum_header_string"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_enum_header_string.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header enum_header_string - {e}"))); + }, + }); + }, + None => {} + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + TestEnumParametersResponse::InvalidRequest + ) + } + 404 => { + Ok( + TestEnumParametersResponse::NotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_inline_additional_properties( + &self, + param_param: std::collections::HashMap, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/inline-additionalProperties", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_param).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_json_form_data( + &self, + param_param: String, + param_param2: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/jsonFormData", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes form body + let mut params = vec![]; + #[allow(clippy::uninlined_format_args)] + params.push(("param", + param_param + )); + #[allow(clippy::uninlined_format_args)] + params.push(("param2", + param_param2 + )); + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "application/x-www-form-urlencoded"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + TestJsonFormDataResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn hyphen_param( + &self, + param_hyphen_param: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake/hyphenParam/{hyphen_param}", + self.base_path + ,hyphen_param=utf8_percent_encode(¶m_hyphen_param.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + HyphenParamResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn test_classname( + &self, + param_body: models::Client, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/fake_classname_test", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(AuthData::ApiKey(ref api_key)) = (context as &dyn Has>).get().as_ref() { + query_string.append_pair("api_key_query", api_key); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PATCH") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(TestClassnameResponse::SuccessfulOperation + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn add_pet( + &self, + param_body: models::Pet, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = param_body.as_xml(); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 405 => { + Ok( + AddPetResponse::InvalidInput + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn find_pets_by_status( + &self, + param_status: &Vec, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/findByStatus", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("status", + ¶m_status.iter().map(ToString::to_string).collect::>().join(",")); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FindPetsByStatusResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + FindPetsByStatusResponse::InvalidStatusValue + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn find_pets_by_tags( + &self, + param_tags: &Vec, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/findByTags", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("tags", + ¶m_tags.iter().map(ToString::to_string).collect::>().join(",")); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FindPetsByTagsResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + FindPetsByTagsResponse::InvalidTagValue + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn update_pet( + &self, + param_body: models::Pet, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = param_body.as_xml(); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + UpdatePetResponse::InvalidIDSupplied + ) + } + 404 => { + Ok( + UpdatePetResponse::PetNotFound + ) + } + 405 => { + Ok( + UpdatePetResponse::ValidationException + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn delete_pet( + &self, + param_pet_id: i64, + param_api_key: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/{pet_id}", + self.base_path + ,pet_id=utf8_percent_encode(¶m_pet_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("DELETE") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + // Header parameters + #[allow(clippy::single_match)] + match param_api_key { + Some(param_api_key) => { + request.headers_mut().append( + HeaderName::from_static("api_key"), + #[allow(clippy::redundant_clone)] + match header::IntoHeaderValue(param_api_key.clone()).try_into() { + Ok(header) => header, + Err(e) => { + return Err(ApiError(format!( + "Invalid header api_key - {e}"))); + }, + }); + }, + None => {} + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + DeletePetResponse::InvalidPetValue + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_pet_by_id( + &self, + param_pet_id: i64, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/{pet_id}", + self.base_path + ,pet_id=utf8_percent_encode(¶m_pet_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(GetPetByIdResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + GetPetByIdResponse::InvalidIDSupplied + ) + } + 404 => { + Ok( + GetPetByIdResponse::PetNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn update_pet_with_form( + &self, + param_pet_id: i64, + param_name: Option, + param_status: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/{pet_id}", + self.base_path + ,pet_id=utf8_percent_encode(¶m_pet_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes form body + let mut params = vec![]; + if let Some(param_name) = param_name { + #[allow(clippy::uninlined_format_args)] + params.push(("name", + param_name + )); + } + if let Some(param_status) = param_status { + #[allow(clippy::uninlined_format_args)] + params.push(("status", + param_status + )); + } + + let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); + + *request.body_mut() = Body::from(body.into_bytes()); + + let header = "application/x-www-form-urlencoded"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 405 => { + Ok( + UpdatePetWithFormResponse::InvalidInput + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn upload_file( + &self, + param_pet_id: i64, + param_additional_metadata: Option, + param_file: Option, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/pet/{pet_id}/uploadImage", + self.base_path + ,pet_id=utf8_percent_encode(¶m_pet_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes multipart/form body + let (body_string, multipart_header) = { + let mut multipart = Multipart::new(); + + // For each parameter, encode as appropriate and add to the multipart body as a stream. + + let additional_metadata_str = match serde_json::to_string(¶m_additional_metadata) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize additional_metadata to string: {e}"))), + }; + + let additional_metadata_vec = additional_metadata_str.as_bytes().to_vec(); + let additional_metadata_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let additional_metadata_cursor = Cursor::new(additional_metadata_vec); + + multipart.add_stream("additional_metadata", additional_metadata_cursor, None as Option<&str>, Some(additional_metadata_mime)); + + + let file_str = match serde_json::to_string(¶m_file) { + Ok(str) => str, + Err(e) => return Err(ApiError(format!("Unable to serialize file to string: {e}"))), + }; + + let file_vec = file_str.as_bytes().to_vec(); + let file_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let file_cursor = Cursor::new(file_vec); + + multipart.add_stream("file", file_cursor, None as Option<&str>, Some(file_mime)); + + + let mut fields = match multipart.prepare() { + Ok(fields) => fields, + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), + }; + + let mut body_string = String::new(); + + match fields.read_to_string(&mut body_string) { + Ok(_) => (), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), + } + + let boundary = fields.boundary(); + + let multipart_header = format!("multipart/form-data;{boundary}"); + + (body_string, multipart_header) + }; + + *request.body_mut() = Body::from(body_string); + + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) + }); + + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(UploadFileResponse::SuccessfulOperation + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_inventory( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/store/inventory", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::>(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(GetInventoryResponse::SuccessfulOperation + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn place_order( + &self, + param_body: models::Order, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/store/order", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(PlaceOrderResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + PlaceOrderResponse::InvalidOrder + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn delete_order( + &self, + param_order_id: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/store/order/{order_id}", + self.base_path + ,order_id=utf8_percent_encode(¶m_order_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("DELETE") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + DeleteOrderResponse::InvalidIDSupplied + ) + } + 404 => { + Ok( + DeleteOrderResponse::OrderNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_order_by_id( + &self, + param_order_id: i64, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/store/order/{order_id}", + self.base_path + ,order_id=utf8_percent_encode(¶m_order_id.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(GetOrderByIdResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + GetOrderByIdResponse::InvalidIDSupplied + ) + } + 404 => { + Ok( + GetOrderByIdResponse::OrderNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn create_user( + &self, + param_body: models::User, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 0 => { + Ok( + CreateUserResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn create_users_with_array_input( + &self, + param_body: &Vec, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/createWithArray", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 0 => { + Ok( + CreateUsersWithArrayInputResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn create_users_with_list_input( + &self, + param_body: &Vec, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/createWithList", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 0 => { + Ok( + CreateUsersWithListInputResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn login_user( + &self, + param_username: String, + param_password: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/login", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("username", + ¶m_username); + query_string.append_pair("password", + ¶m_password); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let response_x_rate_limit = match response.headers().get(HeaderName::from_static("x-rate-limit")) { + Some(response_x_rate_limit) => { + let response_x_rate_limit = response_x_rate_limit.clone(); + let response_x_rate_limit = match TryInto::>::try_into(response_x_rate_limit) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header X-Rate-Limit for response 200 - {e}"))); + }, + }; + Some(response_x_rate_limit.0) + }, + None => None, + }; + + let response_x_expires_after = match response.headers().get(HeaderName::from_static("x-expires-after")) { + Some(response_x_expires_after) => { + let response_x_expires_after = response_x_expires_after.clone(); + let response_x_expires_after = match TryInto::>>::try_into(response_x_expires_after) { + Ok(value) => value, + Err(e) => { + return Err(ApiError(format!("Invalid response header X-Expires-After for response 200 - {e}"))); + }, + }; + Some(response_x_expires_after.0) + }, + None => None, + }; + + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(LoginUserResponse::SuccessfulOperation + { + body, + x_rate_limit: response_x_rate_limit, + x_expires_after: response_x_expires_after, + } + ) + } + 400 => { + Ok( + LoginUserResponse::InvalidUsername + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn logout_user( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/logout", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 0 => { + Ok( + LogoutUserResponse::SuccessfulOperation + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn delete_user( + &self, + param_username: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/{username}", + self.base_path + ,username=utf8_percent_encode(¶m_username.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("DELETE") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + DeleteUserResponse::InvalidUsernameSupplied + ) + } + 404 => { + Ok( + DeleteUserResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_user_by_name( + &self, + param_username: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/{username}", + self.base_path + ,username=utf8_percent_encode(¶m_username.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + // ToDo: this will move to swagger-rs and become a standard From conversion trait + // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream + let body = serde_xml_rs::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(GetUserByNameResponse::SuccessfulOperation + (body) + ) + } + 400 => { + Ok( + GetUserByNameResponse::InvalidUsernameSupplied + ) + } + 404 => { + Ok( + GetUserByNameResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn update_user( + &self, + param_username: String, + param_body: models::User, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/v2/user/{username}", + self.base_path + ,username=utf8_percent_encode(¶m_username.to_string(), ID_ENCODE_SET) + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 400 => { + Ok( + UpdateUserResponse::InvalidUserSupplied + ) + } + 404 => { + Ok( + UpdateUserResponse::UserNotFound + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs new file mode 100644 index 000000000000..d821895b62ad --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs @@ -0,0 +1,192 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + { + use swagger::auth::api_key_from_header; + + if let Some(header) = api_key_from_header(headers, "api_key") { + let authorization = self.inner.apikey_authorization(&header); + let auth_data = AuthData::ApiKey(header); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + { + let key = form_urlencoded::parse(request.uri().query().unwrap_or_default().as_bytes()) + .filter(|e| e.0 == "api_key_query") + .map(|e| e.1.clone().into_owned()) + .next(); + if let Some(key) = key { + let authorization = self.inner.apikey_authorization(&key); + let auth_data = AuthData::ApiKey(key); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + { + use swagger::auth::Basic; + use std::ops::Deref; + if let Some(basic) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.basic_authorization(&basic); + let auth_data = AuthData::Basic(basic); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs new file mode 100644 index 000000000000..b910c9ae6b23 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs @@ -0,0 +1,1209 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = "/v2"; +pub const API_VERSION: &str = "1.0.0"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestSpecialTagsResponse { + /// successful operation + SuccessfulOperation + (models::Client) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum Call123exampleResponse { + /// success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FakeOuterBooleanSerializeResponse { + /// Output boolean + OutputBoolean + (bool) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FakeOuterCompositeSerializeResponse { + /// Output composite + OutputComposite + (models::OuterComposite) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FakeOuterNumberSerializeResponse { + /// Output number + OutputNumber + (f64) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FakeOuterStringSerializeResponse { + /// Output string + OutputString + (String) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FakeResponseWithNumericalDescriptionResponse { + /// 1234 + Status200 +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestBodyWithQueryParamsResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestClientModelResponse { + /// successful operation + SuccessfulOperation + (models::Client) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum TestEndpointParametersResponse { + /// Invalid username supplied + InvalidUsernameSupplied + , + /// User not found + UserNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum TestEnumParametersResponse { + /// Invalid request + InvalidRequest + , + /// Not found + NotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestInlineAdditionalPropertiesResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestJsonFormDataResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum HyphenParamResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum TestClassnameResponse { + /// successful operation + SuccessfulOperation + (models::Client) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum AddPetResponse { + /// Invalid input + InvalidInput +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum FindPetsByStatusResponse { + /// successful operation + SuccessfulOperation + (Vec) + , + /// Invalid status value + InvalidStatusValue +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum FindPetsByTagsResponse { + /// successful operation + SuccessfulOperation + (Vec) + , + /// Invalid tag value + InvalidTagValue +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum UpdatePetResponse { + /// Invalid ID supplied + InvalidIDSupplied + , + /// Pet not found + PetNotFound + , + /// Validation exception + ValidationException +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum DeletePetResponse { + /// Invalid pet value + InvalidPetValue +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum GetPetByIdResponse { + /// successful operation + SuccessfulOperation + (models::Pet) + , + /// Invalid ID supplied + InvalidIDSupplied + , + /// Pet not found + PetNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum UpdatePetWithFormResponse { + /// Invalid input + InvalidInput +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum UploadFileResponse { + /// successful operation + SuccessfulOperation + (models::ApiResponse) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum GetInventoryResponse { + /// successful operation + SuccessfulOperation + (std::collections::HashMap) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum PlaceOrderResponse { + /// successful operation + SuccessfulOperation + (models::Order) + , + /// Invalid Order + InvalidOrder +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum DeleteOrderResponse { + /// Invalid ID supplied + InvalidIDSupplied + , + /// Order not found + OrderNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum GetOrderByIdResponse { + /// successful operation + SuccessfulOperation + (models::Order) + , + /// Invalid ID supplied + InvalidIDSupplied + , + /// Order not found + OrderNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CreateUserResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CreateUsersWithArrayInputResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum CreateUsersWithListInputResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum LoginUserResponse { + /// successful operation + SuccessfulOperation + { + body: String, + x_rate_limit: + Option< + i32 + > + , + x_expires_after: + Option< + chrono::DateTime:: + > + } + , + /// Invalid username/password supplied + InvalidUsername +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum LogoutUserResponse { + /// successful operation + SuccessfulOperation +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum DeleteUserResponse { + /// Invalid username supplied + InvalidUsernameSupplied + , + /// User not found + UserNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum GetUserByNameResponse { + /// successful operation + SuccessfulOperation + (models::User) + , + /// Invalid username supplied + InvalidUsernameSupplied + , + /// User not found + UserNotFound +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[must_use] +pub enum UpdateUserResponse { + /// Invalid user supplied + InvalidUserSupplied + , + /// User not found + UserNotFound +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + /// To test special tags + async fn test_special_tags( + &self, + body: models::Client, + context: &C) -> Result; + + async fn call123example( + &self, + context: &C) -> Result; + + async fn fake_outer_boolean_serialize( + &self, + body: Option, + context: &C) -> Result; + + async fn fake_outer_composite_serialize( + &self, + body: Option, + context: &C) -> Result; + + async fn fake_outer_number_serialize( + &self, + body: Option, + context: &C) -> Result; + + async fn fake_outer_string_serialize( + &self, + body: Option, + context: &C) -> Result; + + async fn fake_response_with_numerical_description( + &self, + context: &C) -> Result; + + async fn test_body_with_query_params( + &self, + query: String, + body: models::User, + context: &C) -> Result; + + /// To test \"client\" model + async fn test_client_model( + &self, + body: models::Client, + context: &C) -> Result; + + /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + async fn test_endpoint_parameters( + &self, + number: f64, + double: f64, + pattern_without_delimiter: String, + byte: swagger::ByteArray, + integer: Option, + int32: Option, + int64: Option, + float: Option, + string: Option, + binary: Option, + date: Option, + date_time: Option>, + password: Option, + callback: Option, + context: &C) -> Result; + + /// To test enum parameters + async fn test_enum_parameters( + &self, + enum_header_string_array: Option<&Vec>, + enum_header_string: Option, + enum_query_string_array: Option<&Vec>, + enum_query_string: Option, + enum_query_integer: Option, + enum_query_double: Option, + enum_form_string: Option, + context: &C) -> Result; + + /// test inline additionalProperties + async fn test_inline_additional_properties( + &self, + param: std::collections::HashMap, + context: &C) -> Result; + + /// test json serialization of form data + async fn test_json_form_data( + &self, + param: String, + param2: String, + context: &C) -> Result; + + async fn hyphen_param( + &self, + hyphen_param: String, + context: &C) -> Result; + + /// To test class name in snake case + async fn test_classname( + &self, + body: models::Client, + context: &C) -> Result; + + /// Add a new pet to the store + async fn add_pet( + &self, + body: models::Pet, + context: &C) -> Result; + + /// Finds Pets by status + async fn find_pets_by_status( + &self, + status: &Vec, + context: &C) -> Result; + + /// Finds Pets by tags + async fn find_pets_by_tags( + &self, + tags: &Vec, + context: &C) -> Result; + + /// Update an existing pet + async fn update_pet( + &self, + body: models::Pet, + context: &C) -> Result; + + /// Deletes a pet + async fn delete_pet( + &self, + pet_id: i64, + api_key: Option, + context: &C) -> Result; + + /// Find pet by ID + async fn get_pet_by_id( + &self, + pet_id: i64, + context: &C) -> Result; + + /// Updates a pet in the store with form data + async fn update_pet_with_form( + &self, + pet_id: i64, + name: Option, + status: Option, + context: &C) -> Result; + + /// uploads an image + async fn upload_file( + &self, + pet_id: i64, + additional_metadata: Option, + file: Option, + context: &C) -> Result; + + /// Returns pet inventories by status + async fn get_inventory( + &self, + context: &C) -> Result; + + /// Place an order for a pet + async fn place_order( + &self, + body: models::Order, + context: &C) -> Result; + + /// Delete purchase order by ID + async fn delete_order( + &self, + order_id: String, + context: &C) -> Result; + + /// Find purchase order by ID + async fn get_order_by_id( + &self, + order_id: i64, + context: &C) -> Result; + + /// Create user + async fn create_user( + &self, + body: models::User, + context: &C) -> Result; + + /// Creates list of users with given input array + async fn create_users_with_array_input( + &self, + body: &Vec, + context: &C) -> Result; + + /// Creates list of users with given input array + async fn create_users_with_list_input( + &self, + body: &Vec, + context: &C) -> Result; + + /// Logs user into the system + async fn login_user( + &self, + username: String, + password: String, + context: &C) -> Result; + + /// Logs out current logged in user session + async fn logout_user( + &self, + context: &C) -> Result; + + /// Delete user + async fn delete_user( + &self, + username: String, + context: &C) -> Result; + + /// Get user by user name + async fn get_user_by_name( + &self, + username: String, + context: &C) -> Result; + + /// Updated user + async fn update_user( + &self, + username: String, + body: models::User, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + /// To test special tags + async fn test_special_tags( + &self, + body: models::Client, + ) -> Result; + + async fn call123example( + &self, + ) -> Result; + + async fn fake_outer_boolean_serialize( + &self, + body: Option, + ) -> Result; + + async fn fake_outer_composite_serialize( + &self, + body: Option, + ) -> Result; + + async fn fake_outer_number_serialize( + &self, + body: Option, + ) -> Result; + + async fn fake_outer_string_serialize( + &self, + body: Option, + ) -> Result; + + async fn fake_response_with_numerical_description( + &self, + ) -> Result; + + async fn test_body_with_query_params( + &self, + query: String, + body: models::User, + ) -> Result; + + /// To test \"client\" model + async fn test_client_model( + &self, + body: models::Client, + ) -> Result; + + /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + async fn test_endpoint_parameters( + &self, + number: f64, + double: f64, + pattern_without_delimiter: String, + byte: swagger::ByteArray, + integer: Option, + int32: Option, + int64: Option, + float: Option, + string: Option, + binary: Option, + date: Option, + date_time: Option>, + password: Option, + callback: Option, + ) -> Result; + + /// To test enum parameters + async fn test_enum_parameters( + &self, + enum_header_string_array: Option<&Vec>, + enum_header_string: Option, + enum_query_string_array: Option<&Vec>, + enum_query_string: Option, + enum_query_integer: Option, + enum_query_double: Option, + enum_form_string: Option, + ) -> Result; + + /// test inline additionalProperties + async fn test_inline_additional_properties( + &self, + param: std::collections::HashMap, + ) -> Result; + + /// test json serialization of form data + async fn test_json_form_data( + &self, + param: String, + param2: String, + ) -> Result; + + async fn hyphen_param( + &self, + hyphen_param: String, + ) -> Result; + + /// To test class name in snake case + async fn test_classname( + &self, + body: models::Client, + ) -> Result; + + /// Add a new pet to the store + async fn add_pet( + &self, + body: models::Pet, + ) -> Result; + + /// Finds Pets by status + async fn find_pets_by_status( + &self, + status: &Vec, + ) -> Result; + + /// Finds Pets by tags + async fn find_pets_by_tags( + &self, + tags: &Vec, + ) -> Result; + + /// Update an existing pet + async fn update_pet( + &self, + body: models::Pet, + ) -> Result; + + /// Deletes a pet + async fn delete_pet( + &self, + pet_id: i64, + api_key: Option, + ) -> Result; + + /// Find pet by ID + async fn get_pet_by_id( + &self, + pet_id: i64, + ) -> Result; + + /// Updates a pet in the store with form data + async fn update_pet_with_form( + &self, + pet_id: i64, + name: Option, + status: Option, + ) -> Result; + + /// uploads an image + async fn upload_file( + &self, + pet_id: i64, + additional_metadata: Option, + file: Option, + ) -> Result; + + /// Returns pet inventories by status + async fn get_inventory( + &self, + ) -> Result; + + /// Place an order for a pet + async fn place_order( + &self, + body: models::Order, + ) -> Result; + + /// Delete purchase order by ID + async fn delete_order( + &self, + order_id: String, + ) -> Result; + + /// Find purchase order by ID + async fn get_order_by_id( + &self, + order_id: i64, + ) -> Result; + + /// Create user + async fn create_user( + &self, + body: models::User, + ) -> Result; + + /// Creates list of users with given input array + async fn create_users_with_array_input( + &self, + body: &Vec, + ) -> Result; + + /// Creates list of users with given input array + async fn create_users_with_list_input( + &self, + body: &Vec, + ) -> Result; + + /// Logs user into the system + async fn login_user( + &self, + username: String, + password: String, + ) -> Result; + + /// Logs out current logged in user session + async fn logout_user( + &self, + ) -> Result; + + /// Delete user + async fn delete_user( + &self, + username: String, + ) -> Result; + + /// Get user by user name + async fn get_user_by_name( + &self, + username: String, + ) -> Result; + + /// Updated user + async fn update_user( + &self, + username: String, + body: models::User, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + /// To test special tags + async fn test_special_tags( + &self, + body: models::Client, + ) -> Result + { + let context = self.context().clone(); + self.api().test_special_tags(body, &context).await + } + + async fn call123example( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().call123example(&context).await + } + + async fn fake_outer_boolean_serialize( + &self, + body: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().fake_outer_boolean_serialize(body, &context).await + } + + async fn fake_outer_composite_serialize( + &self, + body: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().fake_outer_composite_serialize(body, &context).await + } + + async fn fake_outer_number_serialize( + &self, + body: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().fake_outer_number_serialize(body, &context).await + } + + async fn fake_outer_string_serialize( + &self, + body: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().fake_outer_string_serialize(body, &context).await + } + + async fn fake_response_with_numerical_description( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().fake_response_with_numerical_description(&context).await + } + + async fn test_body_with_query_params( + &self, + query: String, + body: models::User, + ) -> Result + { + let context = self.context().clone(); + self.api().test_body_with_query_params(query, body, &context).await + } + + /// To test \"client\" model + async fn test_client_model( + &self, + body: models::Client, + ) -> Result + { + let context = self.context().clone(); + self.api().test_client_model(body, &context).await + } + + /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 + async fn test_endpoint_parameters( + &self, + number: f64, + double: f64, + pattern_without_delimiter: String, + byte: swagger::ByteArray, + integer: Option, + int32: Option, + int64: Option, + float: Option, + string: Option, + binary: Option, + date: Option, + date_time: Option>, + password: Option, + callback: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().test_endpoint_parameters(number, double, pattern_without_delimiter, byte, integer, int32, int64, float, string, binary, date, date_time, password, callback, &context).await + } + + /// To test enum parameters + async fn test_enum_parameters( + &self, + enum_header_string_array: Option<&Vec>, + enum_header_string: Option, + enum_query_string_array: Option<&Vec>, + enum_query_string: Option, + enum_query_integer: Option, + enum_query_double: Option, + enum_form_string: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().test_enum_parameters(enum_header_string_array, enum_header_string, enum_query_string_array, enum_query_string, enum_query_integer, enum_query_double, enum_form_string, &context).await + } + + /// test inline additionalProperties + async fn test_inline_additional_properties( + &self, + param: std::collections::HashMap, + ) -> Result + { + let context = self.context().clone(); + self.api().test_inline_additional_properties(param, &context).await + } + + /// test json serialization of form data + async fn test_json_form_data( + &self, + param: String, + param2: String, + ) -> Result + { + let context = self.context().clone(); + self.api().test_json_form_data(param, param2, &context).await + } + + async fn hyphen_param( + &self, + hyphen_param: String, + ) -> Result + { + let context = self.context().clone(); + self.api().hyphen_param(hyphen_param, &context).await + } + + /// To test class name in snake case + async fn test_classname( + &self, + body: models::Client, + ) -> Result + { + let context = self.context().clone(); + self.api().test_classname(body, &context).await + } + + /// Add a new pet to the store + async fn add_pet( + &self, + body: models::Pet, + ) -> Result + { + let context = self.context().clone(); + self.api().add_pet(body, &context).await + } + + /// Finds Pets by status + async fn find_pets_by_status( + &self, + status: &Vec, + ) -> Result + { + let context = self.context().clone(); + self.api().find_pets_by_status(status, &context).await + } + + /// Finds Pets by tags + async fn find_pets_by_tags( + &self, + tags: &Vec, + ) -> Result + { + let context = self.context().clone(); + self.api().find_pets_by_tags(tags, &context).await + } + + /// Update an existing pet + async fn update_pet( + &self, + body: models::Pet, + ) -> Result + { + let context = self.context().clone(); + self.api().update_pet(body, &context).await + } + + /// Deletes a pet + async fn delete_pet( + &self, + pet_id: i64, + api_key: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().delete_pet(pet_id, api_key, &context).await + } + + /// Find pet by ID + async fn get_pet_by_id( + &self, + pet_id: i64, + ) -> Result + { + let context = self.context().clone(); + self.api().get_pet_by_id(pet_id, &context).await + } + + /// Updates a pet in the store with form data + async fn update_pet_with_form( + &self, + pet_id: i64, + name: Option, + status: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().update_pet_with_form(pet_id, name, status, &context).await + } + + /// uploads an image + async fn upload_file( + &self, + pet_id: i64, + additional_metadata: Option, + file: Option, + ) -> Result + { + let context = self.context().clone(); + self.api().upload_file(pet_id, additional_metadata, file, &context).await + } + + /// Returns pet inventories by status + async fn get_inventory( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().get_inventory(&context).await + } + + /// Place an order for a pet + async fn place_order( + &self, + body: models::Order, + ) -> Result + { + let context = self.context().clone(); + self.api().place_order(body, &context).await + } + + /// Delete purchase order by ID + async fn delete_order( + &self, + order_id: String, + ) -> Result + { + let context = self.context().clone(); + self.api().delete_order(order_id, &context).await + } + + /// Find purchase order by ID + async fn get_order_by_id( + &self, + order_id: i64, + ) -> Result + { + let context = self.context().clone(); + self.api().get_order_by_id(order_id, &context).await + } + + /// Create user + async fn create_user( + &self, + body: models::User, + ) -> Result + { + let context = self.context().clone(); + self.api().create_user(body, &context).await + } + + /// Creates list of users with given input array + async fn create_users_with_array_input( + &self, + body: &Vec, + ) -> Result + { + let context = self.context().clone(); + self.api().create_users_with_array_input(body, &context).await + } + + /// Creates list of users with given input array + async fn create_users_with_list_input( + &self, + body: &Vec, + ) -> Result + { + let context = self.context().clone(); + self.api().create_users_with_list_input(body, &context).await + } + + /// Logs user into the system + async fn login_user( + &self, + username: String, + password: String, + ) -> Result + { + let context = self.context().clone(); + self.api().login_user(username, password, &context).await + } + + /// Logs out current logged in user session + async fn logout_user( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().logout_user(&context).await + } + + /// Delete user + async fn delete_user( + &self, + username: String, + ) -> Result + { + let context = self.context().clone(); + self.api().delete_user(username, &context).await + } + + /// Get user by user name + async fn get_user_by_name( + &self, + username: String, + ) -> Result + { + let context = self.context().clone(); + self.api().get_user_by_name(username, &context).await + } + + /// Updated user + async fn update_user( + &self, + username: String, + body: models::User, + ) -> Result + { + let context = self.context().clone(); + self.api().update_user(username, body, &context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs new file mode 100644 index 000000000000..4ab8b1568999 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs @@ -0,0 +1,8798 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AdditionalPropertiesClass { + #[serde(rename = "map_property")] + #[serde(skip_serializing_if="Option::is_none")] + pub map_property: Option>, + + #[serde(rename = "map_of_map_property")] + #[serde(skip_serializing_if="Option::is_none")] + pub map_of_map_property: Option>>, + +} + + +impl AdditionalPropertiesClass { + #[allow(clippy::new_without_default)] + pub fn new() -> AdditionalPropertiesClass { + AdditionalPropertiesClass { + map_property: None, + map_of_map_property: None, + } + } +} + +/// Converts the AdditionalPropertiesClass value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AdditionalPropertiesClass { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping map map_property in query parameter serialization + // Skipping map map_of_map_property in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesClass value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AdditionalPropertiesClass { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub map_property: Vec>, + pub map_of_map_property: Vec>>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing AdditionalPropertiesClass".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "map_property" => return std::result::Result::Err("Parsing a container in this style is not supported in AdditionalPropertiesClass".to_string()), + "map_of_map_property" => return std::result::Result::Err("Parsing a container in this style is not supported in AdditionalPropertiesClass".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing AdditionalPropertiesClass".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(AdditionalPropertiesClass { + map_property: intermediate_rep.map_property.into_iter().next(), + map_of_map_property: intermediate_rep.map_of_map_property.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AdditionalPropertiesClass - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AdditionalPropertiesClass - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesClass - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AdditionalPropertiesClass { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Animal { + #[serde(rename = "className")] + pub class_name: String, + + #[serde(rename = "color")] + #[serde(skip_serializing_if="Option::is_none")] + pub color: Option, + +} + + +impl Animal { + #[allow(clippy::new_without_default)] + pub fn new(class_name: String, ) -> Animal { + Animal { + class_name, + color: Some("red".to_string()), + } + } +} + +/// Converts the Animal value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Animal { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("className".to_string()), + Some(self.class_name.to_string()), + self.color.as_ref().map(|color| { + [ + "color".to_string(), + color.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Animal value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Animal { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub class_name: Vec, + pub color: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Animal".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "className" => intermediate_rep.class_name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "color" => intermediate_rep.color.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Animal".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Animal { + class_name: intermediate_rep.class_name.into_iter().next().ok_or_else(|| "className missing in Animal".to_string())?, + color: intermediate_rep.color.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Animal - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Animal - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Animal - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Animal { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AnimalFarm( + Vec +); + +impl std::convert::From> for AnimalFarm { + fn from(x: Vec) -> Self { + AnimalFarm(x) + } +} + +impl std::convert::From for Vec { + fn from(x: AnimalFarm) -> Self { + x.0 + } +} + +impl std::iter::FromIterator for AnimalFarm { + fn from_iter>(u: U) -> Self { + AnimalFarm(Vec::::from_iter(u)) + } +} + +impl std::iter::IntoIterator for AnimalFarm { + type Item = Animal; + type IntoIter = std::vec::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a AnimalFarm { + type Item = &'a Animal; + type IntoIter = std::slice::Iter<'a, Animal>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'a> std::iter::IntoIterator for &'a mut AnimalFarm { + type Item = &'a mut Animal; + type IntoIter = std::slice::IterMut<'a, Animal>; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter_mut() + } +} + +impl std::ops::Deref for AnimalFarm { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl std::ops::DerefMut for AnimalFarm { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +/// Converts the AnimalFarm value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AnimalFarm { + fn to_string(&self) -> String { + self.iter().map(|x| x.to_string()).collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AnimalFarm value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AnimalFarm { + type Err = ::Err; + + fn from_str(s: &str) -> std::result::Result { + let mut items = vec![]; + for item in s.split(',') + { + items.push(item.parse()?); + } + std::result::Result::Ok(AnimalFarm(items)) + } +} + + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AnimalFarm - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AnimalFarm - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AnimalFarm - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl AnimalFarm { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ApiResponse { + #[serde(rename = "code")] + #[serde(skip_serializing_if="Option::is_none")] + pub code: Option, + + #[serde(rename = "type")] + #[serde(skip_serializing_if="Option::is_none")] + pub r#type: Option, + + #[serde(rename = "message")] + #[serde(skip_serializing_if="Option::is_none")] + pub message: Option, + +} + + +impl ApiResponse { + #[allow(clippy::new_without_default)] + pub fn new() -> ApiResponse { + ApiResponse { + code: None, + r#type: None, + message: None, + } + } +} + +/// Converts the ApiResponse value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ApiResponse { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.code.as_ref().map(|code| { + [ + "code".to_string(), + code.to_string(), + ].join(",") + }), + self.r#type.as_ref().map(|r#type| { + [ + "type".to_string(), + r#type.to_string(), + ].join(",") + }), + self.message.as_ref().map(|message| { + [ + "message".to_string(), + message.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ApiResponse value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ApiResponse { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub code: Vec, + pub r#type: Vec, + pub message: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ApiResponse".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "code" => intermediate_rep.code.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "type" => intermediate_rep.r#type.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "message" => intermediate_rep.message.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ApiResponse".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ApiResponse { + code: intermediate_rep.code.into_iter().next(), + r#type: intermediate_rep.r#type.into_iter().next(), + message: intermediate_rep.message.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ApiResponse - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ApiResponse - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ApiResponse - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ApiResponse { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ArrayOfArrayOfNumberOnly { + #[serde(rename = "ArrayArrayNumber")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_array_number: Option>>, + +} + + +impl ArrayOfArrayOfNumberOnly { + #[allow(clippy::new_without_default)] + pub fn new() -> ArrayOfArrayOfNumberOnly { + ArrayOfArrayOfNumberOnly { + array_array_number: None, + } + } +} + +/// Converts the ArrayOfArrayOfNumberOnly value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ArrayOfArrayOfNumberOnly { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type ArrayArrayNumber in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ArrayOfArrayOfNumberOnly value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ArrayOfArrayOfNumberOnly { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub array_array_number: Vec>>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ArrayOfArrayOfNumberOnly".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "ArrayArrayNumber" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayOfArrayOfNumberOnly".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing ArrayOfArrayOfNumberOnly".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ArrayOfArrayOfNumberOnly { + array_array_number: intermediate_rep.array_array_number.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ArrayOfArrayOfNumberOnly - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ArrayOfArrayOfNumberOnly - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ArrayOfArrayOfNumberOnly - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ArrayOfArrayOfNumberOnly { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ArrayOfNumberOnly { + #[serde(rename = "ArrayNumber")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_number: Option>, + +} + + +impl ArrayOfNumberOnly { + #[allow(clippy::new_without_default)] + pub fn new() -> ArrayOfNumberOnly { + ArrayOfNumberOnly { + array_number: None, + } + } +} + +/// Converts the ArrayOfNumberOnly value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ArrayOfNumberOnly { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.array_number.as_ref().map(|array_number| { + [ + "ArrayNumber".to_string(), + array_number.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ArrayOfNumberOnly value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ArrayOfNumberOnly { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub array_number: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ArrayOfNumberOnly".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "ArrayNumber" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayOfNumberOnly".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing ArrayOfNumberOnly".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ArrayOfNumberOnly { + array_number: intermediate_rep.array_number.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ArrayOfNumberOnly - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ArrayOfNumberOnly - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ArrayOfNumberOnly - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ArrayOfNumberOnly { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ArrayTest { + #[serde(rename = "array_of_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_of_string: Option>, + + #[serde(rename = "array_array_of_integer")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_array_of_integer: Option>>, + + #[serde(rename = "array_array_of_model")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_array_of_model: Option>>, + + #[serde(rename = "array_of_enum")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_of_enum: Option>, + +} + + +impl ArrayTest { + #[allow(clippy::new_without_default)] + pub fn new() -> ArrayTest { + ArrayTest { + array_of_string: None, + array_array_of_integer: None, + array_array_of_model: None, + array_of_enum: None, + } + } +} + +/// Converts the ArrayTest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ArrayTest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.array_of_string.as_ref().map(|array_of_string| { + [ + "array_of_string".to_string(), + array_of_string.iter().map(|x| x.to_string()).collect::>().join(","), + ].join(",") + }), + // Skipping non-primitive type array_array_of_integer in query parameter serialization + // Skipping non-primitive type array_array_of_model in query parameter serialization + // Skipping non-primitive type array_of_enum in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ArrayTest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ArrayTest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub array_of_string: Vec>, + pub array_array_of_integer: Vec>>, + pub array_array_of_model: Vec>>, + pub array_of_enum: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ArrayTest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "array_of_string" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayTest".to_string()), + "array_array_of_integer" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayTest".to_string()), + "array_array_of_model" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayTest".to_string()), + "array_of_enum" => return std::result::Result::Err("Parsing a container in this style is not supported in ArrayTest".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing ArrayTest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ArrayTest { + array_of_string: intermediate_rep.array_of_string.into_iter().next(), + array_array_of_integer: intermediate_rep.array_array_of_integer.into_iter().next(), + array_array_of_model: intermediate_rep.array_array_of_model.into_iter().next(), + array_of_enum: intermediate_rep.array_of_enum.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ArrayTest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ArrayTest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ArrayTest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ArrayTest { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Capitalization { + #[serde(rename = "smallCamel")] + #[serde(skip_serializing_if="Option::is_none")] + pub small_camel: Option, + + #[serde(rename = "CapitalCamel")] + #[serde(skip_serializing_if="Option::is_none")] + pub capital_camel: Option, + + #[serde(rename = "small_Snake")] + #[serde(skip_serializing_if="Option::is_none")] + pub small_snake: Option, + + #[serde(rename = "Capital_Snake")] + #[serde(skip_serializing_if="Option::is_none")] + pub capital_snake: Option, + + #[serde(rename = "SCA_ETH_Flow_Points")] + #[serde(skip_serializing_if="Option::is_none")] + pub sca_eth_flow_points: Option, + + /// Name of the pet + #[serde(rename = "ATT_NAME")] + #[serde(skip_serializing_if="Option::is_none")] + pub att_name: Option, + +} + + +impl Capitalization { + #[allow(clippy::new_without_default)] + pub fn new() -> Capitalization { + Capitalization { + small_camel: None, + capital_camel: None, + small_snake: None, + capital_snake: None, + sca_eth_flow_points: None, + att_name: None, + } + } +} + +/// Converts the Capitalization value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Capitalization { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.small_camel.as_ref().map(|small_camel| { + [ + "smallCamel".to_string(), + small_camel.to_string(), + ].join(",") + }), + self.capital_camel.as_ref().map(|capital_camel| { + [ + "CapitalCamel".to_string(), + capital_camel.to_string(), + ].join(",") + }), + self.small_snake.as_ref().map(|small_snake| { + [ + "small_Snake".to_string(), + small_snake.to_string(), + ].join(",") + }), + self.capital_snake.as_ref().map(|capital_snake| { + [ + "Capital_Snake".to_string(), + capital_snake.to_string(), + ].join(",") + }), + self.sca_eth_flow_points.as_ref().map(|sca_eth_flow_points| { + [ + "SCA_ETH_Flow_Points".to_string(), + sca_eth_flow_points.to_string(), + ].join(",") + }), + self.att_name.as_ref().map(|att_name| { + [ + "ATT_NAME".to_string(), + att_name.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Capitalization value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Capitalization { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub small_camel: Vec, + pub capital_camel: Vec, + pub small_snake: Vec, + pub capital_snake: Vec, + pub sca_eth_flow_points: Vec, + pub att_name: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Capitalization".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "smallCamel" => intermediate_rep.small_camel.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "CapitalCamel" => intermediate_rep.capital_camel.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "small_Snake" => intermediate_rep.small_snake.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "Capital_Snake" => intermediate_rep.capital_snake.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "SCA_ETH_Flow_Points" => intermediate_rep.sca_eth_flow_points.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "ATT_NAME" => intermediate_rep.att_name.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Capitalization".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Capitalization { + small_camel: intermediate_rep.small_camel.into_iter().next(), + capital_camel: intermediate_rep.capital_camel.into_iter().next(), + small_snake: intermediate_rep.small_snake.into_iter().next(), + capital_snake: intermediate_rep.capital_snake.into_iter().next(), + sca_eth_flow_points: intermediate_rep.sca_eth_flow_points.into_iter().next(), + att_name: intermediate_rep.att_name.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Capitalization - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Capitalization - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Capitalization - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Capitalization { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Cat { + #[serde(rename = "className")] + pub class_name: String, + + #[serde(rename = "color")] + #[serde(skip_serializing_if="Option::is_none")] + pub color: Option, + + #[serde(rename = "declawed")] + #[serde(skip_serializing_if="Option::is_none")] + pub declawed: Option, + +} + + +impl Cat { + #[allow(clippy::new_without_default)] + pub fn new(class_name: String, ) -> Cat { + Cat { + class_name, + color: Some("red".to_string()), + declawed: None, + } + } +} + +/// Converts the Cat value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Cat { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("className".to_string()), + Some(self.class_name.to_string()), + self.color.as_ref().map(|color| { + [ + "color".to_string(), + color.to_string(), + ].join(",") + }), + self.declawed.as_ref().map(|declawed| { + [ + "declawed".to_string(), + declawed.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Cat value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Cat { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub class_name: Vec, + pub color: Vec, + pub declawed: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Cat".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "className" => intermediate_rep.class_name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "color" => intermediate_rep.color.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "declawed" => intermediate_rep.declawed.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Cat".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Cat { + class_name: intermediate_rep.class_name.into_iter().next().ok_or_else(|| "className missing in Cat".to_string())?, + color: intermediate_rep.color.into_iter().next(), + declawed: intermediate_rep.declawed.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Cat - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Cat - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Cat - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Cat { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Category")] +pub struct Category { + #[serde(rename = "id")] + #[serde(skip_serializing_if="Option::is_none")] + pub id: Option, + + #[serde(rename = "name")] + #[serde(skip_serializing_if="Option::is_none")] + pub name: Option, + +} + + +impl Category { + #[allow(clippy::new_without_default)] + pub fn new() -> Category { + Category { + id: None, + name: None, + } + } +} + +/// Converts the Category value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Category { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.id.as_ref().map(|id| { + [ + "id".to_string(), + id.to_string(), + ].join(",") + }), + self.name.as_ref().map(|name| { + [ + "name".to_string(), + name.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Category value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Category { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub name: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Category".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "name" => intermediate_rep.name.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Category".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Category { + id: intermediate_rep.id.into_iter().next(), + name: intermediate_rep.name.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Category - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Category - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Category - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Category { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Model for testing model with \"_class\" property +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ClassModel { + #[serde(rename = "_class")] + #[serde(skip_serializing_if="Option::is_none")] + pub _class: Option, + +} + + +impl ClassModel { + #[allow(clippy::new_without_default)] + pub fn new() -> ClassModel { + ClassModel { + _class: None, + } + } +} + +/// Converts the ClassModel value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ClassModel { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self._class.as_ref().map(|_class| { + [ + "_class".to_string(), + _class.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ClassModel value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ClassModel { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub _class: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ClassModel".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "_class" => intermediate_rep._class.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ClassModel".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ClassModel { + _class: intermediate_rep._class.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ClassModel - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ClassModel - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ClassModel - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ClassModel { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Client { + #[serde(rename = "client")] + #[serde(skip_serializing_if="Option::is_none")] + pub client: Option, + +} + + +impl Client { + #[allow(clippy::new_without_default)] + pub fn new() -> Client { + Client { + client: None, + } + } +} + +/// Converts the Client value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Client { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.client.as_ref().map(|client| { + [ + "client".to_string(), + client.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Client value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Client { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub client: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Client".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "client" => intermediate_rep.client.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Client".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Client { + client: intermediate_rep.client.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Client - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Client - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Client - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Client { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct Dog { + #[serde(rename = "className")] + pub class_name: String, + + #[serde(rename = "color")] + #[serde(skip_serializing_if="Option::is_none")] + pub color: Option, + + #[serde(rename = "breed")] + #[serde(skip_serializing_if="Option::is_none")] + pub breed: Option, + +} + + +impl Dog { + #[allow(clippy::new_without_default)] + pub fn new(class_name: String, ) -> Dog { + Dog { + class_name, + color: Some("red".to_string()), + breed: None, + } + } +} + +/// Converts the Dog value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Dog { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("className".to_string()), + Some(self.class_name.to_string()), + self.color.as_ref().map(|color| { + [ + "color".to_string(), + color.to_string(), + ].join(",") + }), + self.breed.as_ref().map(|breed| { + [ + "breed".to_string(), + breed.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Dog value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Dog { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub class_name: Vec, + pub color: Vec, + pub breed: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Dog".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "className" => intermediate_rep.class_name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "color" => intermediate_rep.color.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "breed" => intermediate_rep.breed.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Dog".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Dog { + class_name: intermediate_rep.class_name.into_iter().next().ok_or_else(|| "className missing in Dog".to_string())?, + color: intermediate_rep.color.into_iter().next(), + breed: intermediate_rep.breed.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Dog - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Dog - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Dog - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Dog { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "$special[model.name]")] +pub struct DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + #[serde(rename = "$special[property.name]")] + #[serde(skip_serializing_if="Option::is_none")] + pub dollar_special_left_square_bracket_property_name_right_square_bracket: Option, + +} + + +impl DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + #[allow(clippy::new_without_default)] + pub fn new() -> DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + dollar_special_left_square_bracket_property_name_right_square_bracket: None, + } + } +} + +/// Converts the DollarSpecialLeftSquareBracketModelNameRightSquareBracket value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.dollar_special_left_square_bracket_property_name_right_square_bracket.as_ref().map(|dollar_special_left_square_bracket_property_name_right_square_bracket| { + [ + "$special[property.name]".to_string(), + dollar_special_left_square_bracket_property_name_right_square_bracket.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a DollarSpecialLeftSquareBracketModelNameRightSquareBracket value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub dollar_special_left_square_bracket_property_name_right_square_bracket: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing DollarSpecialLeftSquareBracketModelNameRightSquareBracket".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "$special[property.name]" => intermediate_rep.dollar_special_left_square_bracket_property_name_right_square_bracket.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing DollarSpecialLeftSquareBracketModelNameRightSquareBracket".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + dollar_special_left_square_bracket_property_name_right_square_bracket: intermediate_rep.dollar_special_left_square_bracket_property_name_right_square_bracket.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for DollarSpecialLeftSquareBracketModelNameRightSquareBracket - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct EnumArrays { + #[serde(rename = "just_symbol")] + #[serde(skip_serializing_if="Option::is_none")] + pub just_symbol: Option, + + #[serde(rename = "array_enum")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_enum: Option>, + + #[serde(rename = "array_array_enum")] + #[serde(skip_serializing_if="Option::is_none")] + pub array_array_enum: Option>>, + +} + + +impl EnumArrays { + #[allow(clippy::new_without_default)] + pub fn new() -> EnumArrays { + EnumArrays { + just_symbol: None, + array_enum: None, + array_array_enum: None, + } + } +} + +/// Converts the EnumArrays value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for EnumArrays { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type just_symbol in query parameter serialization + // Skipping non-primitive type array_enum in query parameter serialization + // Skipping non-primitive type array_array_enum in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a EnumArrays value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for EnumArrays { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub just_symbol: Vec, + pub array_enum: Vec>, + pub array_array_enum: Vec>>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing EnumArrays".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "just_symbol" => intermediate_rep.just_symbol.push(::from_str(val).map_err(|x| x.to_string())?), + "array_enum" => return std::result::Result::Err("Parsing a container in this style is not supported in EnumArrays".to_string()), + "array_array_enum" => return std::result::Result::Err("Parsing a container in this style is not supported in EnumArrays".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing EnumArrays".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(EnumArrays { + just_symbol: intermediate_rep.just_symbol.into_iter().next(), + array_enum: intermediate_rep.array_enum.into_iter().next(), + array_array_enum: intermediate_rep.array_array_enum.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumArrays - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumArrays - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumArrays - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumArrays { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumArraysArrayArrayEnumInnerInner { + #[serde(rename = "Cat")] + Cat, + #[serde(rename = "Dog")] + Dog, +} + +impl std::fmt::Display for EnumArraysArrayArrayEnumInnerInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumArraysArrayArrayEnumInnerInner::Cat => write!(f, "Cat"), + EnumArraysArrayArrayEnumInnerInner::Dog => write!(f, "Dog"), + } + } +} + +impl std::str::FromStr for EnumArraysArrayArrayEnumInnerInner { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "Cat" => std::result::Result::Ok(EnumArraysArrayArrayEnumInnerInner::Cat), + "Dog" => std::result::Result::Ok(EnumArraysArrayArrayEnumInnerInner::Dog), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumArraysArrayArrayEnumInnerInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumArraysArrayArrayEnumInnerInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumArraysArrayArrayEnumInnerInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumArraysArrayArrayEnumInnerInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumArraysArrayEnumInner { + #[serde(rename = "fish")] + Fish, + #[serde(rename = "crab")] + Crab, +} + +impl std::fmt::Display for EnumArraysArrayEnumInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumArraysArrayEnumInner::Fish => write!(f, "fish"), + EnumArraysArrayEnumInner::Crab => write!(f, "crab"), + } + } +} + +impl std::str::FromStr for EnumArraysArrayEnumInner { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "fish" => std::result::Result::Ok(EnumArraysArrayEnumInner::Fish), + "crab" => std::result::Result::Ok(EnumArraysArrayEnumInner::Crab), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumArraysArrayEnumInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumArraysArrayEnumInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumArraysArrayEnumInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumArraysArrayEnumInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumArraysJustSymbol { + #[serde(rename = ">=")] + GreaterThanEqual, + #[serde(rename = "$")] + Dollar, +} + +impl std::fmt::Display for EnumArraysJustSymbol { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumArraysJustSymbol::GreaterThanEqual => write!(f, ">="), + EnumArraysJustSymbol::Dollar => write!(f, "$"), + } + } +} + +impl std::str::FromStr for EnumArraysJustSymbol { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + ">=" => std::result::Result::Ok(EnumArraysJustSymbol::GreaterThanEqual), + "$" => std::result::Result::Ok(EnumArraysJustSymbol::Dollar), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumArraysJustSymbol - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumArraysJustSymbol - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumArraysJustSymbol - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumArraysJustSymbol { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumClass { + #[serde(rename = "_abc")] + Abc, + #[serde(rename = "-efg")] + Efg, + #[serde(rename = "(xyz)")] + LeftParenthesisXyzRightParenthesis, +} + +impl std::fmt::Display for EnumClass { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumClass::Abc => write!(f, "_abc"), + EnumClass::Efg => write!(f, "-efg"), + EnumClass::LeftParenthesisXyzRightParenthesis => write!(f, "(xyz)"), + } + } +} + +impl std::str::FromStr for EnumClass { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "_abc" => std::result::Result::Ok(EnumClass::Abc), + "-efg" => std::result::Result::Ok(EnumClass::Efg), + "(xyz)" => std::result::Result::Ok(EnumClass::LeftParenthesisXyzRightParenthesis), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumClass - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumClass - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumClass - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumClass { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct EnumTest { + #[serde(rename = "enum_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub enum_string: Option, + + #[serde(rename = "enum_string_required")] + pub enum_string_required: models::EnumTestEnumString, + + #[serde(rename = "enum_integer")] + #[serde(skip_serializing_if="Option::is_none")] + pub enum_integer: Option, + + #[serde(rename = "enum_number")] + #[serde(skip_serializing_if="Option::is_none")] + pub enum_number: Option, + + #[serde(rename = "outerEnum")] + #[serde(skip_serializing_if="Option::is_none")] + pub outer_enum: Option, + +} + + +impl EnumTest { + #[allow(clippy::new_without_default)] + pub fn new(enum_string_required: models::EnumTestEnumString, ) -> EnumTest { + EnumTest { + enum_string: None, + enum_string_required, + enum_integer: None, + enum_number: None, + outer_enum: None, + } + } +} + +/// Converts the EnumTest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for EnumTest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type enum_string in query parameter serialization + // Skipping non-primitive type enum_string_required in query parameter serialization + // Skipping non-primitive type enum_integer in query parameter serialization + // Skipping non-primitive type enum_number in query parameter serialization + // Skipping non-primitive type outerEnum in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a EnumTest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for EnumTest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub enum_string: Vec, + pub enum_string_required: Vec, + pub enum_integer: Vec, + pub enum_number: Vec, + pub outer_enum: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing EnumTest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "enum_string" => intermediate_rep.enum_string.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "enum_string_required" => intermediate_rep.enum_string_required.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "enum_integer" => intermediate_rep.enum_integer.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "enum_number" => intermediate_rep.enum_number.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "outerEnum" => intermediate_rep.outer_enum.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing EnumTest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(EnumTest { + enum_string: intermediate_rep.enum_string.into_iter().next(), + enum_string_required: intermediate_rep.enum_string_required.into_iter().next().ok_or_else(|| "enum_string_required missing in EnumTest".to_string())?, + enum_integer: intermediate_rep.enum_integer.into_iter().next(), + enum_number: intermediate_rep.enum_number.into_iter().next(), + outer_enum: intermediate_rep.outer_enum.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumTest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumTest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumTest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumTest { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumTestEnumInteger { + #[serde(rename = "1")] + Variant1, + #[serde(rename = "-1")] + Variant12, +} + +impl std::fmt::Display for EnumTestEnumInteger { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumTestEnumInteger::Variant1 => write!(f, "1"), + EnumTestEnumInteger::Variant12 => write!(f, "-1"), + } + } +} + +impl std::str::FromStr for EnumTestEnumInteger { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "1" => std::result::Result::Ok(EnumTestEnumInteger::Variant1), + "-1" => std::result::Result::Ok(EnumTestEnumInteger::Variant12), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumTestEnumInteger - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumTestEnumInteger - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumTestEnumInteger - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumTestEnumInteger { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum EnumTestEnumString { + #[serde(rename = "UPPER")] + Upper, + #[serde(rename = "lower")] + Lower, + #[serde(rename = "")] + Empty, +} + +impl std::fmt::Display for EnumTestEnumString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + EnumTestEnumString::Upper => write!(f, "UPPER"), + EnumTestEnumString::Lower => write!(f, "lower"), + EnumTestEnumString::Empty => write!(f, ""), + } + } +} + +impl std::str::FromStr for EnumTestEnumString { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "UPPER" => std::result::Result::Ok(EnumTestEnumString::Upper), + "lower" => std::result::Result::Ok(EnumTestEnumString::Lower), + "" => std::result::Result::Ok(EnumTestEnumString::Empty), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for EnumTestEnumString - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into EnumTestEnumString - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into EnumTestEnumString - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl EnumTestEnumString { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum FindPetsByStatusStatusParameterInner { + #[serde(rename = "available")] + Available, + #[serde(rename = "pending")] + Pending, + #[serde(rename = "sold")] + Sold, +} + +impl std::fmt::Display for FindPetsByStatusStatusParameterInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + FindPetsByStatusStatusParameterInner::Available => write!(f, "available"), + FindPetsByStatusStatusParameterInner::Pending => write!(f, "pending"), + FindPetsByStatusStatusParameterInner::Sold => write!(f, "sold"), + } + } +} + +impl std::str::FromStr for FindPetsByStatusStatusParameterInner { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "available" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Available), + "pending" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Pending), + "sold" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Sold), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for FindPetsByStatusStatusParameterInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into FindPetsByStatusStatusParameterInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into FindPetsByStatusStatusParameterInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl FindPetsByStatusStatusParameterInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct FormatTest { + #[serde(rename = "integer")] + #[validate( + range(min = 10, max = 100), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub integer: Option, + + #[serde(rename = "int32")] + #[validate( + range(min = 20, max = 200), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub int32: Option, + + #[serde(rename = "int64")] + #[serde(skip_serializing_if="Option::is_none")] + pub int64: Option, + + #[serde(rename = "number")] + #[validate( + range(min = 32.1, max = 543.2), + )] + pub number: f64, + + #[serde(rename = "float")] + #[validate( + range(min = 54.3, max = 987.6), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub float: Option, + + #[serde(rename = "double")] + #[validate( + range(min = 67.8, max = 123.4), + )] + #[serde(skip_serializing_if="Option::is_none")] + pub double: Option, + + #[serde(rename = "string")] + #[validate( + regex = "RE_FORMATTEST_STRING", + )] + #[serde(skip_serializing_if="Option::is_none")] + pub string: Option, + + #[serde(rename = "byte")] + #[validate( + custom ="validate_byte_formattest_byte" + )] + pub byte: swagger::ByteArray, + + #[serde(rename = "binary")] + #[serde(skip_serializing_if="Option::is_none")] + pub binary: Option, + + #[serde(rename = "date")] + pub date: chrono::naive::NaiveDate, + + #[serde(rename = "dateTime")] + #[serde(skip_serializing_if="Option::is_none")] + pub date_time: Option>, + + #[serde(rename = "uuid")] + #[serde(skip_serializing_if="Option::is_none")] + pub uuid: Option, + + #[serde(rename = "password")] + #[validate( + length(min = 10, max = 64), + )] + pub password: String, + +} + +lazy_static::lazy_static! { + static ref RE_FORMATTEST_STRING: regex::Regex = regex::Regex::new(r"/[a-z]/i").unwrap(); +} +lazy_static::lazy_static! { + static ref RE_FORMATTEST_BYTE: regex::bytes::Regex = regex::bytes::Regex::new(r"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$").unwrap(); +} +fn validate_byte_formattest_byte( + b: &swagger::ByteArray +) -> Result<(), validator::ValidationError> { + if !RE_FORMATTEST_BYTE.is_match(b) { + return Err(validator::ValidationError::new("Character not allowed")); + } + Ok(()) +} + +impl FormatTest { + #[allow(clippy::new_without_default)] + pub fn new(number: f64, byte: swagger::ByteArray, date: chrono::naive::NaiveDate, password: String, ) -> FormatTest { + FormatTest { + integer: None, + int32: None, + int64: None, + number, + float: None, + double: None, + string: None, + byte, + binary: None, + date, + date_time: None, + uuid: None, + password, + } + } +} + +/// Converts the FormatTest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for FormatTest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.integer.as_ref().map(|integer| { + [ + "integer".to_string(), + integer.to_string(), + ].join(",") + }), + self.int32.as_ref().map(|int32| { + [ + "int32".to_string(), + int32.to_string(), + ].join(",") + }), + self.int64.as_ref().map(|int64| { + [ + "int64".to_string(), + int64.to_string(), + ].join(",") + }), + Some("number".to_string()), + Some(self.number.to_string()), + self.float.as_ref().map(|float| { + [ + "float".to_string(), + float.to_string(), + ].join(",") + }), + self.double.as_ref().map(|double| { + [ + "double".to_string(), + double.to_string(), + ].join(",") + }), + self.string.as_ref().map(|string| { + [ + "string".to_string(), + string.to_string(), + ].join(",") + }), + // Skipping byte array byte in query parameter serialization + // Skipping binary data binary in query parameter serialization + // Skipping non-primitive type date in query parameter serialization + // Skipping non-primitive type dateTime in query parameter serialization + // Skipping non-primitive type uuid in query parameter serialization + Some("password".to_string()), + Some(self.password.to_string()), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a FormatTest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for FormatTest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub integer: Vec, + pub int32: Vec, + pub int64: Vec, + pub number: Vec, + pub float: Vec, + pub double: Vec, + pub string: Vec, + pub byte: Vec, + pub binary: Vec, + pub date: Vec, + pub date_time: Vec>, + pub uuid: Vec, + pub password: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing FormatTest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "integer" => intermediate_rep.integer.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "int32" => intermediate_rep.int32.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "int64" => intermediate_rep.int64.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "number" => intermediate_rep.number.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "float" => intermediate_rep.float.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "double" => intermediate_rep.double.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "string" => intermediate_rep.string.push(::from_str(val).map_err(|x| x.to_string())?), + "byte" => return std::result::Result::Err("Parsing binary data in this style is not supported in FormatTest".to_string()), + "binary" => return std::result::Result::Err("Parsing binary data in this style is not supported in FormatTest".to_string()), + #[allow(clippy::redundant_clone)] + "date" => intermediate_rep.date.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "dateTime" => intermediate_rep.date_time.push( as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "uuid" => intermediate_rep.uuid.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "password" => intermediate_rep.password.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing FormatTest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(FormatTest { + integer: intermediate_rep.integer.into_iter().next(), + int32: intermediate_rep.int32.into_iter().next(), + int64: intermediate_rep.int64.into_iter().next(), + number: intermediate_rep.number.into_iter().next().ok_or_else(|| "number missing in FormatTest".to_string())?, + float: intermediate_rep.float.into_iter().next(), + double: intermediate_rep.double.into_iter().next(), + string: intermediate_rep.string.into_iter().next(), + byte: intermediate_rep.byte.into_iter().next().ok_or_else(|| "byte missing in FormatTest".to_string())?, + binary: intermediate_rep.binary.into_iter().next(), + date: intermediate_rep.date.into_iter().next().ok_or_else(|| "date missing in FormatTest".to_string())?, + date_time: intermediate_rep.date_time.into_iter().next(), + uuid: intermediate_rep.uuid.into_iter().next(), + password: intermediate_rep.password.into_iter().next().ok_or_else(|| "password missing in FormatTest".to_string())?, + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for FormatTest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into FormatTest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into FormatTest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl FormatTest { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct HasOnlyReadOnly { + #[serde(rename = "bar")] + #[serde(skip_serializing_if="Option::is_none")] + pub bar: Option, + + #[serde(rename = "foo")] + #[serde(skip_serializing_if="Option::is_none")] + pub foo: Option, + +} + + +impl HasOnlyReadOnly { + #[allow(clippy::new_without_default)] + pub fn new() -> HasOnlyReadOnly { + HasOnlyReadOnly { + bar: None, + foo: None, + } + } +} + +/// Converts the HasOnlyReadOnly value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for HasOnlyReadOnly { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.bar.as_ref().map(|bar| { + [ + "bar".to_string(), + bar.to_string(), + ].join(",") + }), + self.foo.as_ref().map(|foo| { + [ + "foo".to_string(), + foo.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a HasOnlyReadOnly value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for HasOnlyReadOnly { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub bar: Vec, + pub foo: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing HasOnlyReadOnly".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "bar" => intermediate_rep.bar.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "foo" => intermediate_rep.foo.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing HasOnlyReadOnly".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(HasOnlyReadOnly { + bar: intermediate_rep.bar.into_iter().next(), + foo: intermediate_rep.foo.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for HasOnlyReadOnly - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into HasOnlyReadOnly - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into HasOnlyReadOnly - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl HasOnlyReadOnly { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct List { + #[serde(rename = "123-list")] + #[serde(skip_serializing_if="Option::is_none")] + pub param_123_list: Option, + +} + + +impl List { + #[allow(clippy::new_without_default)] + pub fn new() -> List { + List { + param_123_list: None, + } + } +} + +/// Converts the List value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for List { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.param_123_list.as_ref().map(|param_123_list| { + [ + "123-list".to_string(), + param_123_list.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a List value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for List { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub param_123_list: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing List".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "123-list" => intermediate_rep.param_123_list.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing List".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(List { + param_123_list: intermediate_rep.param_123_list.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for List - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into List - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into List - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl List { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MapTest { + #[serde(rename = "map_map_of_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub map_map_of_string: Option>>, + + #[serde(rename = "map_map_of_enum")] + #[serde(skip_serializing_if="Option::is_none")] + pub map_map_of_enum: Option>>, + + #[serde(rename = "map_of_enum_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub map_of_enum_string: Option>, + +} + + +impl MapTest { + #[allow(clippy::new_without_default)] + pub fn new() -> MapTest { + MapTest { + map_map_of_string: None, + map_map_of_enum: None, + map_of_enum_string: None, + } + } +} + +/// Converts the MapTest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MapTest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping map map_map_of_string in query parameter serialization + // Skipping map map_map_of_enum in query parameter serialization + // Skipping map map_of_enum_string in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MapTest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MapTest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub map_map_of_string: Vec>>, + pub map_map_of_enum: Vec>>, + pub map_of_enum_string: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MapTest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "map_map_of_string" => return std::result::Result::Err("Parsing a container in this style is not supported in MapTest".to_string()), + "map_map_of_enum" => return std::result::Result::Err("Parsing a container in this style is not supported in MapTest".to_string()), + "map_of_enum_string" => return std::result::Result::Err("Parsing a container in this style is not supported in MapTest".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing MapTest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MapTest { + map_map_of_string: intermediate_rep.map_map_of_string.into_iter().next(), + map_map_of_enum: intermediate_rep.map_map_of_enum.into_iter().next(), + map_of_enum_string: intermediate_rep.map_of_enum_string.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MapTest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MapTest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MapTest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MapTest { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum MapTestMapMapOfEnumValueValue { + #[serde(rename = "UPPER")] + Upper, + #[serde(rename = "lower")] + Lower, +} + +impl std::fmt::Display for MapTestMapMapOfEnumValueValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + MapTestMapMapOfEnumValueValue::Upper => write!(f, "UPPER"), + MapTestMapMapOfEnumValueValue::Lower => write!(f, "lower"), + } + } +} + +impl std::str::FromStr for MapTestMapMapOfEnumValueValue { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "UPPER" => std::result::Result::Ok(MapTestMapMapOfEnumValueValue::Upper), + "lower" => std::result::Result::Ok(MapTestMapMapOfEnumValueValue::Lower), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MapTestMapMapOfEnumValueValue - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MapTestMapMapOfEnumValueValue - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MapTestMapMapOfEnumValueValue - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MapTestMapMapOfEnumValueValue { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct MixedPropertiesAndAdditionalPropertiesClass { + #[serde(rename = "uuid")] + #[serde(skip_serializing_if="Option::is_none")] + pub uuid: Option, + + #[serde(rename = "dateTime")] + #[serde(skip_serializing_if="Option::is_none")] + pub date_time: Option>, + + #[serde(rename = "map")] + #[serde(skip_serializing_if="Option::is_none")] + pub map: Option>, + +} + + +impl MixedPropertiesAndAdditionalPropertiesClass { + #[allow(clippy::new_without_default)] + pub fn new() -> MixedPropertiesAndAdditionalPropertiesClass { + MixedPropertiesAndAdditionalPropertiesClass { + uuid: None, + date_time: None, + map: None, + } + } +} + +/// Converts the MixedPropertiesAndAdditionalPropertiesClass value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for MixedPropertiesAndAdditionalPropertiesClass { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type uuid in query parameter serialization + // Skipping non-primitive type dateTime in query parameter serialization + // Skipping map map in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a MixedPropertiesAndAdditionalPropertiesClass value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for MixedPropertiesAndAdditionalPropertiesClass { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub uuid: Vec, + pub date_time: Vec>, + pub map: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing MixedPropertiesAndAdditionalPropertiesClass".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "uuid" => intermediate_rep.uuid.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "dateTime" => intermediate_rep.date_time.push( as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?), + "map" => return std::result::Result::Err("Parsing a container in this style is not supported in MixedPropertiesAndAdditionalPropertiesClass".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing MixedPropertiesAndAdditionalPropertiesClass".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(MixedPropertiesAndAdditionalPropertiesClass { + uuid: intermediate_rep.uuid.into_iter().next(), + date_time: intermediate_rep.date_time.into_iter().next(), + map: intermediate_rep.map.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for MixedPropertiesAndAdditionalPropertiesClass - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into MixedPropertiesAndAdditionalPropertiesClass - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into MixedPropertiesAndAdditionalPropertiesClass - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl MixedPropertiesAndAdditionalPropertiesClass { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Model for testing model name starting with number +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Name")] +pub struct Model200Response { + #[serde(rename = "name")] + #[serde(skip_serializing_if="Option::is_none")] + pub name: Option, + + #[serde(rename = "class")] + #[serde(skip_serializing_if="Option::is_none")] + pub class: Option, + +} + + +impl Model200Response { + #[allow(clippy::new_without_default)] + pub fn new() -> Model200Response { + Model200Response { + name: None, + class: None, + } + } +} + +/// Converts the Model200Response value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Model200Response { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.name.as_ref().map(|name| { + [ + "name".to_string(), + name.to_string(), + ].join(",") + }), + self.class.as_ref().map(|class| { + [ + "class".to_string(), + class.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Model200Response value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Model200Response { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub name: Vec, + pub class: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Model200Response".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "name" => intermediate_rep.name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "class" => intermediate_rep.class.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Model200Response".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Model200Response { + name: intermediate_rep.name.into_iter().next(), + class: intermediate_rep.class.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Model200Response - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Model200Response - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Model200Response - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Model200Response { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Model for testing model name same as property name +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Name")] +pub struct Name { + #[serde(rename = "name")] + pub name: i32, + + #[serde(rename = "snake_case")] + #[serde(skip_serializing_if="Option::is_none")] + pub snake_case: Option, + + #[serde(rename = "property")] + #[serde(skip_serializing_if="Option::is_none")] + pub property: Option, + + #[serde(rename = "123Number")] + #[serde(skip_serializing_if="Option::is_none")] + pub param_123_number: Option, + +} + + +impl Name { + #[allow(clippy::new_without_default)] + pub fn new(name: i32, ) -> Name { + Name { + name, + snake_case: None, + property: None, + param_123_number: None, + } + } +} + +/// Converts the Name value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Name { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("name".to_string()), + Some(self.name.to_string()), + self.snake_case.as_ref().map(|snake_case| { + [ + "snake_case".to_string(), + snake_case.to_string(), + ].join(",") + }), + self.property.as_ref().map(|property| { + [ + "property".to_string(), + property.to_string(), + ].join(",") + }), + self.param_123_number.as_ref().map(|param_123_number| { + [ + "123Number".to_string(), + param_123_number.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Name value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Name { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub name: Vec, + pub snake_case: Vec, + pub property: Vec, + pub param_123_number: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Name".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "name" => intermediate_rep.name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "snake_case" => intermediate_rep.snake_case.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "property" => intermediate_rep.property.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "123Number" => intermediate_rep.param_123_number.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Name".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Name { + name: intermediate_rep.name.into_iter().next().ok_or_else(|| "name missing in Name".to_string())?, + snake_case: intermediate_rep.snake_case.into_iter().next(), + property: intermediate_rep.property.into_iter().next(), + param_123_number: intermediate_rep.param_123_number.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Name - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Name - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Name - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Name { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct NumberOnly { + #[serde(rename = "JustNumber")] + #[serde(skip_serializing_if="Option::is_none")] + pub just_number: Option, + +} + + +impl NumberOnly { + #[allow(clippy::new_without_default)] + pub fn new() -> NumberOnly { + NumberOnly { + just_number: None, + } + } +} + +/// Converts the NumberOnly value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for NumberOnly { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.just_number.as_ref().map(|just_number| { + [ + "JustNumber".to_string(), + just_number.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a NumberOnly value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for NumberOnly { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub just_number: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing NumberOnly".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "JustNumber" => intermediate_rep.just_number.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing NumberOnly".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(NumberOnly { + just_number: intermediate_rep.just_number.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for NumberOnly - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into NumberOnly - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into NumberOnly - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl NumberOnly { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectContainingObjectWithOnlyAdditionalProperties { + #[serde(rename = "inner")] + #[serde(skip_serializing_if="Option::is_none")] + pub inner: Option, + +} + + +impl ObjectContainingObjectWithOnlyAdditionalProperties { + #[allow(clippy::new_without_default)] + pub fn new() -> ObjectContainingObjectWithOnlyAdditionalProperties { + ObjectContainingObjectWithOnlyAdditionalProperties { + inner: None, + } + } +} + +/// Converts the ObjectContainingObjectWithOnlyAdditionalProperties value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectContainingObjectWithOnlyAdditionalProperties { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type inner in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectContainingObjectWithOnlyAdditionalProperties value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectContainingObjectWithOnlyAdditionalProperties { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub inner: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectContainingObjectWithOnlyAdditionalProperties".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "inner" => intermediate_rep.inner.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectContainingObjectWithOnlyAdditionalProperties".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectContainingObjectWithOnlyAdditionalProperties { + inner: intermediate_rep.inner.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectContainingObjectWithOnlyAdditionalProperties - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectContainingObjectWithOnlyAdditionalProperties - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectContainingObjectWithOnlyAdditionalProperties - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectContainingObjectWithOnlyAdditionalProperties { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectWithOnlyAdditionalProperties(std::collections::HashMap); + +impl std::convert::From> for ObjectWithOnlyAdditionalProperties { + fn from(x: std::collections::HashMap) -> Self { + ObjectWithOnlyAdditionalProperties(x) + } +} + +impl std::convert::From for std::collections::HashMap { + fn from(x: ObjectWithOnlyAdditionalProperties) -> Self { + x.0 + } +} + +impl std::ops::Deref for ObjectWithOnlyAdditionalProperties { + type Target = std::collections::HashMap; + fn deref(&self) -> &std::collections::HashMap { + &self.0 + } +} + +impl std::ops::DerefMut for ObjectWithOnlyAdditionalProperties { + fn deref_mut(&mut self) -> &mut std::collections::HashMap { + &mut self.0 + } +} + +/// Converts the ObjectWithOnlyAdditionalProperties value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for ObjectWithOnlyAdditionalProperties { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectWithOnlyAdditionalProperties value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for ObjectWithOnlyAdditionalProperties { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing ObjectWithOnlyAdditionalProperties is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectWithOnlyAdditionalProperties - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectWithOnlyAdditionalProperties - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectWithOnlyAdditionalProperties - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ObjectWithOnlyAdditionalProperties { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Order")] +pub struct Order { + #[serde(rename = "id")] + #[serde(skip_serializing_if="Option::is_none")] + pub id: Option, + + #[serde(rename = "petId")] + #[serde(skip_serializing_if="Option::is_none")] + pub pet_id: Option, + + #[serde(rename = "quantity")] + #[serde(skip_serializing_if="Option::is_none")] + pub quantity: Option, + + #[serde(rename = "shipDate")] + #[serde(skip_serializing_if="Option::is_none")] + pub ship_date: Option>, + + #[serde(rename = "status")] + #[serde(skip_serializing_if="Option::is_none")] + pub status: Option, + + #[serde(rename = "complete")] + #[serde(skip_serializing_if="Option::is_none")] + pub complete: Option, + +} + + +impl Order { + #[allow(clippy::new_without_default)] + pub fn new() -> Order { + Order { + id: None, + pet_id: None, + quantity: None, + ship_date: None, + status: None, + complete: Some(false), + } + } +} + +/// Converts the Order value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Order { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.id.as_ref().map(|id| { + [ + "id".to_string(), + id.to_string(), + ].join(",") + }), + self.pet_id.as_ref().map(|pet_id| { + [ + "petId".to_string(), + pet_id.to_string(), + ].join(",") + }), + self.quantity.as_ref().map(|quantity| { + [ + "quantity".to_string(), + quantity.to_string(), + ].join(",") + }), + // Skipping non-primitive type shipDate in query parameter serialization + // Skipping non-primitive type status in query parameter serialization + self.complete.as_ref().map(|complete| { + [ + "complete".to_string(), + complete.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Order value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Order { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub pet_id: Vec, + pub quantity: Vec, + pub ship_date: Vec>, + pub status: Vec, + pub complete: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Order".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "petId" => intermediate_rep.pet_id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "quantity" => intermediate_rep.quantity.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "shipDate" => intermediate_rep.ship_date.push( as std::str::FromStr>::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "status" => intermediate_rep.status.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "complete" => intermediate_rep.complete.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Order".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Order { + id: intermediate_rep.id.into_iter().next(), + pet_id: intermediate_rep.pet_id.into_iter().next(), + quantity: intermediate_rep.quantity.into_iter().next(), + ship_date: intermediate_rep.ship_date.into_iter().next(), + status: intermediate_rep.status.into_iter().next(), + complete: intermediate_rep.complete.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Order - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Order - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Order - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Order { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Order Status +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum OrderStatus { + #[serde(rename = "placed")] + Placed, + #[serde(rename = "approved")] + Approved, + #[serde(rename = "delivered")] + Delivered, +} + +impl std::fmt::Display for OrderStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + OrderStatus::Placed => write!(f, "placed"), + OrderStatus::Approved => write!(f, "approved"), + OrderStatus::Delivered => write!(f, "delivered"), + } + } +} + +impl std::str::FromStr for OrderStatus { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "placed" => std::result::Result::Ok(OrderStatus::Placed), + "approved" => std::result::Result::Ok(OrderStatus::Approved), + "delivered" => std::result::Result::Ok(OrderStatus::Delivered), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OrderStatus - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OrderStatus - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OrderStatus - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OrderStatus { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OuterBoolean(bool); + +impl std::convert::From for OuterBoolean { + fn from(x: bool) -> Self { + OuterBoolean(x) + } +} + +impl std::convert::From for bool { + fn from(x: OuterBoolean) -> Self { + x.0 + } +} + +impl std::ops::Deref for OuterBoolean { + type Target = bool; + fn deref(&self) -> &bool { + &self.0 + } +} + +impl std::ops::DerefMut for OuterBoolean { + fn deref_mut(&mut self) -> &mut bool { + &mut self.0 + } +} + +/// Converts the OuterBoolean value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for OuterBoolean { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OuterBoolean value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for OuterBoolean { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(OuterBoolean(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OuterBoolean: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OuterBoolean - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OuterBoolean - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OuterBoolean - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OuterBoolean { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OuterComposite { + #[serde(rename = "my_number")] + #[serde(skip_serializing_if="Option::is_none")] + pub my_number: Option, + + #[serde(rename = "my_string")] + #[serde(skip_serializing_if="Option::is_none")] + pub my_string: Option, + + #[serde(rename = "my_boolean")] + #[serde(skip_serializing_if="Option::is_none")] + pub my_boolean: Option, + +} + + +impl OuterComposite { + #[allow(clippy::new_without_default)] + pub fn new() -> OuterComposite { + OuterComposite { + my_number: None, + my_string: None, + my_boolean: None, + } + } +} + +/// Converts the OuterComposite value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for OuterComposite { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.my_number.as_ref().map(|my_number| { + [ + "my_number".to_string(), + my_number.to_string(), + ].join(",") + }), + self.my_string.as_ref().map(|my_string| { + [ + "my_string".to_string(), + my_string.to_string(), + ].join(",") + }), + self.my_boolean.as_ref().map(|my_boolean| { + [ + "my_boolean".to_string(), + my_boolean.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OuterComposite value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for OuterComposite { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub my_number: Vec, + pub my_string: Vec, + pub my_boolean: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing OuterComposite".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "my_number" => intermediate_rep.my_number.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "my_string" => intermediate_rep.my_string.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "my_boolean" => intermediate_rep.my_boolean.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing OuterComposite".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(OuterComposite { + my_number: intermediate_rep.my_number.into_iter().next(), + my_string: intermediate_rep.my_string.into_iter().next(), + my_boolean: intermediate_rep.my_boolean.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OuterComposite - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OuterComposite - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OuterComposite - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OuterComposite { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum OuterEnum { + #[serde(rename = "placed")] + Placed, + #[serde(rename = "approved")] + Approved, + #[serde(rename = "delivered")] + Delivered, +} + +impl std::fmt::Display for OuterEnum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + OuterEnum::Placed => write!(f, "placed"), + OuterEnum::Approved => write!(f, "approved"), + OuterEnum::Delivered => write!(f, "delivered"), + } + } +} + +impl std::str::FromStr for OuterEnum { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "placed" => std::result::Result::Ok(OuterEnum::Placed), + "approved" => std::result::Result::Ok(OuterEnum::Approved), + "delivered" => std::result::Result::Ok(OuterEnum::Delivered), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OuterEnum - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OuterEnum - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OuterEnum - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OuterEnum { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OuterNumber(f64); + +impl std::convert::From for OuterNumber { + fn from(x: f64) -> Self { + OuterNumber(x) + } +} + +impl std::convert::From for f64 { + fn from(x: OuterNumber) -> Self { + x.0 + } +} + +impl std::ops::Deref for OuterNumber { + type Target = f64; + fn deref(&self) -> &f64 { + &self.0 + } +} + +impl std::ops::DerefMut for OuterNumber { + fn deref_mut(&mut self) -> &mut f64 { + &mut self.0 + } +} + +/// Converts the OuterNumber value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for OuterNumber { + fn to_string(&self) -> String { + self.0.to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a OuterNumber value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for OuterNumber { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match std::str::FromStr::from_str(s) { + std::result::Result::Ok(r) => std::result::Result::Ok(OuterNumber(r)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OuterNumber: {e:?}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OuterNumber - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OuterNumber - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OuterNumber - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OuterNumber { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, PartialOrd, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct OuterString(String); + +impl std::convert::From for OuterString { + fn from(x: String) -> Self { + OuterString(x) + } +} + +impl std::convert::From for String { + fn from(x: OuterString) -> Self { + x.0 + } +} + +impl std::ops::Deref for OuterString { + type Target = String; + fn deref(&self) -> &String { + &self.0 + } +} + +impl std::ops::DerefMut for OuterString { + fn deref_mut(&mut self) -> &mut String { + &mut self.0 + } +} + +impl std::string::ToString for OuterString { + fn to_string(&self) -> String { + self.0.clone() + } +} + +impl std::str::FromStr for OuterString { + type Err = ::std::convert::Infallible; + fn from_str(x: &str) -> std::result::Result { + std::result::Result::Ok(OuterString(x.to_owned())) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for OuterString - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into OuterString - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into OuterString - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl OuterString { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Pet")] +pub struct Pet { + #[serde(rename = "id")] + #[serde(skip_serializing_if="Option::is_none")] + pub id: Option, + + #[serde(rename = "category")] + #[serde(skip_serializing_if="Option::is_none")] + pub category: Option, + + #[serde(rename = "name")] + pub name: String, + + #[serde(rename = "photoUrls")] + pub photo_urls: Vec, + + #[serde(rename = "tags")] + #[serde(skip_serializing_if="Option::is_none")] + pub tags: Option>, + + #[serde(rename = "status")] + #[serde(skip_serializing_if="Option::is_none")] + pub status: Option, + +} + + +impl Pet { + #[allow(clippy::new_without_default)] + pub fn new(name: String, photo_urls: Vec, ) -> Pet { + Pet { + id: None, + category: None, + name, + photo_urls, + tags: None, + status: None, + } + } +} + +/// Converts the Pet value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Pet { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.id.as_ref().map(|id| { + [ + "id".to_string(), + id.to_string(), + ].join(",") + }), + // Skipping non-primitive type category in query parameter serialization + Some("name".to_string()), + Some(self.name.to_string()), + Some("photoUrls".to_string()), + Some(self.photo_urls.iter().map(|x| x.to_string()).collect::>().join(",")), + // Skipping non-primitive type tags in query parameter serialization + // Skipping non-primitive type status in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Pet value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Pet { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub category: Vec, + pub name: Vec, + pub photo_urls: Vec>, + pub tags: Vec>, + pub status: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Pet".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "category" => intermediate_rep.category.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "name" => intermediate_rep.name.push(::from_str(val).map_err(|x| x.to_string())?), + "photoUrls" => return std::result::Result::Err("Parsing a container in this style is not supported in Pet".to_string()), + "tags" => return std::result::Result::Err("Parsing a container in this style is not supported in Pet".to_string()), + #[allow(clippy::redundant_clone)] + "status" => intermediate_rep.status.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Pet".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Pet { + id: intermediate_rep.id.into_iter().next(), + category: intermediate_rep.category.into_iter().next(), + name: intermediate_rep.name.into_iter().next().ok_or_else(|| "name missing in Pet".to_string())?, + photo_urls: intermediate_rep.photo_urls.into_iter().next().ok_or_else(|| "photoUrls missing in Pet".to_string())?, + tags: intermediate_rep.tags.into_iter().next(), + status: intermediate_rep.status.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Pet - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Pet - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Pet - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Pet { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// pet status in the store +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum PetStatus { + #[serde(rename = "available")] + Available, + #[serde(rename = "pending")] + Pending, + #[serde(rename = "sold")] + Sold, +} + +impl std::fmt::Display for PetStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + PetStatus::Available => write!(f, "available"), + PetStatus::Pending => write!(f, "pending"), + PetStatus::Sold => write!(f, "sold"), + } + } +} + +impl std::str::FromStr for PetStatus { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "available" => std::result::Result::Ok(PetStatus::Available), + "pending" => std::result::Result::Ok(PetStatus::Pending), + "sold" => std::result::Result::Ok(PetStatus::Sold), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for PetStatus - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into PetStatus - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into PetStatus - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl PetStatus { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ReadOnlyFirst { + #[serde(rename = "bar")] + #[serde(skip_serializing_if="Option::is_none")] + pub bar: Option, + + #[serde(rename = "baz")] + #[serde(skip_serializing_if="Option::is_none")] + pub baz: Option, + +} + + +impl ReadOnlyFirst { + #[allow(clippy::new_without_default)] + pub fn new() -> ReadOnlyFirst { + ReadOnlyFirst { + bar: None, + baz: None, + } + } +} + +/// Converts the ReadOnlyFirst value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ReadOnlyFirst { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.bar.as_ref().map(|bar| { + [ + "bar".to_string(), + bar.to_string(), + ].join(",") + }), + self.baz.as_ref().map(|baz| { + [ + "baz".to_string(), + baz.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ReadOnlyFirst value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ReadOnlyFirst { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub bar: Vec, + pub baz: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ReadOnlyFirst".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "bar" => intermediate_rep.bar.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "baz" => intermediate_rep.baz.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ReadOnlyFirst".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ReadOnlyFirst { + bar: intermediate_rep.bar.into_iter().next(), + baz: intermediate_rep.baz.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ReadOnlyFirst - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ReadOnlyFirst - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ReadOnlyFirst - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl ReadOnlyFirst { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Model for testing reserved words +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Return")] +pub struct Return { + #[serde(rename = "return")] + #[serde(skip_serializing_if="Option::is_none")] + pub r#return: Option, + +} + + +impl Return { + #[allow(clippy::new_without_default)] + pub fn new() -> Return { + Return { + r#return: None, + } + } +} + +/// Converts the Return value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Return { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.r#return.as_ref().map(|r#return| { + [ + "return".to_string(), + r#return.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Return value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Return { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub r#return: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Return".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "return" => intermediate_rep.r#return.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Return".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Return { + r#return: intermediate_rep.r#return.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Return - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Return - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Return - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Return { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "Tag")] +pub struct Tag { + #[serde(rename = "id")] + #[serde(skip_serializing_if="Option::is_none")] + pub id: Option, + + #[serde(rename = "name")] + #[serde(skip_serializing_if="Option::is_none")] + pub name: Option, + +} + + +impl Tag { + #[allow(clippy::new_without_default)] + pub fn new() -> Tag { + Tag { + id: None, + name: None, + } + } +} + +/// Converts the Tag value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for Tag { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.id.as_ref().map(|id| { + [ + "id".to_string(), + id.to_string(), + ].join(",") + }), + self.name.as_ref().map(|name| { + [ + "name".to_string(), + name.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a Tag value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for Tag { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub name: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing Tag".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "name" => intermediate_rep.name.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing Tag".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(Tag { + id: intermediate_rep.id.into_iter().next(), + name: intermediate_rep.name.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for Tag - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into Tag - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into Tag - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl Tag { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum TestEnumParametersEnumHeaderStringArrayParameterInner { + #[serde(rename = ">")] + GreaterThan, + #[serde(rename = "$")] + Dollar, +} + +impl std::fmt::Display for TestEnumParametersEnumHeaderStringArrayParameterInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + TestEnumParametersEnumHeaderStringArrayParameterInner::GreaterThan => write!(f, ">"), + TestEnumParametersEnumHeaderStringArrayParameterInner::Dollar => write!(f, "$"), + } + } +} + +impl std::str::FromStr for TestEnumParametersEnumHeaderStringArrayParameterInner { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + ">" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringArrayParameterInner::GreaterThan), + "$" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringArrayParameterInner::Dollar), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for TestEnumParametersEnumHeaderStringArrayParameterInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl TestEnumParametersEnumHeaderStringArrayParameterInner { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum TestEnumParametersEnumHeaderStringParameter { + #[serde(rename = "_abc")] + Abc, + #[serde(rename = "-efg")] + Efg, + #[serde(rename = "(xyz)")] + LeftParenthesisXyzRightParenthesis, +} + +impl std::fmt::Display for TestEnumParametersEnumHeaderStringParameter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + TestEnumParametersEnumHeaderStringParameter::Abc => write!(f, "_abc"), + TestEnumParametersEnumHeaderStringParameter::Efg => write!(f, "-efg"), + TestEnumParametersEnumHeaderStringParameter::LeftParenthesisXyzRightParenthesis => write!(f, "(xyz)"), + } + } +} + +impl std::str::FromStr for TestEnumParametersEnumHeaderStringParameter { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "_abc" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::Abc), + "-efg" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::Efg), + "(xyz)" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::LeftParenthesisXyzRightParenthesis), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for TestEnumParametersEnumHeaderStringParameter - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into TestEnumParametersEnumHeaderStringParameter - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumHeaderStringParameter - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl TestEnumParametersEnumHeaderStringParameter { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum TestEnumParametersEnumQueryDoubleParameter { + #[serde(rename = "1.1")] + Variant11, + #[serde(rename = "-1.2")] + Variant12, +} + +impl std::fmt::Display for TestEnumParametersEnumQueryDoubleParameter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + TestEnumParametersEnumQueryDoubleParameter::Variant11 => write!(f, "1.1"), + TestEnumParametersEnumQueryDoubleParameter::Variant12 => write!(f, "-1.2"), + } + } +} + +impl std::str::FromStr for TestEnumParametersEnumQueryDoubleParameter { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "1.1" => std::result::Result::Ok(TestEnumParametersEnumQueryDoubleParameter::Variant11), + "-1.2" => std::result::Result::Ok(TestEnumParametersEnumQueryDoubleParameter::Variant12), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for TestEnumParametersEnumQueryDoubleParameter - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into TestEnumParametersEnumQueryDoubleParameter - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumQueryDoubleParameter - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl TestEnumParametersEnumQueryDoubleParameter { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum TestEnumParametersEnumQueryIntegerParameter { + #[serde(rename = "1")] + Variant1, + #[serde(rename = "-2")] + Variant2, +} + +impl std::fmt::Display for TestEnumParametersEnumQueryIntegerParameter { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + TestEnumParametersEnumQueryIntegerParameter::Variant1 => write!(f, "1"), + TestEnumParametersEnumQueryIntegerParameter::Variant2 => write!(f, "-2"), + } + } +} + +impl std::str::FromStr for TestEnumParametersEnumQueryIntegerParameter { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "1" => std::result::Result::Ok(TestEnumParametersEnumQueryIntegerParameter::Variant1), + "-2" => std::result::Result::Ok(TestEnumParametersEnumQueryIntegerParameter::Variant2), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for TestEnumParametersEnumQueryIntegerParameter - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into TestEnumParametersEnumQueryIntegerParameter - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumQueryIntegerParameter - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl TestEnumParametersEnumQueryIntegerParameter { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +/// Form parameter enum test (string) +/// Enumeration of values. +/// Since this enum's variants do not hold data, we can easily define them as `#[repr(C)]` +/// which helps with FFI. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, Hash)] +#[cfg_attr(feature = "conversion", derive(frunk_enum_derive::LabelledGenericEnum))] +pub enum TestEnumParametersRequestEnumFormString { + #[serde(rename = "_abc")] + Abc, + #[serde(rename = "-efg")] + Efg, + #[serde(rename = "(xyz)")] + LeftParenthesisXyzRightParenthesis, +} + +impl std::fmt::Display for TestEnumParametersRequestEnumFormString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + TestEnumParametersRequestEnumFormString::Abc => write!(f, "_abc"), + TestEnumParametersRequestEnumFormString::Efg => write!(f, "-efg"), + TestEnumParametersRequestEnumFormString::LeftParenthesisXyzRightParenthesis => write!(f, "(xyz)"), + } + } +} + +impl std::str::FromStr for TestEnumParametersRequestEnumFormString { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + match s { + "_abc" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::Abc), + "-efg" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::Efg), + "(xyz)" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::LeftParenthesisXyzRightParenthesis), + _ => std::result::Result::Err(format!("Value not valid: {s}")), + } + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for TestEnumParametersRequestEnumFormString - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into TestEnumParametersRequestEnumFormString - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersRequestEnumFormString - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl TestEnumParametersRequestEnumFormString { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +#[serde(rename = "User")] +pub struct User { + #[serde(rename = "id")] + #[serde(skip_serializing_if="Option::is_none")] + pub id: Option, + + #[serde(rename = "username")] + #[serde(skip_serializing_if="Option::is_none")] + pub username: Option, + + #[serde(rename = "firstName")] + #[serde(skip_serializing_if="Option::is_none")] + pub first_name: Option, + + #[serde(rename = "lastName")] + #[serde(skip_serializing_if="Option::is_none")] + pub last_name: Option, + + #[serde(rename = "email")] + #[serde(skip_serializing_if="Option::is_none")] + pub email: Option, + + #[serde(rename = "password")] + #[serde(skip_serializing_if="Option::is_none")] + pub password: Option, + + #[serde(rename = "phone")] + #[serde(skip_serializing_if="Option::is_none")] + pub phone: Option, + + /// User Status + #[serde(rename = "userStatus")] + #[serde(skip_serializing_if="Option::is_none")] + pub user_status: Option, + +} + + +impl User { + #[allow(clippy::new_without_default)] + pub fn new() -> User { + User { + id: None, + username: None, + first_name: None, + last_name: None, + email: None, + password: None, + phone: None, + user_status: None, + } + } +} + +/// Converts the User value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for User { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.id.as_ref().map(|id| { + [ + "id".to_string(), + id.to_string(), + ].join(",") + }), + self.username.as_ref().map(|username| { + [ + "username".to_string(), + username.to_string(), + ].join(",") + }), + self.first_name.as_ref().map(|first_name| { + [ + "firstName".to_string(), + first_name.to_string(), + ].join(",") + }), + self.last_name.as_ref().map(|last_name| { + [ + "lastName".to_string(), + last_name.to_string(), + ].join(",") + }), + self.email.as_ref().map(|email| { + [ + "email".to_string(), + email.to_string(), + ].join(",") + }), + self.password.as_ref().map(|password| { + [ + "password".to_string(), + password.to_string(), + ].join(",") + }), + self.phone.as_ref().map(|phone| { + [ + "phone".to_string(), + phone.to_string(), + ].join(",") + }), + self.user_status.as_ref().map(|user_status| { + [ + "userStatus".to_string(), + user_status.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a User value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for User { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub username: Vec, + pub first_name: Vec, + pub last_name: Vec, + pub email: Vec, + pub password: Vec, + pub phone: Vec, + pub user_status: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing User".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "username" => intermediate_rep.username.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "firstName" => intermediate_rep.first_name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "lastName" => intermediate_rep.last_name.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "email" => intermediate_rep.email.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "password" => intermediate_rep.password.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "phone" => intermediate_rep.phone.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "userStatus" => intermediate_rep.user_status.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing User".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(User { + id: intermediate_rep.id.into_iter().next(), + username: intermediate_rep.username.into_iter().next(), + first_name: intermediate_rep.first_name.into_iter().next(), + last_name: intermediate_rep.last_name.into_iter().next(), + email: intermediate_rep.email.into_iter().next(), + password: intermediate_rep.password.into_iter().next(), + phone: intermediate_rep.phone.into_iter().next(), + user_status: intermediate_rep.user_status.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for User - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into User - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into User - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +impl User { + /// Helper function to allow us to convert this model to an XML string. + /// Will panic if serialisation fails. + #[allow(dead_code)] + pub(crate) fn as_xml(&self) -> String { + serde_xml_rs::to_string(&self).expect("impossible to fail to serialize") + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs new file mode 100644 index 000000000000..a6c6aa055f14 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs @@ -0,0 +1,3323 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; +use multipart::server::Multipart; +use multipart::server::save::{PartialReason, SaveResult}; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + TestSpecialTagsResponse, + Call123exampleResponse, + FakeOuterBooleanSerializeResponse, + FakeOuterCompositeSerializeResponse, + FakeOuterNumberSerializeResponse, + FakeOuterStringSerializeResponse, + FakeResponseWithNumericalDescriptionResponse, + TestBodyWithQueryParamsResponse, + TestClientModelResponse, + TestEndpointParametersResponse, + TestEnumParametersResponse, + TestInlineAdditionalPropertiesResponse, + TestJsonFormDataResponse, + HyphenParamResponse, + TestClassnameResponse, + AddPetResponse, + FindPetsByStatusResponse, + FindPetsByTagsResponse, + UpdatePetResponse, + DeletePetResponse, + GetPetByIdResponse, + UpdatePetWithFormResponse, + UploadFileResponse, + GetInventoryResponse, + PlaceOrderResponse, + DeleteOrderResponse, + GetOrderByIdResponse, + CreateUserResponse, + CreateUsersWithArrayInputResponse, + CreateUsersWithListInputResponse, + LoginUserResponse, + LogoutUserResponse, + DeleteUserResponse, + GetUserByNameResponse, + UpdateUserResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/v2/another-fake/dummy$", + r"^/v2/fake$", + r"^/v2/fake/body-with-query-params$", + r"^/v2/fake/hyphenParam/(?P[^/?#]*)$", + r"^/v2/fake/inline-additionalProperties$", + r"^/v2/fake/jsonFormData$", + r"^/v2/fake/operation-with-numeric-id$", + r"^/v2/fake/outer/boolean$", + r"^/v2/fake/outer/composite$", + r"^/v2/fake/outer/number$", + r"^/v2/fake/outer/string$", + r"^/v2/fake/response-with-numerical-description$", + r"^/v2/fake_classname_test$", + r"^/v2/pet$", + r"^/v2/pet/findByStatus$", + r"^/v2/pet/findByTags$", + r"^/v2/pet/(?P[^/?#]*)$", + r"^/v2/pet/(?P[^/?#]*)/uploadImage$", + r"^/v2/store/inventory$", + r"^/v2/store/order$", + r"^/v2/store/order/(?P[^/?#]*)$", + r"^/v2/user$", + r"^/v2/user/createWithArray$", + r"^/v2/user/createWithList$", + r"^/v2/user/login$", + r"^/v2/user/logout$", + r"^/v2/user/(?P[^/?#]*)$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_ANOTHER_FAKE_DUMMY: usize = 0; + pub(crate) static ID_FAKE: usize = 1; + pub(crate) static ID_FAKE_BODY_WITH_QUERY_PARAMS: usize = 2; + pub(crate) static ID_FAKE_HYPHENPARAM_HYPHEN_PARAM: usize = 3; + lazy_static! { + pub static ref REGEX_FAKE_HYPHENPARAM_HYPHEN_PARAM: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/v2/fake/hyphenParam/(?P[^/?#]*)$") + .expect("Unable to create regex for FAKE_HYPHENPARAM_HYPHEN_PARAM"); + } + pub(crate) static ID_FAKE_INLINE_ADDITIONALPROPERTIES: usize = 4; + pub(crate) static ID_FAKE_JSONFORMDATA: usize = 5; + pub(crate) static ID_FAKE_OPERATION_WITH_NUMERIC_ID: usize = 6; + pub(crate) static ID_FAKE_OUTER_BOOLEAN: usize = 7; + pub(crate) static ID_FAKE_OUTER_COMPOSITE: usize = 8; + pub(crate) static ID_FAKE_OUTER_NUMBER: usize = 9; + pub(crate) static ID_FAKE_OUTER_STRING: usize = 10; + pub(crate) static ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION: usize = 11; + pub(crate) static ID_FAKE_CLASSNAME_TEST: usize = 12; + pub(crate) static ID_PET: usize = 13; + pub(crate) static ID_PET_FINDBYSTATUS: usize = 14; + pub(crate) static ID_PET_FINDBYTAGS: usize = 15; + pub(crate) static ID_PET_PETID: usize = 16; + lazy_static! { + pub static ref REGEX_PET_PETID: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/v2/pet/(?P[^/?#]*)$") + .expect("Unable to create regex for PET_PETID"); + } + pub(crate) static ID_PET_PETID_UPLOADIMAGE: usize = 17; + lazy_static! { + pub static ref REGEX_PET_PETID_UPLOADIMAGE: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/v2/pet/(?P[^/?#]*)/uploadImage$") + .expect("Unable to create regex for PET_PETID_UPLOADIMAGE"); + } + pub(crate) static ID_STORE_INVENTORY: usize = 18; + pub(crate) static ID_STORE_ORDER: usize = 19; + pub(crate) static ID_STORE_ORDER_ORDER_ID: usize = 20; + lazy_static! { + pub static ref REGEX_STORE_ORDER_ORDER_ID: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/v2/store/order/(?P[^/?#]*)$") + .expect("Unable to create regex for STORE_ORDER_ORDER_ID"); + } + pub(crate) static ID_USER: usize = 21; + pub(crate) static ID_USER_CREATEWITHARRAY: usize = 22; + pub(crate) static ID_USER_CREATEWITHLIST: usize = 23; + pub(crate) static ID_USER_LOGIN: usize = 24; + pub(crate) static ID_USER_LOGOUT: usize = 25; + pub(crate) static ID_USER_USERNAME: usize = 26; + lazy_static! { + pub static ref REGEX_USER_USERNAME: regex::Regex = + #[allow(clippy::invalid_regex)] + regex::Regex::new(r"^/v2/user/(?P[^/?#]*)$") + .expect("Unable to create regex for USER_USERNAME"); + } +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + multipart_form_size_limit: Option, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData + } + } + + /// Configure size limit when inspecting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()) + .multipart_form_size_limit(self.multipart_form_size_limit); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + multipart_form_size_limit: Option, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData + } + } + + /// Configure size limit when extracting a multipart/form body. + /// + /// Default is 8 MiB. + /// + /// Set to None for no size limit, which presents a Denial of Service attack risk. + pub fn multipart_form_size_limit(mut self, multipart_form_size_limit: Option) -> Self { + self.multipart_form_size_limit = multipart_form_size_limit; + self + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + multipart_form_size_limit: Option, + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // TestSpecialTags - PATCH /another-fake/dummy + hyper::Method::PATCH if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.test_special_tags( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + TestSpecialTagsResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // Call123example - GET /fake/operation-with-numeric-id + hyper::Method::GET if path.matched(paths::ID_FAKE_OPERATION_WITH_NUMERIC_ID) => { + let result = api_impl.call123example( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + Call123exampleResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // FakeOuterBooleanSerialize - POST /fake/outer/boolean + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_BOOLEAN) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.fake_outer_boolean_serialize( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + FakeOuterBooleanSerializeResponse::OutputBoolean + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FakeOuterCompositeSerialize - POST /fake/outer/composite + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_COMPOSITE) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.fake_outer_composite_serialize( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + FakeOuterCompositeSerializeResponse::OutputComposite + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FakeOuterNumberSerialize - POST /fake/outer/number + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_NUMBER) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.fake_outer_number_serialize( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + FakeOuterNumberSerializeResponse::OutputNumber + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FakeOuterStringSerialize - POST /fake/outer/string + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_STRING) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(_) => None, + } + } else { + None + }; + + + let result = api_impl.fake_outer_string_serialize( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + FakeOuterStringSerializeResponse::OutputString + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FakeResponseWithNumericalDescription - GET /fake/response-with-numerical-description + hyper::Method::GET if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => { + let result = api_impl.fake_response_with_numerical_description( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + FakeResponseWithNumericalDescriptionResponse::Status200 + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // TestBodyWithQueryParams - PUT /fake/body-with-query-params + hyper::Method::PUT if path.matched(paths::ID_FAKE_BODY_WITH_QUERY_PARAMS) => { + // 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::>(); + let param_query = query_params.iter().filter(|e| e.0 == "query").map(|e| e.1.clone()) + .next(); + let param_query = match param_query { + Some(param_query) => { + let param_query = + ::from_str + (¶m_query); + match param_query { + Ok(param_query) => Some(param_query), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter query - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter query")), + } + }, + None => None, + }; + let param_query = match param_query { + Some(param_query) => param_query, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter query")) + .expect("Unable to create Bad Request response for missing query parameter query")), + }; + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.test_body_with_query_params( + param_query, + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + TestBodyWithQueryParamsResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // TestClientModel - PATCH /fake + hyper::Method::PATCH if path.matched(paths::ID_FAKE) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.test_client_model( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + TestClientModelResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // TestEndpointParameters - POST /fake + hyper::Method::POST if path.matched(paths::ID_FAKE) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + } + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + // Form parameters + let param_integer = + Some(56); + let param_int32 = + Some(56); + let param_int64 = + Some(789); + let param_number = + 8.14; + let param_float = + Some(3.4); + let param_double = + 1.2; + let param_string = + Some("string_example".to_string()); + let param_pattern_without_delimiter = + "pattern_without_delimiter_example".to_string(); + let param_byte = + swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")); + let param_binary = + Some(swagger::ByteArray(Vec::from("BINARY_DATA_HERE"))); + let param_date = + None; + let param_date_time = + None; + let param_password = + Some("password_example".to_string()); + let param_callback = + Some("callback_example".to_string()); + + + let result = api_impl.test_endpoint_parameters( + param_number, + param_double, + param_pattern_without_delimiter, + param_byte, + param_integer, + param_int32, + param_int64, + param_float, + param_string, + param_binary, + param_date, + param_date_time, + param_password, + param_callback, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + TestEndpointParametersResponse::InvalidUsernameSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + TestEndpointParametersResponse::UserNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // TestEnumParameters - GET /fake + hyper::Method::GET if path.matched(paths::ID_FAKE) => { + // Header parameters + let param_enum_header_string_array = headers.get(HeaderName::from_static("enum_header_string_array")); + + let param_enum_header_string_array = match param_enum_header_string_array { + Some(v) => match header::IntoHeaderValue::>::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header enum_header_string_array - {err}"))) + .expect("Unable to create Bad Request response for invalid header enum_header_string_array")); + + }, + }, + None => { + None + } + }; + let param_enum_header_string = headers.get(HeaderName::from_static("enum_header_string")); + + let param_enum_header_string = match param_enum_header_string { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header enum_header_string - {err}"))) + .expect("Unable to create Bad Request response for invalid header enum_header_string")); + + }, + }, + None => { + None + } + }; + + // 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::>(); + let param_enum_query_string_array = query_params.iter().filter(|e| e.0 == "enum_query_string_array").map(|e| e.1.clone()) + .filter_map(|param_enum_query_string_array| param_enum_query_string_array.parse().ok()) + .collect::>(); + let param_enum_query_string_array = if !param_enum_query_string_array.is_empty() { + Some(param_enum_query_string_array) + } else { + None + }; + let param_enum_query_string = query_params.iter().filter(|e| e.0 == "enum_query_string").map(|e| e.1.clone()) + .next(); + let param_enum_query_string = match param_enum_query_string { + Some(param_enum_query_string) => { + let param_enum_query_string = + ::from_str + (¶m_enum_query_string); + match param_enum_query_string { + Ok(param_enum_query_string) => Some(param_enum_query_string), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter enum_query_string - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter enum_query_string")), + } + }, + None => None, + }; + let param_enum_query_integer = query_params.iter().filter(|e| e.0 == "enum_query_integer").map(|e| e.1.clone()) + .next(); + let param_enum_query_integer = match param_enum_query_integer { + Some(param_enum_query_integer) => { + let param_enum_query_integer = + ::from_str + (¶m_enum_query_integer); + match param_enum_query_integer { + Ok(param_enum_query_integer) => Some(param_enum_query_integer), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter enum_query_integer - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter enum_query_integer")), + } + }, + None => None, + }; + let param_enum_query_double = query_params.iter().filter(|e| e.0 == "enum_query_double").map(|e| e.1.clone()) + .next(); + let param_enum_query_double = match param_enum_query_double { + Some(param_enum_query_double) => { + let param_enum_query_double = + ::from_str + (¶m_enum_query_double); + match param_enum_query_double { + Ok(param_enum_query_double) => Some(param_enum_query_double), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter enum_query_double - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter enum_query_double")), + } + }, + None => None, + }; + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + // Form parameters + let param_enum_form_string = + None; + + + let result = api_impl.test_enum_parameters( + param_enum_header_string_array.as_ref(), + param_enum_header_string, + param_enum_query_string_array.as_ref(), + param_enum_query_string, + param_enum_query_integer, + param_enum_query_double, + param_enum_form_string, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + TestEnumParametersResponse::InvalidRequest + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + TestEnumParametersResponse::NotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // TestInlineAdditionalProperties - POST /fake/inline-additionalProperties + hyper::Method::POST if path.matched(paths::ID_FAKE_INLINE_ADDITIONALPROPERTIES) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_param: Option> = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_param) => param_param, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter param - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter param due to schema")), + } + } else { + None + }; + let param_param = match param_param { + Some(param_param) => param_param, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter param")) + .expect("Unable to create Bad Request response for missing body parameter param")), + }; + + + let result = api_impl.test_inline_additional_properties( + param_param, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + TestInlineAdditionalPropertiesResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // TestJsonFormData - GET /fake/jsonFormData + hyper::Method::GET if path.matched(paths::ID_FAKE_JSONFORMDATA) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + // Form parameters + let param_param = + "param_example".to_string(); + let param_param2 = + "param2_example".to_string(); + + + let result = api_impl.test_json_form_data( + param_param, + param_param2, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + TestJsonFormDataResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // HyphenParam - GET /fake/hyphenParam/{hyphen-param} + hyper::Method::GET if path.matched(paths::ID_FAKE_HYPHENPARAM_HYPHEN_PARAM) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_FAKE_HYPHENPARAM_HYPHEN_PARAM + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE FAKE_HYPHENPARAM_HYPHEN_PARAM in set but failed match against \"{}\"", path, paths::REGEX_FAKE_HYPHENPARAM_HYPHEN_PARAM.as_str()) + ); + + let param_hyphen_param = match percent_encoding::percent_decode(path_params["hyphen-param"].as_bytes()).decode_utf8() { + Ok(param_hyphen_param) => match param_hyphen_param.parse::() { + Ok(param_hyphen_param) => param_hyphen_param, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter hyphen-param: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["hyphen-param"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.hyphen_param( + param_hyphen_param, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + HyphenParamResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // TestClassname - PATCH /fake_classname_test + hyper::Method::PATCH if path.matched(paths::ID_FAKE_CLASSNAME_TEST) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + } + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.test_classname( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + TestClassnameResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // AddPet - POST /pet + hyper::Method::POST if path.matched(paths::ID_PET) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.add_pet( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + AddPetResponse::InvalidInput + => { + *response.status_mut() = StatusCode::from_u16(405).expect("Unable to turn 405 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FindPetsByStatus - GET /pet/findByStatus + hyper::Method::GET if path.matched(paths::ID_PET_FINDBYSTATUS) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // 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::>(); + let param_status = query_params.iter().filter(|e| e.0 == "status").map(|e| e.1.clone()) + .filter_map(|param_status| param_status.parse().ok()) + .collect::>(); + + let result = api_impl.find_pets_by_status( + param_status.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + FindPetsByStatusResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + FindPetsByStatusResponse::InvalidStatusValue + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // FindPetsByTags - GET /pet/findByTags + hyper::Method::GET if path.matched(paths::ID_PET_FINDBYTAGS) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // 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::>(); + let param_tags = query_params.iter().filter(|e| e.0 == "tags").map(|e| e.1.clone()) + .filter_map(|param_tags| param_tags.parse().ok()) + .collect::>(); + + let result = api_impl.find_pets_by_tags( + param_tags.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + FindPetsByTagsResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + FindPetsByTagsResponse::InvalidTagValue + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // UpdatePet - PUT /pet + hyper::Method::PUT if path.matched(paths::ID_PET) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.update_pet( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + UpdatePetResponse::InvalidIDSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + UpdatePetResponse::PetNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + UpdatePetResponse::ValidationException + => { + *response.status_mut() = StatusCode::from_u16(405).expect("Unable to turn 405 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // DeletePet - DELETE /pet/{petId} + hyper::Method::DELETE if path.matched(paths::ID_PET_PETID) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_PET_PETID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter petId: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + // Header parameters + let param_api_key = headers.get(HeaderName::from_static("api_key")); + + let param_api_key = match param_api_key { + Some(v) => match header::IntoHeaderValue::::try_from((*v).clone()) { + Ok(result) => + Some(result.0), + Err(err) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Invalid header api_key - {err}"))) + .expect("Unable to create Bad Request response for invalid header api_key")); + + }, + }, + None => { + None + } + }; + + let result = api_impl.delete_pet( + param_pet_id, + param_api_key, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + DeletePetResponse::InvalidPetValue + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // GetPetById - GET /pet/{petId} + hyper::Method::GET if path.matched(paths::ID_PET_PETID) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + } + + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_PET_PETID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter petId: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.get_pet_by_id( + param_pet_id, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetPetByIdResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + GetPetByIdResponse::InvalidIDSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + GetPetByIdResponse::PetNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // UpdatePetWithForm - POST /pet/{petId} + hyper::Method::POST if path.matched(paths::ID_PET_PETID) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_PET_PETID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter petId: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + // Form parameters + let param_name = + Some("name_example".to_string()); + let param_status = + Some("status_example".to_string()); + + + let result = api_impl.update_pet_with_form( + param_pet_id, + param_name, + param_status, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + UpdatePetWithFormResponse::InvalidInput + => { + *response.status_mut() = StatusCode::from_u16(405).expect("Unable to turn 405 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // UploadFile - POST /pet/{petId}/uploadImage + hyper::Method::POST if path.matched(paths::ID_PET_PETID_UPLOADIMAGE) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + + // Authorization + if let Scopes::Some(ref scopes) = authorization.scopes { + let required_scopes: std::collections::BTreeSet = vec![ + "write:pets".to_string(), // modify pets in your account + "read:pets".to_string(), // read your pets + ].into_iter().collect(); + + if !required_scopes.is_subset(scopes) { + let missing_scopes = required_scopes.difference(scopes); + return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from(missing_scopes.fold( + "Insufficient authorization, missing scopes".to_string(), + |s, scope| format!("{s} {scope}")) + )) + .expect("Unable to create Authentication Insufficient response") + ); + } + } + } + + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_PET_PETID_UPLOADIMAGE + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE PET_PETID_UPLOADIMAGE in set but failed match against \"{}\"", path, paths::REGEX_PET_PETID_UPLOADIMAGE.as_str()) + ); + + let param_pet_id = match percent_encoding::percent_decode(path_params["petId"].as_bytes()).decode_utf8() { + Ok(param_pet_id) => match param_pet_id.parse::() { + Ok(param_pet_id) => param_pet_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter petId: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let boundary = match swagger::multipart::form::boundary(&headers) { + Some(boundary) => boundary.to_string(), + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Couldn't find valid multipart body".to_string())) + .expect("Unable to create Bad Request response for incorrect boundary")), + }; + + use std::io::Read; + + // Read Form Parameters from body + let mut entries = match Multipart::with_body(&body.to_vec()[..], boundary) + .save() + .size_limit(multipart_form_size_limit) + .temp() + { + SaveResult::Full(entries) => { + entries + }, + SaveResult::Partial(_, PartialReason::CountLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .expect("Unable to create Bad Request response due to excessive parts")) + }, + SaveResult::Partial(_, PartialReason::SizeLimit) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to excessive data".to_string())) + .expect("Unable to create Bad Request response due to excessive data")) + }, + SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { + return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Unable to process message part due to invalid data".to_string())) + .expect("Unable to create Bad Request response due to invalid data")) + }, + SaveResult::Partial(_, PartialReason::IoError(_)) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process message part due an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + SaveResult::Error(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .expect("Unable to create Internal Server Error response due to an internal error")) + }, + }; + let field_additional_metadata = entries.fields.remove("additional_metadata"); + let param_additional_metadata = match field_additional_metadata { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for additional_metadata"); + Some({ + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let additional_metadata_model: String = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("additional_metadata data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter additional_metadata")) + } + }; + additional_metadata_model + }) + }, + None => { + None + } + }; + let field_file = entries.fields.remove("file"); + let param_file = match field_file { + Some(field) => { + let mut reader = field[0].data.readable().expect("Unable to read field for file"); + Some({ + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let file_model: swagger::ByteArray = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("file data does not match API definition : {e}"))) + .expect("Unable to create Bad Request due to missing required form parameter file")) + } + }; + file_model + }) + }, + None => { + None + } + }; + + + let result = api_impl.upload_file( + param_pet_id, + param_additional_metadata, + param_file, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + UploadFileResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // GetInventory - GET /store/inventory + hyper::Method::GET if path.matched(paths::ID_STORE_INVENTORY) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + } + + let result = api_impl.get_inventory( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetInventoryResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // PlaceOrder - POST /store/order + hyper::Method::POST if path.matched(paths::ID_STORE_ORDER) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.place_order( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + PlaceOrderResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + PlaceOrderResponse::InvalidOrder + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // DeleteOrder - DELETE /store/order/{order_id} + hyper::Method::DELETE if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_STORE_ORDER_ORDER_ID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE STORE_ORDER_ORDER_ID in set but failed match against \"{}\"", path, paths::REGEX_STORE_ORDER_ORDER_ID.as_str()) + ); + + let param_order_id = match percent_encoding::percent_decode(path_params["order_id"].as_bytes()).decode_utf8() { + Ok(param_order_id) => match param_order_id.parse::() { + Ok(param_order_id) => param_order_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter order_id: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.delete_order( + param_order_id, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + DeleteOrderResponse::InvalidIDSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + DeleteOrderResponse::OrderNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // GetOrderById - GET /store/order/{order_id} + hyper::Method::GET if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_STORE_ORDER_ORDER_ID + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE STORE_ORDER_ORDER_ID in set but failed match against \"{}\"", path, paths::REGEX_STORE_ORDER_ORDER_ID.as_str()) + ); + + let param_order_id = match percent_encoding::percent_decode(path_params["order_id"].as_bytes()).decode_utf8() { + Ok(param_order_id) => match param_order_id.parse::() { + Ok(param_order_id) => param_order_id, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter order_id: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.get_order_by_id( + param_order_id, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetOrderByIdResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + GetOrderByIdResponse::InvalidIDSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + GetOrderByIdResponse::OrderNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // CreateUser - POST /user + hyper::Method::POST if path.matched(paths::ID_USER) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.create_user( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + CreateUserResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(0).expect("Unable to turn 0 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // CreateUsersWithArrayInput - POST /user/createWithArray + hyper::Method::POST if path.matched(paths::ID_USER_CREATEWITHARRAY) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option> = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.create_users_with_array_input( + param_body.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + CreateUsersWithArrayInputResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(0).expect("Unable to turn 0 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // CreateUsersWithListInput - POST /user/createWithList + hyper::Method::POST if path.matched(paths::ID_USER_CREATEWITHLIST) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option> = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.create_users_with_list_input( + param_body.as_ref(), + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + CreateUsersWithListInputResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(0).expect("Unable to turn 0 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // LoginUser - GET /user/login + hyper::Method::GET if path.matched(paths::ID_USER_LOGIN) => { + // 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::>(); + let param_username = query_params.iter().filter(|e| e.0 == "username").map(|e| e.1.clone()) + .next(); + let param_username = match param_username { + Some(param_username) => { + let param_username = + ::from_str + (¶m_username); + match param_username { + Ok(param_username) => Some(param_username), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter username - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter username")), + } + }, + None => None, + }; + let param_username = match param_username { + Some(param_username) => param_username, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter username")) + .expect("Unable to create Bad Request response for missing query parameter username")), + }; + let param_password = query_params.iter().filter(|e| e.0 == "password").map(|e| e.1.clone()) + .next(); + let param_password = match param_password { + Some(param_password) => { + let param_password = + ::from_str + (¶m_password); + match param_password { + Ok(param_password) => Some(param_password), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter password - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter password")), + } + }, + None => None, + }; + let param_password = match param_password { + Some(param_password) => param_password, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter password")) + .expect("Unable to create Bad Request response for missing query parameter password")), + }; + + let result = api_impl.login_user( + param_username, + param_password, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + LoginUserResponse::SuccessfulOperation + { + body, + x_rate_limit, + x_expires_after + } + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + if let Some(x_rate_limit) = x_rate_limit { + let x_rate_limit = match header::IntoHeaderValue(x_rate_limit).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling x_rate_limit header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("x-rate-limit"), + x_rate_limit + ); + } + + if let Some(x_expires_after) = x_expires_after { + let x_expires_after = match header::IntoHeaderValue(x_expires_after).try_into() { + Ok(val) => val, + Err(e) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(format!("An internal server error occurred handling x_expires_after header - {e}"))) + .expect("Unable to create Internal Server Error for invalid response header")) + } + }; + + response.headers_mut().insert( + HeaderName::from_static("x-expires-after"), + x_expires_after + ); + } + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + LoginUserResponse::InvalidUsername + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // LogoutUser - GET /user/logout + hyper::Method::GET if path.matched(paths::ID_USER_LOGOUT) => { + let result = api_impl.logout_user( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + LogoutUserResponse::SuccessfulOperation + => { + *response.status_mut() = StatusCode::from_u16(0).expect("Unable to turn 0 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // DeleteUser - DELETE /user/{username} + hyper::Method::DELETE if path.matched(paths::ID_USER_USERNAME) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter username: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.delete_user( + param_username, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + DeleteUserResponse::InvalidUsernameSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + DeleteUserResponse::UserNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // GetUserByName - GET /user/{username} + hyper::Method::GET if path.matched(paths::ID_USER_USERNAME) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter username: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + let result = api_impl.get_user_by_name( + param_username, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetUserByNameResponse::SuccessfulOperation + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/xml") + .expect("Unable to create Content-Type header for application/xml")); + // XML Body + let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + GetUserByNameResponse::InvalidUsernameSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + GetUserByNameResponse::UserNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // UpdateUser - PUT /user/{username} + hyper::Method::PUT if path.matched(paths::ID_USER_USERNAME) => { + // Path parameters + let path: &str = uri.path(); + let path_params = + paths::REGEX_USER_USERNAME + .captures(path) + .unwrap_or_else(|| + panic!("Path {} matched RE USER_USERNAME in set but failed match against \"{}\"", path, paths::REGEX_USER_USERNAME.as_str()) + ); + + let param_username = match percent_encoding::percent_decode(path_params["username"].as_bytes()).decode_utf8() { + Ok(param_username) => match param_username.parse::() { + Ok(param_username) => param_username, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse path parameter username: {e}"))) + .expect("Unable to create Bad Request response for invalid path parameter")), + }, + Err(_) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .expect("Unable to create Bad Request response for invalid percent decode")) + }; + + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_body: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_body) => param_body, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.update_user( + param_username, + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + UpdateUserResponse::InvalidUserSupplied + => { + *response.status_mut() = StatusCode::from_u16(400).expect("Unable to turn 400 into a StatusCode"); + + }, + UpdateUserResponse::UserNotFound + => { + *response.status_mut() = StatusCode::from_u16(404).expect("Unable to turn 404 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + _ if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_BODY_WITH_QUERY_PARAMS) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_HYPHENPARAM_HYPHEN_PARAM) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_INLINE_ADDITIONALPROPERTIES) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_JSONFORMDATA) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_OPERATION_WITH_NUMERIC_ID) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_OUTER_BOOLEAN) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_OUTER_COMPOSITE) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_OUTER_NUMBER) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_OUTER_STRING) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => method_not_allowed(), + _ if path.matched(paths::ID_FAKE_CLASSNAME_TEST) => method_not_allowed(), + _ if path.matched(paths::ID_PET) => method_not_allowed(), + _ if path.matched(paths::ID_PET_FINDBYSTATUS) => method_not_allowed(), + _ if path.matched(paths::ID_PET_FINDBYTAGS) => method_not_allowed(), + _ if path.matched(paths::ID_PET_PETID) => method_not_allowed(), + _ if path.matched(paths::ID_PET_PETID_UPLOADIMAGE) => method_not_allowed(), + _ if path.matched(paths::ID_STORE_INVENTORY) => method_not_allowed(), + _ if path.matched(paths::ID_STORE_ORDER) => method_not_allowed(), + _ if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => method_not_allowed(), + _ if path.matched(paths::ID_USER) => method_not_allowed(), + _ if path.matched(paths::ID_USER_CREATEWITHARRAY) => method_not_allowed(), + _ if path.matched(paths::ID_USER_CREATEWITHLIST) => method_not_allowed(), + _ if path.matched(paths::ID_USER_LOGIN) => method_not_allowed(), + _ if path.matched(paths::ID_USER_LOGOUT) => method_not_allowed(), + _ if path.matched(paths::ID_USER_USERNAME) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + self.multipart_form_size_limit, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // TestSpecialTags - PATCH /another-fake/dummy + hyper::Method::PATCH if path.matched(paths::ID_ANOTHER_FAKE_DUMMY) => Some("TestSpecialTags"), + // Call123example - GET /fake/operation-with-numeric-id + hyper::Method::GET if path.matched(paths::ID_FAKE_OPERATION_WITH_NUMERIC_ID) => Some("Call123example"), + // FakeOuterBooleanSerialize - POST /fake/outer/boolean + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_BOOLEAN) => Some("FakeOuterBooleanSerialize"), + // FakeOuterCompositeSerialize - POST /fake/outer/composite + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_COMPOSITE) => Some("FakeOuterCompositeSerialize"), + // FakeOuterNumberSerialize - POST /fake/outer/number + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_NUMBER) => Some("FakeOuterNumberSerialize"), + // FakeOuterStringSerialize - POST /fake/outer/string + hyper::Method::POST if path.matched(paths::ID_FAKE_OUTER_STRING) => Some("FakeOuterStringSerialize"), + // FakeResponseWithNumericalDescription - GET /fake/response-with-numerical-description + hyper::Method::GET if path.matched(paths::ID_FAKE_RESPONSE_WITH_NUMERICAL_DESCRIPTION) => Some("FakeResponseWithNumericalDescription"), + // TestBodyWithQueryParams - PUT /fake/body-with-query-params + hyper::Method::PUT if path.matched(paths::ID_FAKE_BODY_WITH_QUERY_PARAMS) => Some("TestBodyWithQueryParams"), + // TestClientModel - PATCH /fake + hyper::Method::PATCH if path.matched(paths::ID_FAKE) => Some("TestClientModel"), + // TestEndpointParameters - POST /fake + hyper::Method::POST if path.matched(paths::ID_FAKE) => Some("TestEndpointParameters"), + // TestEnumParameters - GET /fake + hyper::Method::GET if path.matched(paths::ID_FAKE) => Some("TestEnumParameters"), + // TestInlineAdditionalProperties - POST /fake/inline-additionalProperties + hyper::Method::POST if path.matched(paths::ID_FAKE_INLINE_ADDITIONALPROPERTIES) => Some("TestInlineAdditionalProperties"), + // TestJsonFormData - GET /fake/jsonFormData + hyper::Method::GET if path.matched(paths::ID_FAKE_JSONFORMDATA) => Some("TestJsonFormData"), + // HyphenParam - GET /fake/hyphenParam/{hyphen-param} + hyper::Method::GET if path.matched(paths::ID_FAKE_HYPHENPARAM_HYPHEN_PARAM) => Some("HyphenParam"), + // TestClassname - PATCH /fake_classname_test + hyper::Method::PATCH if path.matched(paths::ID_FAKE_CLASSNAME_TEST) => Some("TestClassname"), + // AddPet - POST /pet + hyper::Method::POST if path.matched(paths::ID_PET) => Some("AddPet"), + // FindPetsByStatus - GET /pet/findByStatus + hyper::Method::GET if path.matched(paths::ID_PET_FINDBYSTATUS) => Some("FindPetsByStatus"), + // FindPetsByTags - GET /pet/findByTags + hyper::Method::GET if path.matched(paths::ID_PET_FINDBYTAGS) => Some("FindPetsByTags"), + // UpdatePet - PUT /pet + hyper::Method::PUT if path.matched(paths::ID_PET) => Some("UpdatePet"), + // DeletePet - DELETE /pet/{petId} + hyper::Method::DELETE if path.matched(paths::ID_PET_PETID) => Some("DeletePet"), + // GetPetById - GET /pet/{petId} + hyper::Method::GET if path.matched(paths::ID_PET_PETID) => Some("GetPetById"), + // UpdatePetWithForm - POST /pet/{petId} + hyper::Method::POST if path.matched(paths::ID_PET_PETID) => Some("UpdatePetWithForm"), + // UploadFile - POST /pet/{petId}/uploadImage + hyper::Method::POST if path.matched(paths::ID_PET_PETID_UPLOADIMAGE) => Some("UploadFile"), + // GetInventory - GET /store/inventory + hyper::Method::GET if path.matched(paths::ID_STORE_INVENTORY) => Some("GetInventory"), + // PlaceOrder - POST /store/order + hyper::Method::POST if path.matched(paths::ID_STORE_ORDER) => Some("PlaceOrder"), + // DeleteOrder - DELETE /store/order/{order_id} + hyper::Method::DELETE if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => Some("DeleteOrder"), + // GetOrderById - GET /store/order/{order_id} + hyper::Method::GET if path.matched(paths::ID_STORE_ORDER_ORDER_ID) => Some("GetOrderById"), + // CreateUser - POST /user + hyper::Method::POST if path.matched(paths::ID_USER) => Some("CreateUser"), + // CreateUsersWithArrayInput - POST /user/createWithArray + hyper::Method::POST if path.matched(paths::ID_USER_CREATEWITHARRAY) => Some("CreateUsersWithArrayInput"), + // CreateUsersWithListInput - POST /user/createWithList + hyper::Method::POST if path.matched(paths::ID_USER_CREATEWITHLIST) => Some("CreateUsersWithListInput"), + // LoginUser - GET /user/login + hyper::Method::GET if path.matched(paths::ID_USER_LOGIN) => Some("LoginUser"), + // LogoutUser - GET /user/logout + hyper::Method::GET if path.matched(paths::ID_USER_LOGOUT) => Some("LogoutUser"), + // DeleteUser - DELETE /user/{username} + hyper::Method::DELETE if path.matched(paths::ID_USER_USERNAME) => Some("DeleteUser"), + // GetUserByName - GET /user/{username} + hyper::Method::GET if path.matched(paths::ID_USER_USERNAME) => Some("GetUserByName"), + // UpdateUser - PUT /user/{username} + hyper::Method::PUT if path.matched(paths::ID_USER_USERNAME) => Some("UpdateUser"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/ping-bearer-auth/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.gitignore b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/FILES new file mode 100644 index 000000000000..ce2109b1de2e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/FILES @@ -0,0 +1,23 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/default_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/Cargo.toml new file mode 100644 index 000000000000..c8e60c539bba --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/Cargo.toml @@ -0,0 +1,96 @@ +[package] +name = "ping-bearer-auth" +version = "1.0.0" +authors = ["OpenAPI Generator team and contributors"] +description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "ping-bearer-auth" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/README.md b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/README.md new file mode 100644 index 000000000000..a271c49c17dc --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/README.md @@ -0,0 +1,145 @@ +# Rust API for ping-bearer-auth + +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +## Overview + +This client/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: 1.0 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `ping-bearer-auth` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `ping-bearer-auth`: + +* The example server starts up a web server using the `ping-bearer-auth` + 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 `ping-bearer-auth` 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 the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client PingGet +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost:8080* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**pingGet**](docs/default_api.md#pingGet) | **GET** /ping | + + +## Documentation For Models + + + +## Documentation For Authorization + +Authentication schemes defined for the API: +### bearerAuth +- **Type**: Bearer token authentication + +Example +``` +``` + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/api/openapi.yaml new file mode 100644 index 000000000000..c33a45c78341 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/api/openapi.yaml @@ -0,0 +1,23 @@ +openapi: 3.0.1 +info: + title: ping test + version: "1.0" +servers: +- url: http://localhost:8080/ +security: +- bearerAuth: [] +paths: + /ping: + get: + operationId: pingGet + responses: + "201": + description: OK +components: + schemas: {} + securitySchemes: + bearerAuth: + bearerFormat: token + scheme: bearer + type: http + diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/bin/cli.rs new file mode 100644 index 000000000000..5838290c33a9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/bin/cli.rs @@ -0,0 +1,156 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use ping_bearer_auth::{ + models, ApiNoContext, Client, ContextWrapperExt, + PingGetResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "ping test", + version = "1.0", + about = "CLI access to ping test" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, + + /// Bearer token if used for authentication + #[structopt(env = "PING_BEARER_AUTH_BEARER_TOKEN", hide_env_values = true)] + bearer_token: Option, +} + +#[derive(StructOpt, Debug)] +enum Operation { + PingGet { + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let mut auth_data: Option = None; + + if let Some(ref bearer_token) = args.bearer_token { + debug!("Using bearer token"); + auth_data = Some(AuthData::bearer(bearer_token)); + } + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::PingGet { + } => { + info!("Performing a PingGet request"); + + let result = client.ping_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + PingGetResponse::OK + => "OK\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/docs/default_api.md new file mode 100644 index 000000000000..2aab8587315d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/docs/default_api.md @@ -0,0 +1,31 @@ +# default_api + +All URIs are relative to *http://localhost:8080* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**pingGet**](default_api.md#pingGet) | **GET** /ping | + + +# **pingGet** +> pingGet(ctx, ) + + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +[bearerAuth](../README.md#bearerAuth) + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/client_auth.rs new file mode 100644 index 000000000000..75571b40f0ae --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use ping_bearer_auth::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/main.rs new file mode 100644 index 000000000000..e19f556283f4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/client/main.rs @@ -0,0 +1,115 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use ping_bearer_auth::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + PingGetResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "PingGet", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + "".to_owned() + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + Some("PingGet") => { + let result = rt.block_on(client.ping_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/main.rs new file mode 100644 index 000000000000..6b54873a7e94 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for ping_bearer_auth implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server.rs new file mode 100644 index 000000000000..7cac3452a975 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server.rs @@ -0,0 +1,122 @@ +//! Main library entry point for ping_bearer_auth implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use ping_bearer_auth::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + ping_bearer_auth::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use ping_bearer_auth::{ + Api, + PingGetResponse, +}; +use ping_bearer_auth::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn ping_get( + &self, + context: &C) -> Result + { + info!("ping_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server_auth.rs new file mode 100644 index 000000000000..15b1fc1a4443 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/examples/server/server_auth.rs @@ -0,0 +1,127 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use ping_bearer_auth::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + "".to_owned() + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/client/mod.rs new file mode 100644 index 000000000000..df5337dd74ef --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/client/mod.rs @@ -0,0 +1,470 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + PingGetResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Has> + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn ping_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/ping", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + #[allow(clippy::collapsible_match)] + if let Some(auth_data) = Has::>::get(context).as_ref() { + #[allow(clippy::single_match, clippy::match_single_binding)] + match auth_data { + AuthData::Bearer(bearer_header) => { + let auth = swagger::auth::Header(bearer_header.clone()); + let header = match HeaderValue::from_str(&format!("{auth}")) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) + }; + request.headers_mut().insert( + hyper::header::AUTHORIZATION, + header); + }, + _ => {} + } + } + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 201 => { + Ok( + PingGetResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/context.rs new file mode 100644 index 000000000000..e01187ca3c82 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/context.rs @@ -0,0 +1,133 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + { + use swagger::auth::Bearer; + use std::ops::Deref; + if let Some(bearer) = swagger::auth::from_headers::(headers) { + let authorization = self.inner.bearer_authorization(&bearer); + let auth_data = AuthData::Bearer(bearer); + + let context = context.push(Some(auth_data)); + let context = match authorization { + Ok(auth) => context.push(Some(auth)), + Err(err) => { + error!("Error during Authorization: {err:?}"); + context.push(None::) + } + }; + + return self.inner.call((request, context)) + } + } + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/lib.rs new file mode 100644 index 000000000000..495d022b04a3 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/lib.rs @@ -0,0 +1,112 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "1.0"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum PingGetResponse { + /// OK + OK +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn ping_get( + &self, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn ping_get( + &self, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn ping_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().ping_get(&context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/models.rs new file mode 100644 index 000000000000..d0763192cf7c --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/models.rs @@ -0,0 +1,8 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/mod.rs new file mode 100644 index 000000000000..cb5761f49013 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/mod.rs @@ -0,0 +1,215 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + PingGetResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/ping$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_PING: usize = 0; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Has> + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // PingGet - GET /ping + hyper::Method::GET if path.matched(paths::ID_PING) => { + { + let authorization = match *(&context as &dyn Has>).get() { + Some(ref authorization) => authorization, + None => return Ok(Response::builder() + .status(StatusCode::FORBIDDEN) + .body(Body::from("Unauthenticated")) + .expect("Unable to create Authentication Forbidden response")), + }; + } + + let result = api_impl.ping_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + PingGetResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(201).expect("Unable to turn 201 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + _ if path.matched(paths::ID_PING) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // PingGet - GET /ping + hyper::Method::GET if path.matched(paths::ID_PING) => Some("PingGet"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/ping-bearer-auth/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server/output/rust-server-test/.cargo/config b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.cargo/config similarity index 100% rename from samples/server/petstore/rust-server/output/rust-server-test/.cargo/config rename to samples/server/petstore/rust-server-deprecated/output/rust-server-test/.cargo/config diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.gitignore b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.gitignore new file mode 100644 index 000000000000..a9d37c560c6a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator-ignore b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/FILES b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/FILES new file mode 100644 index 000000000000..e27ac4b0b61a --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/FILES @@ -0,0 +1,31 @@ +.cargo/config +.gitignore +Cargo.toml +README.md +api/openapi.yaml +bin/cli.rs +docs/ANullableContainer.md +docs/AdditionalPropertiesObject.md +docs/AllOfObject.md +docs/BaseAllOf.md +docs/DummyPutRequest.md +docs/GetYamlResponse.md +docs/ObjectOfObjects.md +docs/ObjectOfObjectsInner.md +docs/default_api.md +examples/ca.pem +examples/client/client_auth.rs +examples/client/main.rs +examples/server-chain.pem +examples/server-key.pem +examples/server/main.rs +examples/server/server.rs +examples/server/server_auth.rs +src/auth.rs +src/client/mod.rs +src/context.rs +src/header.rs +src/lib.rs +src/models.rs +src/server/mod.rs +src/server/server_auth.rs diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/VERSION b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/VERSION new file mode 100644 index 000000000000..fc74d6ceba8e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.15.0-SNAPSHOT diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/Cargo.toml b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/Cargo.toml new file mode 100644 index 000000000000..f85aaea14517 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/Cargo.toml @@ -0,0 +1,96 @@ +[package] +name = "rust-server-test" +version = "2.3.4" +authors = ["OpenAPI Generator team and contributors"] +description = "This spec is for testing rust-server-specific things" +# Override this license by providing a License Object in the OpenAPI. +license = "Unlicense" +edition = "2018" + +[features] +default = ["client", "server"] +client = [ + "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" +] +server = [ + "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" +] +cli = [ + "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" +] +conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] + +[target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] +native-tls = { version = "0.2", optional = true } +hyper-tls = { version = "0.5", optional = true } + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] +hyper-openssl = { version = "0.9", optional = true } +openssl = {version = "0.10", optional = true } + +[dependencies] +# Common +async-trait = "0.1.24" +chrono = { version = "0.4", features = ["serde"] } +futures = "0.3" +swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } +log = "0.4.0" +mime = "0.3" + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +validator = { version = "0.16", features = ["derive"] } + +# Crates included if required by the API definition + +# Common between server and client features +hyper = {version = "0.14", features = ["full"], optional = true} +serde_ignored = {version = "0.1.1", optional = true} +url = {version = "2.1", optional = true} + +# Client-specific + +# Server, and client callback-specific +lazy_static = { version = "1.4", optional = true } +percent-encoding = {version = "2.1.0", optional = true} +regex = {version = "1.3", optional = true} + +# CLI-specific +anyhow = { version = "1", optional = true } +clap-verbosity-flag = { version = "0.3", optional = true } +simple_logger = { version = "2.0", features = ["stderr"], optional = true } +structopt = { version = "0.3", optional = true } +tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } + +# Conversion +frunk = { version = "0.4.0", optional = true } +frunk_derives = { version = "0.4.0", optional = true } +frunk_core = { version = "0.4.0", optional = true } +frunk-enum-derive = { version = "0.3.0", optional = true } +frunk-enum-core = { version = "0.3.0", optional = true } + +# Bearer authentication +jsonwebtoken = { version = "9.3.0", optional = false } + +[dev-dependencies] +clap = "2.25" +env_logger = "0.11" +tokio = { version = "1.14", features = ["full"] } +native-tls = "0.2" + +[target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] +tokio-openssl = "0.6" +openssl = "0.10" + +[[example]] +name = "client" +required-features = ["client"] + +[[example]] +name = "server" +required-features = ["server"] + +[[bin]] +name = "rust-server-test" +path = "bin/cli.rs" +required-features = ["client", "cli"] diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/README.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/README.md new file mode 100644 index 000000000000..7df0f0f02113 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/README.md @@ -0,0 +1,161 @@ +# Rust API for rust-server-test + +This spec is for testing rust-server-specific things + +## Overview + +This client/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: 2.3.4 +- Generator version: 7.15.0-SNAPSHOT + + + +This autogenerated project defines an API crate `rust-server-test` 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. +* A CLI tool to drive basic API operations from the command line. + +It also contains an example server and client which make use of `rust-server-test`: + +* The example server starts up a web server using the `rust-server-test` + router, and supplies a trivial implementation of `Api` which returns failure + for every operation. +* The example client provides a CLI which lets you invoke + any single operation on the `rust-server-test` client by passing appropriate + arguments on the command line. + +You can use the example server and client as a basis for your own code. +See below for [more detail on the examples](#using-the-generated-library). + +## CLI + +Run the included CLI tool with: + +``` +cargo run --bin cli --features=cli +``` + +To pass in arguments, put them after `--`, for example: + +``` +cargo run --bin cli --features=cli -- --help +``` + +See the help text for available options. + +To build a standalone tool, use: + +``` +cargo build --bin cli --features=cli --release +``` + +You'll find the binary at `target/release/cli`. + +## Examples + +Run examples with: + +``` +cargo run --example +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example client AllOfGet +cargo run --example client DummyGet +cargo run --example client FileResponseGet +cargo run --example client GetStructuredYaml +cargo run --example client HtmlPost +cargo run --example client PostYaml +cargo run --example client RawJsonGet +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example server -- --https +``` + +This will use the keys/certificates from the examples directory. Note that the +server chain is signed with `CN=localhost`. + +## Using the generated library + +The generated library has a few optional features that can be activated through Cargo. + +* `server` + * This defaults to enabled and creates the basic skeleton of a server implementation based on hyper + * To create the server stack you'll need to provide an implementation of the API trait to provide the server function. +* `client` + * This defaults to enabled and creates the basic skeleton of a client implementation based on hyper + * The constructed client implements the API trait by making remote API call. +* `conversions` + * This defaults to disabled and creates extra derives on models to allow "transmogrification" between objects of structurally similar types. +* `cli` + * This defaults to disabled and is required for building the included CLI tool. + +See https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section for how to use features in your `Cargo.toml`. + +## Documentation for API Endpoints + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**AllOf_Get**](docs/default_api.md#AllOf_Get) | **GET** /allOf | +[**dummyGet**](docs/default_api.md#dummyGet) | **GET** /dummy | A dummy endpoint to make the spec valid. +[**dummyPut**](docs/default_api.md#dummyPut) | **PUT** /dummy | +[**file_responseGet**](docs/default_api.md#file_responseGet) | **GET** /file_response | Get a file +[**getStructuredYaml**](docs/default_api.md#getStructuredYaml) | **GET** /get-structured-yaml | +[**htmlPost**](docs/default_api.md#htmlPost) | **POST** /html | Test HTML handling +[**post_yaml**](docs/default_api.md#post_yaml) | **POST** /post-yaml | +[**raw_jsonGet**](docs/default_api.md#raw_jsonGet) | **GET** /raw_json | Get an arbitrary JSON blob. +[**solo_objectPost**](docs/default_api.md#solo_objectPost) | **POST** /solo-object | Send an arbitrary JSON blob + + +## Documentation For Models + + - [ANullableContainer](docs/ANullableContainer.md) + - [AdditionalPropertiesObject](docs/AdditionalPropertiesObject.md) + - [AllOfObject](docs/AllOfObject.md) + - [BaseAllOf](docs/BaseAllOf.md) + - [DummyPutRequest](docs/DummyPutRequest.md) + - [GetYamlResponse](docs/GetYamlResponse.md) + - [ObjectOfObjects](docs/ObjectOfObjects.md) + - [ObjectOfObjectsInner](docs/ObjectOfObjectsInner.md) + + +## Documentation For Authorization +Endpoints do not require authorization. + + +## Author + + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/api/openapi.yaml b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/api/openapi.yaml new file mode 100644 index 000000000000..bfa9d4342d42 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/api/openapi.yaml @@ -0,0 +1,202 @@ +openapi: 3.0.1 +info: + description: This spec is for testing rust-server-specific things + title: rust-server-test + version: 2.3.4 +servers: +- url: / +paths: + /dummy: + get: + operationId: dummyGet + responses: + "200": + content: {} + description: Success + summary: A dummy endpoint to make the spec valid. + put: + operationId: dummyPut + requestBody: + content: + '*/*': + schema: + $ref: "#/components/schemas/dummyPut_request" + required: true + responses: + "200": + content: {} + description: Success + x-codegen-request-body-name: nested_response + /html: + post: + operationId: htmlPost + requestBody: + content: + text/html: + schema: + type: string + required: true + responses: + "200": + content: + text/html: + schema: + type: string + description: Success + summary: Test HTML handling + x-codegen-request-body-name: body + /file_response: + get: + operationId: file_responseGet + responses: + "200": + content: + application/json: + schema: + format: binary + type: string + description: Success + summary: Get a file + /raw_json: + get: + operationId: raw_jsonGet + responses: + "200": + content: + '*/*': + schema: + type: object + description: Success + summary: Get an arbitrary JSON blob. + /solo-object: + post: + operationId: solo_objectPost + requestBody: + content: + application/json: + schema: + type: object + required: true + responses: + "204": + content: {} + description: OK + summary: Send an arbitrary JSON blob + x-codegen-request-body-name: value + /post-yaml: + post: + description: Test sending an arbitrary unsupported format - e.g. YAML + operationId: post_yaml + requestBody: + content: + application/yaml: + schema: + type: string + description: The YAML body to test + required: true + responses: + "204": + content: {} + description: OK + x-codegen-request-body-name: value + /get-structured-yaml: + get: + description: Test returning arbitrary structured YAML + operationId: getStructuredYaml + responses: + "200": + content: + application/yaml: + schema: + $ref: "#/components/schemas/get_yaml_response" + description: OK + /allOf: + get: + description: Test getting an object which uses allOf + operationId: AllOf_Get + responses: + "200": + content: + '*/*': + schema: + $ref: "#/components/schemas/allOfObject" + description: OK +components: + requestBodies: + nested_response: + content: + '*/*': + schema: + properties: + id: + type: string + password: + type: string + required: + - id + type: object + required: true + schemas: + additionalPropertiesObject: + additionalProperties: + type: string + description: An additionalPropertiesObject + example: foo + type: object + allOfObject: + allOf: + - $ref: "#/components/schemas/baseAllOf" + example: + sampleProperty: sampleProperty + properties: + sampleProperty: + type: string + baseAllOf: + properties: + sampleBaseProperty: + type: string + type: object + aNullableContainer: + properties: + NullableThing: + nullable: true + type: string + RequiredNullableThing: + nullable: true + type: string + required: + - RequiredNullableThing + type: object + ObjectOfObjects: + description: An object of objects + properties: + inner: + $ref: "#/components/schemas/ObjectOfObjects_inner" + type: object + get_yaml_response: + description: structured response + properties: + value: + description: Inner string + type: string + type: object + dummyPut_request: + properties: + id: + type: string + password: + type: string + required: + - id + type: object + ObjectOfObjects_inner: + properties: + required_thing: + type: string + optional_thing: + type: integer + required: + - required_thing + type: object +x-original-swagger-version: "2.0" + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/bin/cli.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/bin/cli.rs new file mode 100644 index 000000000000..e582c479c363 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/bin/cli.rs @@ -0,0 +1,312 @@ +//! CLI tool driving the API client +use anyhow::{anyhow, Context, Result}; +use log::{debug, info}; +// models may be unused if all inputs are primitive types +#[allow(unused_imports)] +use rust_server_test::{ + models, ApiNoContext, Client, ContextWrapperExt, + AllOfGetResponse, + DummyGetResponse, + DummyPutResponse, + FileResponseGetResponse, + GetStructuredYamlResponse, + HtmlPostResponse, + PostYamlResponse, + RawJsonGetResponse, + SoloObjectPostResponse, +}; +use simple_logger::SimpleLogger; +use structopt::StructOpt; +use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!( + ContextBuilder, + EmptyContext, + Option, + XSpanIdString +); + +#[derive(StructOpt, Debug)] +#[structopt( + name = "rust-server-test", + version = "2.3.4", + about = "CLI access to rust-server-test" +)] +struct Cli { + #[structopt(subcommand)] + operation: Operation, + + /// Address or hostname of the server hosting this API, including optional port + #[structopt(short = "a", long, default_value = "http://localhost")] + server_address: String, + + /// Path to the client private key if using client-side TLS authentication + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + client_key: Option, + + /// Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + client_certificate: Option, + + /// Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + #[structopt(long)] + server_certificate: Option, + + /// If set, write output to file instead of stdout + #[structopt(short, long)] + output_file: Option, + + #[structopt(flatten)] + verbosity: clap_verbosity_flag::Verbosity, +} + +#[derive(StructOpt, Debug)] +enum Operation { + AllOfGet { + }, + /// A dummy endpoint to make the spec valid. + DummyGet { + }, + DummyPut { + #[structopt(parse(try_from_str = parse_json))] + nested_response: models::DummyPutRequest, + }, + /// Get a file + FileResponseGet { + }, + GetStructuredYaml { + }, + /// Test HTML handling + HtmlPost { + body: String, + }, + PostYaml { + /// The YAML body to test + value: String, + }, + /// Get an arbitrary JSON blob. + RawJsonGet { + }, + /// Send an arbitrary JSON blob + SoloObjectPost { + value: serde_json::Value, + }, +} + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + if args.client_certificate.is_some() { + debug!("Using mutual TLS"); + let client = Client::try_new_https_mutual( + &args.server_address, + args.server_certificate.clone().unwrap(), + args.client_key.clone().unwrap(), + args.client_certificate.clone().unwrap(), + ) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else if args.server_certificate.is_some() { + debug!("Using TLS with pinned server certificate"); + let client = + Client::try_new_https_pinned(&args.server_address, args.server_certificate.clone().unwrap()) + .context("Failed to create HTTPS client")?; + Ok(Box::new(client.with_context(context))) + } else { + debug!("Using client without certificates"); + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +fn create_client(args: &Cli, context: ClientContext) -> Result>> { + let client = + Client::try_new(&args.server_address).context("Failed to create HTTP(S) client")?; + Ok(Box::new(client.with_context(context))) +} + +#[tokio::main] +async fn main() -> Result<()> { + let args = Cli::from_args(); + if let Some(log_level) = args.verbosity.log_level() { + SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; + } + + debug!("Arguments: {:?}", &args); + + let auth_data: Option = None; + + #[allow(trivial_casts)] + let context = swagger::make_context!( + ContextBuilder, + EmptyContext, + auth_data, + XSpanIdString::default() + ); + + let client = create_client(&args, context)?; + + let result = match args.operation { + Operation::AllOfGet { + } => { + info!("Performing a AllOfGet request"); + + let result = client.all_of_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + AllOfGetResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::DummyGet { + } => { + info!("Performing a DummyGet request"); + + let result = client.dummy_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + DummyGetResponse::Success + => "Success\n".to_string() + , + } + } + Operation::DummyPut { + nested_response, + } => { + info!("Performing a DummyPut request"); + + let result = client.dummy_put( + nested_response, + ).await?; + debug!("Result: {:?}", result); + + match result { + DummyPutResponse::Success + => "Success\n".to_string() + , + } + } + Operation::FileResponseGet { + } => { + info!("Performing a FileResponseGet request"); + + let result = client.file_response_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + FileResponseGetResponse::Success + (body) + => "Success\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::GetStructuredYaml { + } => { + info!("Performing a GetStructuredYaml request"); + + let result = client.get_structured_yaml( + ).await?; + debug!("Result: {:?}", result); + + match result { + GetStructuredYamlResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::HtmlPost { + body, + } => { + info!("Performing a HtmlPost request"); + + let result = client.html_post( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + HtmlPostResponse::Success + (body) + => "Success\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::PostYaml { + value, + } => { + info!("Performing a PostYaml request"); + + let result = client.post_yaml( + value, + ).await?; + debug!("Result: {:?}", result); + + match result { + PostYamlResponse::OK + => "OK\n".to_string() + , + } + } + Operation::RawJsonGet { + } => { + info!("Performing a RawJsonGet request"); + + let result = client.raw_json_get( + ).await?; + debug!("Result: {:?}", result); + + match result { + RawJsonGetResponse::Success + (body) + => "Success\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } + Operation::SoloObjectPost { + value, + } => { + info!("Performing a SoloObjectPost request"); + + let result = client.solo_object_post( + value, + ).await?; + debug!("Result: {:?}", result); + + match result { + SoloObjectPostResponse::OK + => "OK\n".to_string() + , + } + } + }; + + if let Some(output_file) = args.output_file { + std::fs::write(output_file, result)? + } else { + println!("{}", result); + } + Ok(()) +} + +// May be unused if all inputs are primitive types +#[allow(dead_code)] +fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { + serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ANullableContainer.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ANullableContainer.md new file mode 100644 index 000000000000..883546f323e9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ANullableContainer.md @@ -0,0 +1,11 @@ +# ANullableContainer + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**nullable_thing** | **swagger::Nullable** | | [optional] [default to None] +**required_nullable_thing** | **swagger::Nullable** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AdditionalPropertiesObject.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AdditionalPropertiesObject.md new file mode 100644 index 000000000000..add2259d383e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AdditionalPropertiesObject.md @@ -0,0 +1,9 @@ +# AdditionalPropertiesObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AllOfObject.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AllOfObject.md new file mode 100644 index 000000000000..d9f96cbbc22e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/AllOfObject.md @@ -0,0 +1,11 @@ +# AllOfObject + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**sample_property** | **String** | | [optional] [default to None] +**sample_base_property** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/BaseAllOf.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/BaseAllOf.md new file mode 100644 index 000000000000..9de71eae81f1 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/BaseAllOf.md @@ -0,0 +1,10 @@ +# BaseAllOf + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**sample_base_property** | **String** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server/output/rust-server-test/docs/InlineObject.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/DummyPutRequest.md similarity index 95% rename from samples/server/petstore/rust-server/output/rust-server-test/docs/InlineObject.md rename to samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/DummyPutRequest.md index c29026e8d7e0..7e9214c43659 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/docs/InlineObject.md +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/DummyPutRequest.md @@ -1,4 +1,4 @@ -# InlineObject +# DummyPutRequest ## Properties Name | Type | Description | Notes diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/GetYamlResponse.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/GetYamlResponse.md new file mode 100644 index 000000000000..fe36971696eb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/GetYamlResponse.md @@ -0,0 +1,10 @@ +# GetYamlResponse + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**value** | **String** | Inner string | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjects.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjects.md new file mode 100644 index 000000000000..86d6853d5aa8 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjects.md @@ -0,0 +1,10 @@ +# ObjectOfObjects + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**inner** | [***models::ObjectOfObjectsInner**](ObjectOfObjects_inner.md) | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjectsInner.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjectsInner.md new file mode 100644 index 000000000000..965210d38f9d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/ObjectOfObjectsInner.md @@ -0,0 +1,11 @@ +# ObjectOfObjectsInner + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**required_thing** | **String** | | +**optional_thing** | **i32** | | [optional] [default to None] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/default_api.md b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/default_api.md new file mode 100644 index 000000000000..72af23483491 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/docs/default_api.md @@ -0,0 +1,233 @@ +# default_api + +All URIs are relative to *http://localhost* + +Method | HTTP request | Description +------------- | ------------- | ------------- +**AllOf_Get**](default_api.md#AllOf_Get) | **GET** /allOf | +**dummyGet**](default_api.md#dummyGet) | **GET** /dummy | A dummy endpoint to make the spec valid. +**dummyPut**](default_api.md#dummyPut) | **PUT** /dummy | +**file_responseGet**](default_api.md#file_responseGet) | **GET** /file_response | Get a file +**getStructuredYaml**](default_api.md#getStructuredYaml) | **GET** /get-structured-yaml | +**htmlPost**](default_api.md#htmlPost) | **POST** /html | Test HTML handling +**post_yaml**](default_api.md#post_yaml) | **POST** /post-yaml | +**raw_jsonGet**](default_api.md#raw_jsonGet) | **GET** /raw_json | Get an arbitrary JSON blob. +**solo_objectPost**](default_api.md#solo_objectPost) | **POST** /solo-object | Send an arbitrary JSON blob + + +# **AllOf_Get** +> models::AllOfObject AllOf_Get() + + +Test getting an object which uses allOf + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::AllOfObject**](allOfObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **dummyGet** +> dummyGet() +A dummy endpoint to make the spec valid. + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **dummyPut** +> dummyPut(nested_response) + + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **nested_response** | [**DummyPutRequest**](DummyPutRequest.md)| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **file_responseGet** +> swagger::ByteArray file_responseGet() +Get a file + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**swagger::ByteArray**](file.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **getStructuredYaml** +> models::GetYamlResponse getStructuredYaml() + + +Test returning arbitrary structured YAML + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**models::GetYamlResponse**](get_yaml_response.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/yaml + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **htmlPost** +> String htmlPost(body) +Test HTML handling + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **body** | **String**| | + +### Return type + +[**String**](string.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: text/html + - **Accept**: text/html + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **post_yaml** +> post_yaml(value) + + +Test sending an arbitrary unsupported format - e.g. YAML + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **value** | **String**| The YAML body to test | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/yaml + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **raw_jsonGet** +> serde_json::Value raw_jsonGet() +Get an arbitrary JSON blob. + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**serde_json::Value**](object.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: */* + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **solo_objectPost** +> solo_objectPost(value) +Send an arbitrary JSON blob + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **value** | **serde_json::Value**| | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/ca.pem b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/ca.pem new file mode 100644 index 000000000000..d2317fb5db7d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtjCCAZ4CCQDpKecRERZ0xDANBgkqhkiG9w0BAQsFADAdMQswCQYDVQQGEwJV +UzEOMAwGA1UEAxMFTXkgQ0EwHhcNMTcwNTIzMTYwMDIzWhcNMTcwNjIyMTYwMDIz +WjAdMQswCQYDVQQGEwJVUzEOMAwGA1UEAxMFTXkgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCt66py3x7sCSASRF2D05L5wkNDxAUjQKYx23W8Gbwv +GMGykk89BIdU5LX1JB1cKiUOkoIxfwAYuWc2V/wzTvVV7+11besnk3uX1c9KiqUF +LIX7kn/z5hzS4aelhKvH+MJlSZCSlp1ytpZbwo5GB5Pi2SGH56jDBiBoDRNBVdWL +z4wH7TdrQjqWwNxIZumD5OGMtcfJyuX08iPiEOaslOeoMqzObhvjc9aUgjVjhqyA +FkJGTXsi0oaD7oml+NE+mTNfEeZvEJQpLSjBY0OvQHzuHkyGBShBnfu/9x7/NRwd +WaqsLiF7/re9KDGYdJwP7Cu6uxYfKAyWarp6h2mG/GIdAgMBAAEwDQYJKoZIhvcN +AQELBQADggEBAGIl/VVIafeq/AJOQ9r7TzzB2ABJYr7NZa6bTu5O1jSp1Fonac15 +SZ8gvRxODgH22ZYSqghPG4xzq4J3hkytlQqm57ZEt2I2M3OqIp17Ndcc1xDYzpLl +tA0FrVn6crQTM8vQkTDtGesaCWX+7Fir5dK7HnYWzfpSmsOpST07PfbNisEXKOxG +Dj4lBL1OnhTjsJeymVS1pFvkKkrcEJO+IxFiHL3CDsWjcXB0Z+E1zBtPoYyYsNsO +rBrjUxcZewF4xqWZhpW90Mt61fY2nRgU0uUwHcvDQUqvmzKcsqYa4mPKzfBI5mxo +01Ta96cDD6pS5Y1hOflZ0g84f2g/7xBLLDA= +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/client_auth.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/client_auth.rs new file mode 100644 index 000000000000..be8520202742 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/client_auth.rs @@ -0,0 +1,17 @@ +use rust_server_test::Claims; +use jsonwebtoken::{encode, errors::Error as JwtError, Algorithm, EncodingKey, Header}; +use log::debug; + +/// build an encrypted token with the provided claims. +pub fn build_token(my_claims: Claims, key: &[u8]) -> Result { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = + Header { kid: Some("signing_key".to_owned()), alg: Algorithm::HS512, ..Default::default() }; + + let token = encode(&header, &my_claims, &EncodingKey::from_secret(key))?; + debug!("Derived token: {:?}", token); + + Ok(token) +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/main.rs new file mode 100644 index 000000000000..99939f148aff --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/client/main.rs @@ -0,0 +1,177 @@ +#![allow(missing_docs, unused_variables, trivial_casts)] + + +#[allow(unused_imports)] +use futures::{future, Stream, stream}; +#[allow(unused_imports)] +use rust_server_test::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, + AllOfGetResponse, + DummyGetResponse, + DummyPutResponse, + FileResponseGetResponse, + GetStructuredYamlResponse, + HtmlPostResponse, + PostYamlResponse, + RawJsonGetResponse, + SoloObjectPostResponse, + }; +use clap::{App, Arg}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + +#[allow(unused_imports)] +use log::info; + +// swagger::Has may be unused if there are no examples +#[allow(unused_imports)] +use swagger::{AuthData, ContextBuilder, EmptyContext, Has, Push, XSpanIdString}; + +type ClientContext = swagger::make_context_ty!(ContextBuilder, EmptyContext, Option, XSpanIdString); + +mod client_auth; +use client_auth::build_token; + + +// rt may be unused if there are no examples +#[allow(unused_mut)] +fn main() { + env_logger::init(); + + let matches = App::new("client") + .arg(Arg::with_name("operation") + .help("Sets the operation to run") + .possible_values(&[ + "AllOfGet", + "DummyGet", + "FileResponseGet", + "GetStructuredYaml", + "HtmlPost", + "PostYaml", + "RawJsonGet", + ]) + .required(true) + .index(1)) + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .arg(Arg::with_name("host") + .long("host") + .takes_value(true) + .default_value("localhost") + .help("Hostname to contact")) + .arg(Arg::with_name("port") + .long("port") + .takes_value(true) + .default_value("8080") + .help("Port to contact")) + .get_matches(); + + // Create Bearer-token with a fixed key (secret) for test purposes. + // In a real (production) system this Bearer token should be obtained via an external Identity/Authentication-server + // Ensure that you set the correct algorithm and encodingkey that matches what is used on the server side. + // See https://github.com/Keats/jsonwebtoken for more information + let auth_token = build_token( + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "my_identity_provider".to_owned(), + // added a very long expiry time + aud: "org.acme.Resource_Server".to_string(), + exp: 10000000000, + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + scopes: + "".to_owned() + }, + b"secret").unwrap(); + + let auth_data = if !auth_token.is_empty() { + Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + } else { + // No Bearer-token available, so return None + None + }; + + let is_https = matches.is_present("https"); + let base_url = format!("{}://{}:{}", + if is_https { "https" } else { "http" }, + matches.value_of("host").unwrap(), + matches.value_of("port").unwrap()); + + let context: ClientContext = + swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); + + let mut client : Box> = if matches.is_present("https") { + // Using Simple HTTPS + let client = Box::new(Client::try_new_https(&base_url) + .expect("Failed to create HTTPS client")); + Box::new(client.with_context(context)) + } else { + // Using HTTP + let client = Box::new(Client::try_new_http( + &base_url) + .expect("Failed to create HTTP client")); + Box::new(client.with_context(context)) + }; + + let mut rt = tokio::runtime::Runtime::new().unwrap(); + + match matches.value_of("operation") { + Some("AllOfGet") => { + let result = rt.block_on(client.all_of_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("DummyGet") => { + let result = rt.block_on(client.dummy_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("DummyPut") => { + let result = rt.block_on(client.dummy_put( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + Some("FileResponseGet") => { + let result = rt.block_on(client.file_response_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("GetStructuredYaml") => { + let result = rt.block_on(client.get_structured_yaml( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("HtmlPost") => { + let result = rt.block_on(client.html_post( + "body_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("PostYaml") => { + let result = rt.block_on(client.post_yaml( + "value_example".to_string() + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + Some("RawJsonGet") => { + let result = rt.block_on(client.raw_json_get( + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + /* Disabled because there's no example. + Some("SoloObjectPost") => { + let result = rt.block_on(client.solo_object_post( + ??? + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, + */ + _ => { + panic!("Invalid operation provided") + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-chain.pem b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-chain.pem new file mode 100644 index 000000000000..47d7e2014046 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-chain.pem @@ -0,0 +1,66 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4096 (0x1000) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, CN=My CA + Validity + Not Before: May 23 16:00:23 2017 GMT + Not After : Apr 29 16:00:23 2117 GMT + Subject: CN=localhost, C=US + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:d4:43:60:50:fc:d6:0f:38:4d:5d:5e:aa:7c: + c0:5e:a9:ec:d9:93:78:d3:93:72:28:41:f5:08:a5: + ea:ac:67:07:d7:1f:f7:7d:74:69:7e:46:89:20:4b: + 7a:2d:9b:02:08:e7:6f:0f:1d:0c:0f:c7:60:69:19: + 4b:df:7e:ca:75:94:0b:49:71:e3:6d:f2:e8:79:fd: + ed:0a:94:67:55:f3:ca:6b:61:ba:58:b7:2e:dd:7b: + ca:b9:02:9f:24:36:ac:26:8f:04:8f:81:c8:35:10: + f4:aa:33:b2:24:16:f8:f7:1e:ea:f7:16:fe:fa:34: + c3:dd:bb:2c:ba:7a:df:4d:e2:da:1e:e5:d2:28:44: + 6e:c8:96:e0:fd:09:0c:14:0c:31:dc:e0:ca:c1:a7: + 9b:bf:16:8c:f7:36:3f:1b:2e:dd:90:eb:45:78:51: + bf:59:22:1e:c6:8c:0a:69:88:e5:03:5e:73:b7:fc: + 93:7f:1b:46:1b:97:68:c5:c0:8b:35:1f:bb:1e:67: + 7f:55:b7:3b:55:3f:ea:f2:ca:db:cc:52:cd:16:89: + db:15:47:bd:f2:cd:6c:7a:d7:b4:1a:ac:c8:15:6c: + 6a:fb:77:c4:e9:f2:30:e0:14:24:66:65:6f:2a:e5: + 2d:cc:f6:81:ae:57:c8:d1:9b:38:90:dc:60:93:02: + 5e:cb + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 1c:7c:39:e8:3d:49:b2:09:1e:68:5a:2f:74:18:f4:63:b5:8c: + f6:e6:a1:e3:4d:95:90:99:ef:32:5c:34:40:e8:55:13:0e:e0: + 1c:be:cd:ab:3f:64:38:99:5e:2b:c1:81:53:a0:18:a8:f6:ee: + 6a:33:73:6c:9a:73:9d:86:08:5d:c7:11:38:46:4c:cd:a0:47: + 37:8f:fe:a6:50:a9:02:21:99:42:86:5e:47:fe:65:56:60:1d: + 16:53:86:bd:e4:63:c5:69:cf:fa:30:51:ab:a1:c3:50:53:cc: + 66:1c:4c:ff:3f:2a:39:4d:a2:8f:9d:d1:a7:8b:22:e4:78:69: + 24:06:83:4d:cc:0a:c0:87:69:9b:bc:80:a9:d2:b7:a5:23:84: + 7e:a2:32:26:7c:78:0e:bd:db:cd:3b:69:18:33:b8:44:ef:96: + b4:99:86:ee:06:bd:51:1c:c7:a1:a4:0c:c4:4c:51:a0:df:ac: + 14:07:88:8e:d7:39:45:fe:52:e0:a3:4c:db:5d:7a:ab:4d:e4: + ca:06:e8:bd:74:6f:46:e7:93:4a:4f:1b:67:e7:a5:9f:ef:9c: + 02:49:d1:f2:d5:e9:53:ee:09:21:ac:08:c8:15:f7:af:35:b9: + 4f:11:0f:43:ae:46:8e:fd:5b:8d:a3:4e:a7:2c:b7:25:ed:e4: + e5:94:1d:e3 +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CAhAAMA0GCSqGSIb3DQEBCwUAMB0xCzAJBgNVBAYTAlVTMQ4wDAYD +VQQDEwVNeSBDQTAgFw0xNzA1MjMxNjAwMjNaGA8yMTE3MDQyOTE2MDAyM1owITES +MBAGA1UEAxMJbG9jYWxob3N0MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMnUQ2BQ/NYPOE1dXqp8wF6p7NmTeNOTcihB9Qil6qxn +B9cf9310aX5GiSBLei2bAgjnbw8dDA/HYGkZS99+ynWUC0lx423y6Hn97QqUZ1Xz +ymthuli3Lt17yrkCnyQ2rCaPBI+ByDUQ9KozsiQW+Pce6vcW/vo0w927LLp6303i +2h7l0ihEbsiW4P0JDBQMMdzgysGnm78WjPc2Pxsu3ZDrRXhRv1kiHsaMCmmI5QNe +c7f8k38bRhuXaMXAizUfux5nf1W3O1U/6vLK28xSzRaJ2xVHvfLNbHrXtBqsyBVs +avt3xOnyMOAUJGZlbyrlLcz2ga5XyNGbOJDcYJMCXssCAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAHHw56D1JsgkeaFovdBj0Y7WM9uah402VkJnvMlw0QOhVEw7gHL7N +qz9kOJleK8GBU6AYqPbuajNzbJpznYYIXccROEZMzaBHN4/+plCpAiGZQoZeR/5l +VmAdFlOGveRjxWnP+jBRq6HDUFPMZhxM/z8qOU2ij53Rp4si5HhpJAaDTcwKwIdp +m7yAqdK3pSOEfqIyJnx4Dr3bzTtpGDO4RO+WtJmG7ga9URzHoaQMxExRoN+sFAeI +jtc5Rf5S4KNM2116q03kygbovXRvRueTSk8bZ+eln++cAknR8tXpU+4JIawIyBX3 +rzW5TxEPQ65Gjv1bjaNOpyy3Je3k5ZQd4w== +-----END CERTIFICATE----- diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-key.pem b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-key.pem new file mode 100644 index 000000000000..29c006829229 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDJ1ENgUPzWDzhN +XV6qfMBeqezZk3jTk3IoQfUIpeqsZwfXH/d9dGl+RokgS3otmwII528PHQwPx2Bp +GUvffsp1lAtJceNt8uh5/e0KlGdV88prYbpYty7de8q5Ap8kNqwmjwSPgcg1EPSq +M7IkFvj3Hur3Fv76NMPduyy6et9N4toe5dIoRG7IluD9CQwUDDHc4MrBp5u/Foz3 +Nj8bLt2Q60V4Ub9ZIh7GjAppiOUDXnO3/JN/G0Ybl2jFwIs1H7seZ39VtztVP+ry +ytvMUs0WidsVR73yzWx617QarMgVbGr7d8Tp8jDgFCRmZW8q5S3M9oGuV8jRmziQ +3GCTAl7LAgMBAAECggEBAKEd1q9j14KWYc64s6KLthGbutyxsinMMbxbct11fdIk +6YhdF3fJ35ETg9IJDr6rWEN9ZRX+jStncNpVfFEs6ThVd3Eo/nI+EEGaaIkikR93 +X2a7fEPn7/yVHu70XdBN6L1bPDvHUeiy4W2hmRrgT90OjGm1rNRWHOm7yugOwIZu +HclzbR9Ca7EInFnotUiDQm9sw9VKHbJHqWx6OORdZrxR2ytYs0Qkq0XpGMvti2HW +7WAmKTg5QM8myXW7+/4iqb/u68wVBR2BBalShKmIf7lim9O3W2a1RjDdsvm/wNe9 +I+D+Iq825vpqkKXcrxYlpVg7hYiaQaW/MNsEb7lQRjECgYEA/RJYby0POW+/k0Jn +jO8UmJVEMiuGa8WIUu/JJWMOmzRCukjSRNQOkt7niQrZPJYE8W6clM6RJTolWf9L +IL6mIb+mRaoudUk8SHGDq7ho1iMg9GK8lhYxvKh1Q6uv8EyVSkgLknAEY0NANKC1 +zNdU5Dhven9aRX2gq9vP4XwMz2MCgYEAzCogQ7IFk+gkp3k491dOZnrGRoRCfuzo +4CJtyKFgOSd7BjmpcKkj0IPfVBjw6GjMIxfQRMTQmxAjjWevH45vG8l0Iiwz/gSp +81b5nsDEX5uv2Olcmcz5zxRFy36jOZ9ihMWinxcIlT2oDbyCdbruDKZq9ieJ9S8g +4qGx0OkwE3kCgYEA7CmAiU89U9YqqttfEq/RQoqY91CSwmO10d+ej9seuEtOsdRf +FIfnibulycdr7hP5TOxyBpO1802NqayJiWcgVYIpQf2MGTtcnCYCP+95NcvWZvj1 +EAJqK6nwtFO1fcOZ1ZXh5qfOEGujsPkAbsXLnKXlsiTCMvMHSxl3pu5Cbg0CgYBf +JjbZNctRrjv+7Qj2hPLd4dQsIxGWc7ToWENP4J2mpVa5hQAJqFovoHXhjKohtk2F +AWEn243Y5oGbMjo0e74edhmwn2cvuF64MM2vBem/ISCn98IXT6cQskMA3qkVfsl8 +VVs/x41ReGWs2TD3y0GMFbb9t1mdMfSiincDhNnKCQKBgGfeT4jKyYeCoCw4OLI1 +G75Gd0METt/IkppwODPpNwj3Rp9I5jctWZFA/3wCX/zk0HgBeou5AFNS4nQZ/X/L +L9axbSdR7UJTGkT1r4gu3rLkPV4Tk+8XM03/JT2cofMlzQBuhvl1Pn4SgKowz7hl +lS76ECw4Av3T0S34VW9Z5oye +-----END PRIVATE KEY----- diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/main.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/main.rs new file mode 100644 index 000000000000..7492252060e2 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/main.rs @@ -0,0 +1,28 @@ +//! Main binary entry point for rust_server_test implementation. +// This is the amended version that adds Authorization via Inversion of Control. + +#![allow(missing_docs)] + + +use clap::{App, Arg}; + +mod server; +mod server_auth; + + +/// Create custom server, wire it to the autogenerated router, +/// and pass it to the web server. +#[tokio::main] +async fn main() { + env_logger::init(); + + let matches = App::new("server") + .arg(Arg::with_name("https") + .long("https") + .help("Whether to use HTTPS or not")) + .get_matches(); + + let addr = "127.0.0.1:8080"; + + server::create(addr, matches.is_present("https")).await; +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server.rs new file mode 100644 index 000000000000..00240b2ecdce --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server.rs @@ -0,0 +1,203 @@ +//! Main library entry point for rust_server_test implementation. + +#![allow(unused_imports)] + +use async_trait::async_trait; +use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; +use hyper::server::conn::Http; +use hyper::service::Service; +use log::info; +use std::future::Future; +use std::marker::PhantomData; +use std::net::SocketAddr; +use std::sync::{Arc, Mutex}; +use std::task::{Context, Poll}; +use swagger::{Has, XSpanIdString}; +use swagger::auth::MakeAllowAllAuthenticator; +use swagger::EmptyContext; +use tokio::net::TcpListener; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +use openssl::ssl::{Ssl, SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; + +use rust_server_test::models; + +/// Builds an SSL implementation for Simple HTTPS from some hard-coded file names +pub async fn create(addr: &str, https: bool) { + let addr = addr.parse().expect("Failed to parse bind address"); + + let server = Server::new(); + + let service = MakeService::new(server); + + let service = MakeAllowAllAuthenticator::new(service, "cosmo"); + + #[allow(unused_mut)] + let mut service = + rust_server_test::server::context::MakeAddContext::<_, EmptyContext>::new( + service + ); + + if https { + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + { + unimplemented!("SSL is not implemented for the examples on MacOS, Windows or iOS"); + } + + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + { + let mut ssl = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).expect("Failed to create SSL Acceptor"); + + // Server authentication + ssl.set_private_key_file("examples/server-key.pem", SslFiletype::PEM).expect("Failed to set private key"); + ssl.set_certificate_chain_file("examples/server-chain.pem").expect("Failed to set certificate chain"); + ssl.check_private_key().expect("Failed to check private key"); + + let tls_acceptor = ssl.build(); + let tcp_listener = TcpListener::bind(&addr).await.unwrap(); + + info!("Starting a server (with https)"); + loop { + if let Ok((tcp, _)) = tcp_listener.accept().await { + let ssl = Ssl::new(tls_acceptor.context()).unwrap(); + let addr = tcp.peer_addr().expect("Unable to get remote address"); + let service = service.call(addr); + + tokio::spawn(async move { + let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; + let service = service.await.map_err(|_| ())?; + + Http::new() + .serve_connection(tls, service) + .await + .map_err(|_| ()) + }); + } + } + } + } else { + info!("Starting a server (over http, so no TLS)"); + // Using HTTP + hyper::server::Server::bind(&addr).serve(service).await.unwrap() + } +} + +#[derive(Copy, Clone)] +pub struct Server { + marker: PhantomData, +} + +impl Server { + pub fn new() -> Self { + Server{marker: PhantomData} + } +} + + +use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; +use serde::{Deserialize, Serialize}; +use swagger::auth::Authorization; +use crate::server_auth; + + +use rust_server_test::{ + Api, + AllOfGetResponse, + DummyGetResponse, + DummyPutResponse, + FileResponseGetResponse, + GetStructuredYamlResponse, + HtmlPostResponse, + PostYamlResponse, + RawJsonGetResponse, + SoloObjectPostResponse, +}; +use rust_server_test::server::MakeService; +use std::error::Error; +use swagger::ApiError; + +#[async_trait] +impl Api for Server where C: Has + Send + Sync +{ + async fn all_of_get( + &self, + context: &C) -> Result + { + info!("all_of_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// A dummy endpoint to make the spec valid. + async fn dummy_get( + &self, + context: &C) -> Result + { + info!("dummy_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn dummy_put( + &self, + nested_response: models::DummyPutRequest, + context: &C) -> Result + { + info!("dummy_put({:?}) - X-Span-ID: {:?}", nested_response, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Get a file + async fn file_response_get( + &self, + context: &C) -> Result + { + info!("file_response_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn get_structured_yaml( + &self, + context: &C) -> Result + { + info!("get_structured_yaml() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Test HTML handling + async fn html_post( + &self, + body: String, + context: &C) -> Result + { + info!("html_post(\"{}\") - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + async fn post_yaml( + &self, + value: String, + context: &C) -> Result + { + info!("post_yaml(\"{}\") - X-Span-ID: {:?}", value, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Get an arbitrary JSON blob. + async fn raw_json_get( + &self, + context: &C) -> Result + { + info!("raw_json_get() - X-Span-ID: {:?}", context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + + /// Send an arbitrary JSON blob + async fn solo_object_post( + &self, + value: serde_json::Value, + context: &C) -> Result + { + info!("solo_object_post({:?}) - X-Span-ID: {:?}", value, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server_auth.rs new file mode 100644 index 000000000000..3191e2f7dcb9 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/examples/server/server_auth.rs @@ -0,0 +1,127 @@ +use swagger::{ + ApiError, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; +use rust_server_test::{AuthenticationApi, Claims}; +use crate::server::Server; +use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; +use swagger::auth::Authorization; +use log::{error, debug}; + +// NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. +// See https://docs.rs/env_logger/latest/env_logger/ for more details + + +/// Get a dummy claim with full permissions (all scopes) for testing purposes +fn full_permission_claim() -> Claims { + // In this example code all available Scopes are added, so the current Bearer Token gets fully authorization. + Claims { + sub: "tester@acme.com".to_owned(), + company: "ACME".to_owned(), + iss: "mini-bank-IDP".to_owned(), + aud: "org.acme.Resource_Server".to_string(), + // added a very long expiry time + exp: 10000000000, + scopes: + "".to_owned() + } +} + + + +/// Extract the data from a Bearer token using the provided Key (secret) and using the HS512-algorithm in this example. +fn extract_token_data(token: &str, key: &[u8]) -> Result, JwtError::Error> { + + // Ensure that you set the correct algorithm and correct key. + // See https://github.com/Keats/jsonwebtoken for more information. + let header = decode_header(token)?; + let validation = { + let mut validation = Validation::new(header.alg); + validation.set_audience(&["org.acme.Resource_Server"]); + validation.validate_exp = true; + validation + }; + + let token_data = decode::( + &token, + &DecodingKey::from_secret(key), + &validation, + )?; + + Ok(token_data) +} + +/// Build a swagger-Authorization based on the claims (Assuming claims have been extracted from a validated token) +fn build_authorization(claims: Claims) -> Authorization { + let mut scopes = std::collections::BTreeSet::::new(); + claims + .scopes + .split(",") + .map(|s| s.trim()) + .for_each(|s| {let _ = scopes.insert(s.to_string()); }); + let scopes = swagger::auth::Scopes::Some(scopes); + + Authorization{ + subject: claims.sub, + scopes, + issuer: Some(claims.iss)} +} + +fn get_jwt_error_string(error: JwtError::Error) -> String { + match error.kind() { + JwtError::ErrorKind::InvalidSignature => "Incorrect token signature".to_owned(), + JwtError::ErrorKind::InvalidAlgorithm => "The Algorithm is not correct".to_owned(), + JwtError::ErrorKind::ExpiredSignature => "The token has expired".to_owned(), + JwtError::ErrorKind::Base64(e) => format!("Base64 decode failed: {e}"), + JwtError::ErrorKind::Json(e) => format!("JSON decoding: {e}"), + JwtError::ErrorKind::Utf8(e) => format!("Invalid UTF-8: {e}"), + _ => error.to_string() + } +} + + +impl AuthenticationApi for Server where C: Has + Send + Sync { + + /// Implementation of the method to map a Bearer-token to an Authorization + fn bearer_authorization(&self, bearer: &Bearer) -> Result { + debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); + + match extract_token_data(&bearer.token, b"secret") { + Ok(auth_data) => { + debug!("\tUnpack auth_data as: {auth_data:#?}"); + let authorization = build_authorization(auth_data.claims); + Ok(authorization) + }, + Err(err) => { + let msg = get_jwt_error_string(err); + error!("Failed to unpack Bearer-token: {msg}"); + Err(ApiError(msg)) + } + } + } + + /// Implementation of the method to map an api-key to an Authorization + fn apikey_authorization(&self, api_key: &str) -> Result { + debug!("\tAuthorizationApi: Received api-key, {api_key:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + + /// Implementation of the method to map a basic authentication (username and password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result { + debug!("\tAuthorizationApi: Received Basic-token, {basic:#?}"); + + // TODO: insert the logic to map received apikey to the set of claims + let claims = full_permission_claim(); + + // and build an authorization out of it + Ok(build_authorization(claims)) + } + +} + diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/auth.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/auth.rs new file mode 100644 index 000000000000..d2b1481eeb81 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/auth.rs @@ -0,0 +1,62 @@ +use std::collections::BTreeSet; +use crate::server::Authorization; +use serde::{Deserialize, Serialize}; +use swagger::{ApiError, auth::{Basic, Bearer}}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Claims { + pub sub: String, + pub iss: String, + pub aud: String, + pub company: String, + pub exp: u64, + pub scopes: String, +} + + +pub trait AuthenticationApi { + + /// Method should be implemented (see example-code) to map Bearer-token to an Authorization + fn bearer_authorization(&self, token: &Bearer) -> Result; + + /// Method should be implemented (see example-code) to map ApiKey to an Authorization + fn apikey_authorization(&self, token: &str) -> Result; + + /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization + fn basic_authorization(&self, basic: &Basic) -> Result; +} + +// Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) +use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; + +fn dummy_authorization() -> Authorization { + // Is called when MakeAllowAllAuthenticator is added to the stack. This is not needed as we have Bearer-authorization in the example-code. + // However, if you want to use it anyway this can not be unimplemented, so dummy implementation added. + // unimplemented!() + Authorization{ + subject: "Dummy".to_owned(), + scopes: Scopes::Some(BTreeSet::new()), // create an empty scope, as this should not be used + issuer: None + } +} + +impl AuthenticationApi for AllowAllAuthenticator +where + RC: RcBound, + RC::Result: Send + 'static { + + /// Get method to map Bearer-token to an Authorization + fn bearer_authorization(&self, _token: &Bearer) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map api-key to an Authorization + fn apikey_authorization(&self, _apikey: &str) -> Result { + Ok(dummy_authorization()) + } + + /// Get method to map basic token to an Authorization + fn basic_authorization(&self, _basic: &Basic) -> Result { + Ok(dummy_authorization()) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/client/mod.rs new file mode 100644 index 000000000000..555113f36ca6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/client/mod.rs @@ -0,0 +1,1097 @@ +#![allow(clippy::clone_on_copy)] +#![allow(clippy::vec_init_then_push)] +use async_trait::async_trait; +use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use hyper::{Body, Request, Response, service::Service, Uri}; +use percent_encoding::{utf8_percent_encode, AsciiSet}; +use std::borrow::Cow; +use std::convert::TryInto; +use std::io::{ErrorKind, Read}; +use std::error::Error; +use std::future::Future; +use std::fmt; +use std::marker::PhantomData; +use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::str; +use std::str::FromStr; +use std::string::ToString; +use std::task::{Context, Poll}; +use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; +use url::form_urlencoded; + + +use crate::models; +use crate::header; + +/// https://url.spec.whatwg.org/#fragment-percent-encode-set +#[allow(dead_code)] +const FRAGMENT_ENCODE_SET: &AsciiSet = &percent_encoding::CONTROLS + .add(b' ').add(b'"').add(b'<').add(b'>').add(b'`'); + +/// This encode set is used for object IDs +/// +/// Aside from the special characters defined in the `PATH_SEGMENT_ENCODE_SET`, +/// the vertical bar (|) is encoded. +#[allow(dead_code)] +const ID_ENCODE_SET: &AsciiSet = &FRAGMENT_ENCODE_SET.add(b'|'); + +use crate::{Api, + AllOfGetResponse, + DummyGetResponse, + DummyPutResponse, + FileResponseGetResponse, + GetStructuredYamlResponse, + HtmlPostResponse, + PostYamlResponse, + RawJsonGetResponse, + SoloObjectPostResponse + }; + +/// Convert input into a base path, e.g. "http://example:123". Also checks the scheme as it goes. +fn into_base_path(input: impl TryInto, correct_scheme: Option<&'static str>) -> Result { + // First convert to Uri, since a base path is a subset of Uri. + let uri = input.try_into()?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + + // Check the scheme if necessary + if let Some(correct_scheme) = correct_scheme { + if scheme != correct_scheme { + return Err(ClientInitError::InvalidScheme); + } + } + + let host = uri.host().ok_or(ClientInitError::MissingHost)?; + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) +} + +/// A client that implements the API by making HTTP calls out to a server. +pub struct Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Inner service + client_service: S, + + /// Base path of the API + base_path: String, + + /// Marker + marker: PhantomData, +} + +impl fmt::Debug for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Client {{ base_path: {} }}", self.base_path) + } +} + +impl Clone for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + client_service: self.client_service.clone(), + base_path: self.base_path.clone(), + marker: PhantomData, + } + } +} + +impl Client, C>, C> where + Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, + C: Clone + Send + Sync + 'static, +{ + /// Create a client with a custom implementation of hyper::client::Connect. + /// + /// Intended for use with custom implementations of connect for e.g. protocol logging + /// or similar functionality which requires wrapping the transport layer. When wrapping a TCP connection, + /// this function should be used in conjunction with `swagger::Connector::builder()`. + /// + /// For ordinary tcp connections, prefer the use of `try_new_http`, `try_new_https` + /// and `try_new_https_mutual`, to avoid introducing a dependency on the underlying transport layer. + /// + /// # Arguments + /// + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` + /// * `connector` - Implementation of `hyper::client::Connect` to use for the client + pub fn try_new_with_connector( + base_path: &str, + protocol: Option<&'static str>, + connector: Connector, + ) -> Result + { + let client_service = hyper::client::Client::builder().build(connector); + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, protocol)?, + marker: PhantomData, + }) + } +} + +#[derive(Debug, Clone)] +pub enum HyperClient { + Http(hyper::client::Client), + Https(hyper::client::Client), +} + +impl Service> for HyperClient { + type Response = Response; + type Error = hyper::Error; + type Future = hyper::client::ResponseFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + match self { + HyperClient::Http(client) => client.poll_ready(cx), + HyperClient::Https(client) => client.poll_ready(cx), + } + } + + fn call(&mut self, req: Request) -> Self::Future { + match self { + HyperClient::Http(client) => client.call(req), + HyperClient::Https(client) => client.call(req) + } + } +} + +impl Client, C> where + C: Clone + Send + Sync + 'static, +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new( + base_path: &str, + ) -> Result { + let uri = Uri::from_str(base_path)?; + + let scheme = uri.scheme_str().ok_or(ClientInitError::InvalidScheme)?; + let scheme = scheme.to_ascii_lowercase(); + + let connector = Connector::builder(); + + let client_service = match scheme.as_str() { + "http" => { + HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + }, + "https" => { + let connector = connector.https() + .build() + .map_err(ClientInitError::SslError)?; + HyperClient::Https(hyper::client::Client::builder().build(connector)) + }, + _ => { + return Err(ClientInitError::InvalidScheme); + } + }; + + let client_service = DropContextService::new(client_service); + + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create an HTTP client. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + pub fn try_new_http( + base_path: &str, + ) -> Result { + let http_connector = Connector::builder().build(); + + Self::try_new_with_connector(base_path, Some("http"), http_connector) + } +} + +#[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] +type HttpsConnector = hyper_tls::HttpsConnector; + +#[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] +type HttpsConnector = hyper_openssl::HttpsConnector; + +impl Client, C>, C> where + C: Clone + Send + Sync + 'static +{ + /// Create a client with a TLS connection to the server + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + pub fn try_new_https(base_path: &str) -> Result + { + let https_connector = Connector::builder() + .https() + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a TLS connection to the server using a pinned certificate + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_pinned( + base_path: &str, + ca_certificate: CA, + ) -> Result + where + CA: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } + + /// Create a client with a mutually authenticated TLS connection to the server. + /// + /// # Arguments + /// * `base_path` - base path of the client API, i.e. "" + /// * `ca_certificate` - Path to CA certificate used to authenticate the server + /// * `client_key` - Path to the client private key + /// * `client_certificate` - Path to the client's public certificate associated with the private key + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + pub fn try_new_https_mutual( + base_path: &str, + ca_certificate: CA, + client_key: K, + client_certificate: D, + ) -> Result + where + CA: AsRef, + K: AsRef, + D: AsRef, + { + let https_connector = Connector::builder() + .https() + .pin_server_certificate(ca_certificate) + .client_authentication(client_key, client_certificate) + .build() + .map_err(ClientInitError::SslError)?; + Self::try_new_with_connector(base_path, Some("https"), https_connector) + } +} + +impl Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Clone + Send + Sync + 'static +{ + /// Constructor for creating a `Client` by passing in a pre-made `hyper::service::Service` / + /// `tower::Service` + /// + /// This allows adding custom wrappers around the underlying transport, for example for logging. + pub fn try_new_with_client_service( + client_service: S, + base_path: &str, + ) -> Result + { + Ok(Self { + client_service, + base_path: into_base_path(base_path, None)?, + marker: PhantomData, + }) + } +} + +/// Error type failing to create a Client +#[derive(Debug)] +pub enum ClientInitError { + /// Invalid URL Scheme + InvalidScheme, + + /// Invalid URI + InvalidUri(hyper::http::uri::InvalidUri), + + /// Missing Hostname + MissingHost, + + /// SSL Connection Error + #[cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))] + SslError(native_tls::Error), + + /// SSL Connection Error + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] + SslError(openssl::error::ErrorStack), +} + +impl From for ClientInitError { + fn from(err: hyper::http::uri::InvalidUri) -> ClientInitError { + ClientInitError::InvalidUri(err) + } +} + +impl fmt::Display for ClientInitError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s: &dyn fmt::Debug = self; + s.fmt(f) + } +} + +impl Error for ClientInitError { + fn description(&self) -> &str { + "Failed to produce a hyper client." + } +} + +#[async_trait] +impl Api for Client where + S: Service< + (Request, C), + Response=Response> + Clone + Sync + Send + 'static, + S::Future: Send + 'static, + S::Error: Into + fmt::Display, + C: Has + Clone + Send + Sync + 'static, +{ + fn poll_ready(&self, cx: &mut Context) -> Poll> { + match self.client_service.clone().poll_ready(cx) { + Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), + Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), + Poll::Pending => Poll::Pending, + } + } + + async fn all_of_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/allOf", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(AllOfGetResponse::OK + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn dummy_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/dummy", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + DummyGetResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn dummy_put( + &self, + param_nested_response: models::DummyPutRequest, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/dummy", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("PUT") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_nested_response).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + Ok( + DummyPutResponse::Success + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn file_response_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/file_response", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(FileResponseGetResponse::Success + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn get_structured_yaml( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/get-structured-yaml", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = body.to_string(); + + + Ok(GetStructuredYamlResponse::OK + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn html_post( + &self, + param_body: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/html", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = param_body; + *request.body_mut() = Body::from(body); + + let header = "text/html"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = body.to_string(); + + + Ok(HtmlPostResponse::Success + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn post_yaml( + &self, + param_value: String, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/post-yaml", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = param_value; + *request.body_mut() = Body::from(body); + + let header = "application/yaml"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + PostYamlResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn raw_json_get( + &self, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/raw_json", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = body + .into_raw() + .map_err(|e| ApiError(format!("Failed to read response: {e}"))).await?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(RawJsonGetResponse::Success + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + + async fn solo_object_post( + &self, + param_value: serde_json::Value, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/solo-object", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("POST") + .uri(uri) + .body(Body::empty()) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + let body = serde_json::to_string(¶m_value).expect("impossible to fail to serialize"); + *request.body_mut() = Body::from(body); + + let header = "application/json"; + request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) + }); + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 204 => { + Ok( + SoloObjectPostResponse::OK + ) + } + code => { + let headers = response.headers().clone(); + let body = response.into_body() + .take(100) + .into_raw().await; + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!(""), + } + ))) + } + } + } + +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/context.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/context.rs new file mode 100644 index 000000000000..ee8e118587bb --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/context.rs @@ -0,0 +1,114 @@ +use futures::future::BoxFuture; +use hyper::header::HeaderName; +use hyper::{Error, Request, Response, StatusCode, service::Service}; +use url::form_urlencoded; +use std::default::Default; +use std::io; +use std::marker::PhantomData; +use std::task::{Poll, Context}; +use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; +use crate::{Api, AuthenticationApi}; +use log::error; + +pub struct MakeAddContext { + inner: T, + marker: PhantomData, +} + +impl MakeAddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> MakeAddContext { + MakeAddContext { + inner, + marker: PhantomData, + } + } +} + +// Make a service that adds context. +impl Service for + MakeAddContext +where + Target: Send, + A: Default + Push + Send, + B: Push, Result = C>, + C: Push, Result = D>, + D: Send + 'static, + T: Service + Send, + T::Future: Send + 'static +{ + type Error = T::Error; + type Response = AddContext; + type Future = BoxFuture<'static, Result>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = self.inner.call(target); + + Box::pin(async move { + Ok(AddContext::new(service.await?)) + }) + } +} + +/// Middleware to add context data from the request +pub struct AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D> +{ + inner: T, + marker: PhantomData, +} + +impl AddContext +where + A: Default + Push, + B: Push, Result = C>, + C: Push, Result = D>, +{ + pub fn new(inner: T) -> Self { + AddContext { + inner, + marker: PhantomData, + } + } +} + +impl Service> for AddContext + where + A: Default + Push, + B: Push, Result=C>, + C: Push, Result=D>, + D: Send + 'static, + T: Service<(Request, D)> + AuthenticationApi +{ + type Error = T::Error; + type Future = T::Future; + type Response = T::Response; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + + fn call(&mut self, request: Request) -> Self::Future { + let context = A::default().push(XSpanIdString::get_or_generate(&request)); + let headers = request.headers(); + + + let context = context.push(None::); + let context = context.push(None::); + + self.inner.call((request, context)) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/header.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/header.rs new file mode 100644 index 000000000000..571ad3cf51bf --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/header.rs @@ -0,0 +1,169 @@ +use chrono::{DateTime, Utc}; +use hyper::header::HeaderValue; +use std::convert::TryFrom; +use std::fmt; +use std::ops::Deref; + +/// A struct to allow homogeneous conversion into a HeaderValue. We can't +/// implement the From/Into trait on HeaderValue because we don't own +/// either of the types. +#[derive(Debug, Clone)] +pub(crate) struct IntoHeaderValue(pub T); + +// Generic implementations + +impl Deref for IntoHeaderValue { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +// Derive for each TryFrom in hyper::header::HeaderValue + +macro_rules! ihv_generate { + ($t:ident) => { + impl TryFrom for IntoHeaderValue<$t> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse::<$t>() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse {} as a string: {}", + stringify!($t), e)), + }, + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), + } + } + } + + impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue<$t>) -> Result { + Ok(hdr_value.0.into()) + } + } + }; +} + +ihv_generate!(u64); +ihv_generate!(i64); +ihv_generate!(i16); +ihv_generate!(u16); +ihv_generate!(u32); +ihv_generate!(usize); +ihv_generate!(isize); +ihv_generate!(i32); + +// Custom derivations + +// Vec + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue( + hdr_value + .split(',') + .filter_map(|x| match x.trim() { + "" => None, + y => Some(y.to_string()), + }) + .collect())), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(&hdr_value.0.join(", ")) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) + } + } +} + +// String + +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) + } + } +} + +// bool +impl TryFrom for IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match hdr_value.parse() { + Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), + }, + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), + } + } +} + +impl TryFrom> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue) -> Result { + match HeaderValue::from_str(&hdr_value.0.to_string()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) + } + } +} + +// DateTime + +impl TryFrom for IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_value: HeaderValue) -> Result { + match hdr_value.to_str() { + Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { + Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), + }, + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), + } + } +} + +impl TryFrom>> for HeaderValue { + type Error = String; + + fn try_from(hdr_value: IntoHeaderValue>) -> Result { + match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { + Ok(hdr_value) => Ok(hdr_value), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/lib.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/lib.rs new file mode 100644 index 000000000000..3adabd148d80 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/lib.rs @@ -0,0 +1,320 @@ +#![allow(missing_docs, trivial_casts, unused_variables, unused_mut, unused_imports, unused_extern_crates, unused_attributes, non_camel_case_types)] +#![allow(clippy::derive_partial_eq_without_eq, clippy::disallowed_names)] + +use async_trait::async_trait; +use futures::Stream; +use std::error::Error; +use std::collections::BTreeSet; +use std::task::{Poll, Context}; +use swagger::{ApiError, ContextWrapper}; +use serde::{Serialize, Deserialize}; +use crate::server::Authorization; + + +type ServiceError = Box; + +pub const BASE_PATH: &str = ""; +pub const API_VERSION: &str = "2.3.4"; + +mod auth; +pub use auth::{AuthenticationApi, Claims}; + + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum AllOfGetResponse { + /// OK + OK + (models::AllOfObject) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum DummyGetResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum DummyPutResponse { + /// Success + Success +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum FileResponseGetResponse { + /// Success + Success + (swagger::ByteArray) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum GetStructuredYamlResponse { + /// OK + OK + (String) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum HtmlPostResponse { + /// Success + Success + (String) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum PostYamlResponse { + /// OK + OK +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum RawJsonGetResponse { + /// Success + Success + (serde_json::Value) +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum SoloObjectPostResponse { + /// OK + OK +} + +/// API +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait Api { + fn poll_ready(&self, _cx: &mut Context) -> Poll>> { + Poll::Ready(Ok(())) + } + + async fn all_of_get( + &self, + context: &C) -> Result; + + /// A dummy endpoint to make the spec valid. + async fn dummy_get( + &self, + context: &C) -> Result; + + async fn dummy_put( + &self, + nested_response: models::DummyPutRequest, + context: &C) -> Result; + + /// Get a file + async fn file_response_get( + &self, + context: &C) -> Result; + + async fn get_structured_yaml( + &self, + context: &C) -> Result; + + /// Test HTML handling + async fn html_post( + &self, + body: String, + context: &C) -> Result; + + async fn post_yaml( + &self, + value: String, + context: &C) -> Result; + + /// Get an arbitrary JSON blob. + async fn raw_json_get( + &self, + context: &C) -> Result; + + /// Send an arbitrary JSON blob + async fn solo_object_post( + &self, + value: serde_json::Value, + context: &C) -> Result; + +} + +/// API where `Context` isn't passed on every API call +#[async_trait] +#[allow(clippy::too_many_arguments, clippy::ptr_arg)] +pub trait ApiNoContext { + + fn poll_ready(&self, _cx: &mut Context) -> Poll>>; + + fn context(&self) -> &C; + + async fn all_of_get( + &self, + ) -> Result; + + /// A dummy endpoint to make the spec valid. + async fn dummy_get( + &self, + ) -> Result; + + async fn dummy_put( + &self, + nested_response: models::DummyPutRequest, + ) -> Result; + + /// Get a file + async fn file_response_get( + &self, + ) -> Result; + + async fn get_structured_yaml( + &self, + ) -> Result; + + /// Test HTML handling + async fn html_post( + &self, + body: String, + ) -> Result; + + async fn post_yaml( + &self, + value: String, + ) -> Result; + + /// Get an arbitrary JSON blob. + async fn raw_json_get( + &self, + ) -> Result; + + /// Send an arbitrary JSON blob + async fn solo_object_post( + &self, + value: serde_json::Value, + ) -> Result; + +} + +/// Trait to extend an API to make it easy to bind it to a context. +pub trait ContextWrapperExt where Self: Sized +{ + /// Binds this API to a context. + fn with_context(self, context: C) -> ContextWrapper; +} + +impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T { + fn with_context(self: T, context: C) -> ContextWrapper { + ContextWrapper::::new(self, context) + } +} + +#[async_trait] +impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { + fn poll_ready(&self, cx: &mut Context) -> Poll> { + self.api().poll_ready(cx) + } + + fn context(&self) -> &C { + ContextWrapper::context(self) + } + + async fn all_of_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().all_of_get(&context).await + } + + /// A dummy endpoint to make the spec valid. + async fn dummy_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().dummy_get(&context).await + } + + async fn dummy_put( + &self, + nested_response: models::DummyPutRequest, + ) -> Result + { + let context = self.context().clone(); + self.api().dummy_put(nested_response, &context).await + } + + /// Get a file + async fn file_response_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().file_response_get(&context).await + } + + async fn get_structured_yaml( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().get_structured_yaml(&context).await + } + + /// Test HTML handling + async fn html_post( + &self, + body: String, + ) -> Result + { + let context = self.context().clone(); + self.api().html_post(body, &context).await + } + + async fn post_yaml( + &self, + value: String, + ) -> Result + { + let context = self.context().clone(); + self.api().post_yaml(value, &context).await + } + + /// Get an arbitrary JSON blob. + async fn raw_json_get( + &self, + ) -> Result + { + let context = self.context().clone(); + self.api().raw_json_get(&context).await + } + + /// Send an arbitrary JSON blob + async fn solo_object_post( + &self, + value: serde_json::Value, + ) -> Result + { + let context = self.context().clone(); + self.api().solo_object_post(value, &context).await + } + +} + + +#[cfg(feature = "client")] +pub mod client; + +// Re-export Client as a top-level name +#[cfg(feature = "client")] +pub use client::Client; + +#[cfg(feature = "server")] +pub mod server; + +// Re-export router() as a top-level name +#[cfg(feature = "server")] +pub use self::server::Service; + +#[cfg(feature = "server")] +pub mod context; + +pub mod models; + +#[cfg(any(feature = "client", feature = "server"))] +pub(crate) mod header; diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/models.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/models.rs new file mode 100644 index 000000000000..08d58d11ce8b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/models.rs @@ -0,0 +1,1307 @@ +#![allow(unused_qualifications)] +#![allow(clippy::to_string_trait_impl)] + +use validator::Validate; + +use crate::models; +#[cfg(any(feature = "client", feature = "server"))] +use crate::header; + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ANullableContainer { + #[serde(rename = "NullableThing")] + #[serde(deserialize_with = "swagger::nullable_format::deserialize_optional_nullable")] + #[serde(default = "swagger::nullable_format::default_optional_nullable")] + #[serde(skip_serializing_if="Option::is_none")] + pub nullable_thing: Option>, + + #[serde(rename = "RequiredNullableThing")] + pub required_nullable_thing: swagger::Nullable, + +} + + +impl ANullableContainer { + #[allow(clippy::new_without_default)] + pub fn new(required_nullable_thing: swagger::Nullable, ) -> ANullableContainer { + ANullableContainer { + nullable_thing: None, + required_nullable_thing, + } + } +} + +/// Converts the ANullableContainer value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ANullableContainer { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.nullable_thing.as_ref().map(|nullable_thing| { + [ + "NullableThing".to_string(), + nullable_thing.as_ref().map_or("null".to_string(), |x| x.to_string()), + ].join(",") + }), + Some("RequiredNullableThing".to_string()), + Some(self.required_nullable_thing.as_ref().map_or("null".to_string(), |x| x.to_string())), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ANullableContainer value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ANullableContainer { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub nullable_thing: Vec>, + pub required_nullable_thing: Vec>, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ANullableContainer".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + "NullableThing" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in ANullableContainer".to_string()), + "RequiredNullableThing" => return std::result::Result::Err("Parsing a nullable type in this style is not supported in ANullableContainer".to_string()), + _ => return std::result::Result::Err("Unexpected key while parsing ANullableContainer".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ANullableContainer { + nullable_thing: std::result::Result::Err("Nullable types not supported in ANullableContainer".to_string())?, + required_nullable_thing: std::result::Result::Err("Nullable types not supported in ANullableContainer".to_string())?, + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ANullableContainer - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ANullableContainer - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ANullableContainer - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +/// An additionalPropertiesObject +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AdditionalPropertiesObject(std::collections::HashMap); + +impl std::convert::From> for AdditionalPropertiesObject { + fn from(x: std::collections::HashMap) -> Self { + AdditionalPropertiesObject(x) + } +} + +impl std::convert::From for std::collections::HashMap { + fn from(x: AdditionalPropertiesObject) -> Self { + x.0 + } +} + +impl std::ops::Deref for AdditionalPropertiesObject { + type Target = std::collections::HashMap; + fn deref(&self) -> &std::collections::HashMap { + &self.0 + } +} + +impl std::ops::DerefMut for AdditionalPropertiesObject { + fn deref_mut(&mut self) -> &mut std::collections::HashMap { + &mut self.0 + } +} + +/// Converts the AdditionalPropertiesObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl ::std::string::ToString for AdditionalPropertiesObject { + fn to_string(&self) -> String { + // ToString for this model is not supported + "".to_string() + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl ::std::str::FromStr for AdditionalPropertiesObject { + type Err = &'static str; + + fn from_str(s: &str) -> std::result::Result { + std::result::Result::Err("Parsing AdditionalPropertiesObject is not supported") + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AdditionalPropertiesObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AdditionalPropertiesObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct AllOfObject { + #[serde(rename = "sampleProperty")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_property: Option, + + #[serde(rename = "sampleBaseProperty")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_base_property: Option, + +} + + +impl AllOfObject { + #[allow(clippy::new_without_default)] + pub fn new() -> AllOfObject { + AllOfObject { + sample_property: None, + sample_base_property: None, + } + } +} + +/// Converts the AllOfObject value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for AllOfObject { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.sample_property.as_ref().map(|sample_property| { + [ + "sampleProperty".to_string(), + sample_property.to_string(), + ].join(",") + }), + self.sample_base_property.as_ref().map(|sample_base_property| { + [ + "sampleBaseProperty".to_string(), + sample_base_property.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a AllOfObject value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for AllOfObject { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub sample_property: Vec, + pub sample_base_property: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing AllOfObject".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "sampleProperty" => intermediate_rep.sample_property.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "sampleBaseProperty" => intermediate_rep.sample_base_property.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing AllOfObject".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(AllOfObject { + sample_property: intermediate_rep.sample_property.into_iter().next(), + sample_base_property: intermediate_rep.sample_base_property.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for AllOfObject - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into AllOfObject - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into AllOfObject - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct BaseAllOf { + #[serde(rename = "sampleBaseProperty")] + #[serde(skip_serializing_if="Option::is_none")] + pub sample_base_property: Option, + +} + + +impl BaseAllOf { + #[allow(clippy::new_without_default)] + pub fn new() -> BaseAllOf { + BaseAllOf { + sample_base_property: None, + } + } +} + +/// Converts the BaseAllOf value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for BaseAllOf { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.sample_base_property.as_ref().map(|sample_base_property| { + [ + "sampleBaseProperty".to_string(), + sample_base_property.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a BaseAllOf value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for BaseAllOf { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub sample_base_property: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing BaseAllOf".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "sampleBaseProperty" => intermediate_rep.sample_base_property.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing BaseAllOf".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(BaseAllOf { + sample_base_property: intermediate_rep.sample_base_property.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for BaseAllOf - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into BaseAllOf - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into BaseAllOf - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct DummyPutRequest { + #[serde(rename = "id")] + pub id: String, + + #[serde(rename = "password")] + #[serde(skip_serializing_if="Option::is_none")] + pub password: Option, + +} + + +impl DummyPutRequest { + #[allow(clippy::new_without_default)] + pub fn new(id: String, ) -> DummyPutRequest { + DummyPutRequest { + id, + password: None, + } + } +} + +/// Converts the DummyPutRequest value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for DummyPutRequest { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("id".to_string()), + Some(self.id.to_string()), + self.password.as_ref().map(|password| { + [ + "password".to_string(), + password.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a DummyPutRequest value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for DummyPutRequest { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub id: Vec, + pub password: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing DummyPutRequest".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "id" => intermediate_rep.id.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "password" => intermediate_rep.password.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing DummyPutRequest".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(DummyPutRequest { + id: intermediate_rep.id.into_iter().next().ok_or_else(|| "id missing in DummyPutRequest".to_string())?, + password: intermediate_rep.password.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for DummyPutRequest - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into DummyPutRequest - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into DummyPutRequest - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +/// structured response +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct GetYamlResponse { + /// Inner string + #[serde(rename = "value")] + #[serde(skip_serializing_if="Option::is_none")] + pub value: Option, + +} + + +impl GetYamlResponse { + #[allow(clippy::new_without_default)] + pub fn new() -> GetYamlResponse { + GetYamlResponse { + value: None, + } + } +} + +/// Converts the GetYamlResponse value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for GetYamlResponse { + fn to_string(&self) -> String { + let params: Vec> = vec![ + self.value.as_ref().map(|value| { + [ + "value".to_string(), + value.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a GetYamlResponse value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for GetYamlResponse { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub value: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing GetYamlResponse".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "value" => intermediate_rep.value.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing GetYamlResponse".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(GetYamlResponse { + value: intermediate_rep.value.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for GetYamlResponse - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into GetYamlResponse - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into GetYamlResponse - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +/// An object of objects +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectOfObjects { + #[serde(rename = "inner")] + #[serde(skip_serializing_if="Option::is_none")] + pub inner: Option, + +} + + +impl ObjectOfObjects { + #[allow(clippy::new_without_default)] + pub fn new() -> ObjectOfObjects { + ObjectOfObjects { + inner: None, + } + } +} + +/// Converts the ObjectOfObjects value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectOfObjects { + fn to_string(&self) -> String { + let params: Vec> = vec![ + // Skipping non-primitive type inner in query parameter serialization + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectOfObjects value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectOfObjects { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub inner: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectOfObjects".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "inner" => intermediate_rep.inner.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectOfObjects".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectOfObjects { + inner: intermediate_rep.inner.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectOfObjects - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectOfObjects - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectOfObjects - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, validator::Validate)] +#[cfg_attr(feature = "conversion", derive(frunk::LabelledGeneric))] +pub struct ObjectOfObjectsInner { + #[serde(rename = "required_thing")] + pub required_thing: String, + + #[serde(rename = "optional_thing")] + #[serde(skip_serializing_if="Option::is_none")] + pub optional_thing: Option, + +} + + +impl ObjectOfObjectsInner { + #[allow(clippy::new_without_default)] + pub fn new(required_thing: String, ) -> ObjectOfObjectsInner { + ObjectOfObjectsInner { + required_thing, + optional_thing: None, + } + } +} + +/// Converts the ObjectOfObjectsInner value to the Query Parameters representation (style=form, explode=false) +/// specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde serializer +impl std::string::ToString for ObjectOfObjectsInner { + fn to_string(&self) -> String { + let params: Vec> = vec![ + Some("required_thing".to_string()), + Some(self.required_thing.to_string()), + self.optional_thing.as_ref().map(|optional_thing| { + [ + "optional_thing".to_string(), + optional_thing.to_string(), + ].join(",") + }), + ]; + + params.into_iter().flatten().collect::>().join(",") + } +} + +/// Converts Query Parameters representation (style=form, explode=false) to a ObjectOfObjectsInner value +/// as specified in https://swagger.io/docs/specification/serialization/ +/// Should be implemented in a serde deserializer +impl std::str::FromStr for ObjectOfObjectsInner { + type Err = String; + + fn from_str(s: &str) -> std::result::Result { + /// An intermediate representation of the struct to use for parsing. + #[derive(Default)] + #[allow(dead_code)] + struct IntermediateRep { + pub required_thing: Vec, + pub optional_thing: Vec, + } + + let mut intermediate_rep = IntermediateRep::default(); + + // Parse into intermediate representation + let mut string_iter = s.split(','); + let mut key_result = string_iter.next(); + + while key_result.is_some() { + let val = match string_iter.next() { + Some(x) => x, + None => return std::result::Result::Err("Missing value while parsing ObjectOfObjectsInner".to_string()) + }; + + if let Some(key) = key_result { + #[allow(clippy::match_single_binding)] + match key { + #[allow(clippy::redundant_clone)] + "required_thing" => intermediate_rep.required_thing.push(::from_str(val).map_err(|x| x.to_string())?), + #[allow(clippy::redundant_clone)] + "optional_thing" => intermediate_rep.optional_thing.push(::from_str(val).map_err(|x| x.to_string())?), + _ => return std::result::Result::Err("Unexpected key while parsing ObjectOfObjectsInner".to_string()) + } + } + + // Get the next key + key_result = string_iter.next(); + } + + // Use the intermediate representation to return the struct + std::result::Result::Ok(ObjectOfObjectsInner { + required_thing: intermediate_rep.required_thing.into_iter().next().ok_or_else(|| "required_thing missing in ObjectOfObjectsInner".to_string())?, + optional_thing: intermediate_rep.optional_thing.into_iter().next(), + }) + } +} + +// Methods for converting between header::IntoHeaderValue and hyper::header::HeaderValue + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_value: header::IntoHeaderValue) -> std::result::Result { + let hdr_value = hdr_value.to_string(); + match hyper::header::HeaderValue::from_str(&hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(e) => std::result::Result::Err( + format!("Invalid header value for ObjectOfObjectsInner - value: {hdr_value} is invalid {e}")) + } + } +} + +#[cfg(any(feature = "client", feature = "server"))] +impl std::convert::TryFrom for header::IntoHeaderValue { + type Error = String; + + fn try_from(hdr_value: hyper::header::HeaderValue) -> std::result::Result { + match hdr_value.to_str() { + std::result::Result::Ok(value) => { + match ::from_str(value) { + std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{value}' into ObjectOfObjectsInner - {err}")) + } + }, + std::result::Result::Err(e) => std::result::Result::Err( + format!("Unable to convert header: {hdr_value:?} to string: {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom>> for hyper::header::HeaderValue { + type Error = String; + + fn try_from(hdr_values: header::IntoHeaderValue>) -> std::result::Result { + let hdr_values : Vec = hdr_values.0.into_iter().map(|hdr_value| { + hdr_value.to_string() + }).collect(); + + match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { + std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}")) + } + } +} + +#[cfg(feature = "server")] +impl std::convert::TryFrom for header::IntoHeaderValue> { + type Error = String; + + fn try_from(hdr_values: hyper::header::HeaderValue) -> std::result::Result { + match hdr_values.to_str() { + std::result::Result::Ok(hdr_values) => { + let hdr_values : std::vec::Vec = hdr_values + .split(',') + .filter_map(|hdr_value| match hdr_value.trim() { + "" => std::option::Option::None, + hdr_value => std::option::Option::Some({ + match ::from_str(hdr_value) { + std::result::Result::Ok(value) => std::result::Result::Ok(value), + std::result::Result::Err(err) => std::result::Result::Err( + format!("Unable to convert header value '{hdr_value}' into ObjectOfObjectsInner - {err}")) + } + }) + }).collect::, String>>()?; + + std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) + }, + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/mod.rs new file mode 100644 index 000000000000..4c288f04851e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/mod.rs @@ -0,0 +1,684 @@ +#![allow(clippy::redundant_locals)] +#![allow(clippy::explicit_auto_deref)] +#![allow(clippy::manual_unwrap_or_default)] +use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; +use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; +use log::warn; +#[allow(unused_imports)] +use std::convert::{TryFrom, TryInto}; +use std::error::Error; +use std::future::Future; +use std::marker::PhantomData; +use std::task::{Context, Poll}; +use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; +pub use swagger::auth::Authorization; +use swagger::auth::Scopes; +use url::form_urlencoded; + +#[allow(unused_imports)] +use crate::{models, header, AuthenticationApi}; + +pub use crate::context; + +type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; + +use crate::{Api, + AllOfGetResponse, + DummyGetResponse, + DummyPutResponse, + FileResponseGetResponse, + GetStructuredYamlResponse, + HtmlPostResponse, + PostYamlResponse, + RawJsonGetResponse, + SoloObjectPostResponse +}; + +mod server_auth; + +mod paths { + use lazy_static::lazy_static; + + lazy_static! { + pub static ref GLOBAL_REGEX_SET: regex::RegexSet = regex::RegexSet::new(vec![ + r"^/allOf$", + r"^/dummy$", + r"^/file_response$", + r"^/get-structured-yaml$", + r"^/html$", + r"^/post-yaml$", + r"^/raw_json$", + r"^/solo-object$" + ]) + .expect("Unable to create global regex set"); + } + pub(crate) static ID_ALLOF: usize = 0; + pub(crate) static ID_DUMMY: usize = 1; + pub(crate) static ID_FILE_RESPONSE: usize = 2; + pub(crate) static ID_GET_STRUCTURED_YAML: usize = 3; + pub(crate) static ID_HTML: usize = 4; + pub(crate) static ID_POST_YAML: usize = 5; + pub(crate) static ID_RAW_JSON: usize = 6; + pub(crate) static ID_SOLO_OBJECT: usize = 7; +} + + +pub struct MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + MakeService { + api_impl, + marker: PhantomData + } + } +} + +impl hyper::service::Service for MakeService where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Service; + type Error = crate::ServiceError; + type Future = future::Ready>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, target: Target) -> Self::Future { + let service = Service::new(self.api_impl.clone()); + + future::ok(service) + } +} + +fn method_not_allowed() -> Result, crate::ServiceError> { + Ok( + Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) + .body(Body::empty()) + .expect("Unable to create Method Not Allowed response") + ) +} + +pub struct Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + api_impl: T, + marker: PhantomData, +} + +impl Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + pub fn new(api_impl: T) -> Self { + Service { + api_impl, + marker: PhantomData + } + } +} + +impl Clone for Service where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Service { + api_impl: self.api_impl.clone(), + marker: self.marker, + } + } +} + +impl hyper::service::Service<(Request, C)> for Service where + T: Api + Clone + Send + Sync + 'static, + C: Has + Send + Sync + 'static +{ + type Response = Response; + type Error = crate::ServiceError; + type Future = ServiceFuture; + + fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + self.api_impl.poll_ready(cx) + } + + fn call(&mut self, req: (Request, C)) -> Self::Future { + async fn run( + mut api_impl: T, + req: (Request, C), + ) -> Result, crate::ServiceError> where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static + { + let (request, context) = req; + let (parts, body) = request.into_parts(); + let (method, uri, headers) = (parts.method, parts.uri, parts.headers); + let path = paths::GLOBAL_REGEX_SET.matches(uri.path()); + + match method { + + // AllOfGet - GET /allOf + hyper::Method::GET if path.matched(paths::ID_ALLOF) => { + let result = api_impl.all_of_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + AllOfGetResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // DummyGet - GET /dummy + hyper::Method::GET if path.matched(paths::ID_DUMMY) => { + let result = api_impl.dummy_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + DummyGetResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // DummyPut - PUT /dummy + hyper::Method::PUT if path.matched(paths::ID_DUMMY) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_nested_response: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_nested_response) => param_nested_response, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter nested_response - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter nested_response due to schema")), + } + } else { + None + }; + let param_nested_response = match param_nested_response { + Some(param_nested_response) => param_nested_response, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter nested_response")) + .expect("Unable to create Bad Request response for missing body parameter nested_response")), + }; + + + let result = api_impl.dummy_put( + param_nested_response, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + DummyPutResponse::Success + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // FileResponseGet - GET /file_response + hyper::Method::GET if path.matched(paths::ID_FILE_RESPONSE) => { + let result = api_impl.file_response_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + FileResponseGetResponse::Success + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // GetStructuredYaml - GET /get-structured-yaml + hyper::Method::GET if path.matched(paths::ID_GET_STRUCTURED_YAML) => { + let result = api_impl.get_structured_yaml( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + GetStructuredYamlResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/yaml") + .expect("Unable to create Content-Type header for application/yaml")); + // Plain text Body + let body = body; + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // HtmlPost - POST /html + hyper::Method::POST if path.matched(paths::ID_HTML) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let param_body: Option = if !body.is_empty() { + match String::from_utf8(body.to_vec()) { + Ok(param_body) => Some(param_body), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter body - not valid UTF-8: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter body due to UTF-8")), + } + } else { + None + }; + let param_body = match param_body { + Some(param_body) => param_body, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter body")) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.html_post( + param_body, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + HtmlPostResponse::Success + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("text/html") + .expect("Unable to create Content-Type header for text/html")); + // Plain text Body + let body = body; + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // PostYaml - POST /post-yaml + hyper::Method::POST if path.matched(paths::ID_POST_YAML) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let param_value: Option = if !body.is_empty() { + match String::from_utf8(body.to_vec()) { + Ok(param_value) => Some(param_value), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter value - not valid UTF-8: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter value due to UTF-8")), + } + } else { + None + }; + let param_value = match param_value { + Some(param_value) => param_value, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter value")) + .expect("Unable to create Bad Request response for missing body parameter value")), + }; + + + let result = api_impl.post_yaml( + param_value, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + PostYamlResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + // RawJsonGet - GET /raw_json + hyper::Method::GET if path.matched(paths::ID_RAW_JSON) => { + let result = api_impl.raw_json_get( + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + RawJsonGetResponse::Success + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("*/*") + .expect("Unable to create Content-Type header for */*")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = Body::from(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + + // SoloObjectPost - POST /solo-object + hyper::Method::POST if path.matched(paths::ID_SOLO_OBJECT) => { + // Handle body parameters (note that non-required body parameters will ignore garbage + // values, rather than causing a 400 response). Produce warning header and logs for + // any unused fields. + let result = body.into_raw().await; + match result { + Ok(body) => { + let mut unused_elements : Vec = vec![]; + let param_value: Option = if !body.is_empty() { + let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + match serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }) { + Ok(param_value) => param_value, + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse body parameter value - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid body parameter value due to schema")), + } + } else { + None + }; + let param_value = match param_value { + Some(param_value) => param_value, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required body parameter value")) + .expect("Unable to create Bad Request response for missing body parameter value")), + }; + + + let result = api_impl.solo_object_post( + param_value, + &context + ).await; + let mut response = Response::new(Body::empty()); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + if !unused_elements.is_empty() { + response.headers_mut().insert( + HeaderName::from_static("warning"), + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) + .expect("Unable to create Warning header value")); + } + match result { + Ok(rsp) => match rsp { + SoloObjectPostResponse::OK + => { + *response.status_mut() = StatusCode::from_u16(204).expect("Unable to turn 204 into a StatusCode"); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = Body::from("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Unable to read body: {e}"))) + .expect("Unable to create Bad Request response due to unable to read body")), + } + }, + + _ if path.matched(paths::ID_ALLOF) => method_not_allowed(), + _ if path.matched(paths::ID_DUMMY) => method_not_allowed(), + _ if path.matched(paths::ID_FILE_RESPONSE) => method_not_allowed(), + _ if path.matched(paths::ID_GET_STRUCTURED_YAML) => method_not_allowed(), + _ if path.matched(paths::ID_HTML) => method_not_allowed(), + _ if path.matched(paths::ID_POST_YAML) => method_not_allowed(), + _ if path.matched(paths::ID_RAW_JSON) => method_not_allowed(), + _ if path.matched(paths::ID_SOLO_OBJECT) => method_not_allowed(), + _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) + .body(Body::empty()) + .expect("Unable to create Not Found response")) + } + } + Box::pin(run( + self.api_impl.clone(), + req, + )) + } +} + +/// Request parser for `Api`. +pub struct ApiRequestParser; +impl RequestParser for ApiRequestParser { + fn parse_operation_id(request: &Request) -> Option<&'static str> { + let path = paths::GLOBAL_REGEX_SET.matches(request.uri().path()); + match *request.method() { + // AllOfGet - GET /allOf + hyper::Method::GET if path.matched(paths::ID_ALLOF) => Some("AllOfGet"), + // DummyGet - GET /dummy + hyper::Method::GET if path.matched(paths::ID_DUMMY) => Some("DummyGet"), + // DummyPut - PUT /dummy + hyper::Method::PUT if path.matched(paths::ID_DUMMY) => Some("DummyPut"), + // FileResponseGet - GET /file_response + hyper::Method::GET if path.matched(paths::ID_FILE_RESPONSE) => Some("FileResponseGet"), + // GetStructuredYaml - GET /get-structured-yaml + hyper::Method::GET if path.matched(paths::ID_GET_STRUCTURED_YAML) => Some("GetStructuredYaml"), + // HtmlPost - POST /html + hyper::Method::POST if path.matched(paths::ID_HTML) => Some("HtmlPost"), + // PostYaml - POST /post-yaml + hyper::Method::POST if path.matched(paths::ID_POST_YAML) => Some("PostYaml"), + // RawJsonGet - GET /raw_json + hyper::Method::GET if path.matched(paths::ID_RAW_JSON) => Some("RawJsonGet"), + // SoloObjectPost - POST /solo-object + hyper::Method::POST if path.matched(paths::ID_SOLO_OBJECT) => Some("SoloObjectPost"), + _ => None, + } + } +} diff --git a/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/server_auth.rs b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/server_auth.rs new file mode 100644 index 000000000000..ba78eb2f3f5d --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/rust-server-test/src/server/server_auth.rs @@ -0,0 +1,28 @@ +use super::Service; +use crate::{Api, AuthenticationApi}; +use swagger::{ + ApiError, + Authorization, + auth::{Basic, Bearer}, + Has, + XSpanIdString}; + +impl AuthenticationApi for Service where +T: Api + Clone + Send + 'static + AuthenticationApi, +C: Has + Has> + Send + Sync + 'static { + + /// Passthrough of the task to the api-implementation + fn bearer_authorization(&self, token: &Bearer) -> Result { + self.api_impl.bearer_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn apikey_authorization(&self, token: &str) -> Result { + self.api_impl.apikey_authorization(token) + } + + /// Passthrough of the task to the api-implementation + fn basic_authorization(&self, basic: &Basic) -> Result { + self.api_impl.basic_authorization(basic) + } +} diff --git a/samples/server/petstore/rust-server-deprecated/pom.xml b/samples/server/petstore/rust-server-deprecated/pom.xml new file mode 100644 index 000000000000..61e50dcc15a0 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/pom.xml @@ -0,0 +1,73 @@ + + 4.0.0 + org.openapitools + RustServerTests + pom + 1.0-SNAPSHOT + Rust Petstore Sample + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory} + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + build + integration-test + + exec + + + cargo + + build + --examples + + + + + test + integration-test + + exec + + + cargo + + test + + + + + clippy + integration-test + + exec + + + cargo + + clippy + + + + + + + + diff --git a/samples/server/petstore/rust-server/.cargo/config.toml b/samples/server/petstore/rust-server/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/multipart-v3/.cargo/config.toml b/samples/server/petstore/rust-server/output/multipart-v3/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/multipart-v3/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/multipart-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/multipart-v3/.openapi-generator/FILES index 3f051cfa5e44..422fe9b45d10 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/multipart-v3/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml index c17bc7e481fd..67914ca651ff 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml @@ -10,83 +10,86 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "mime_0_2", "multipart", "multipart/client", "swagger/multipart_form", - "hyper_0_10", "mime_multipart", "swagger/multipart_related", - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "mime_multipart", "swagger/multipart_related", + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ - "mime_0_2", "multipart", "multipart/server", "swagger/multipart_form", - "hyper_0_10", "mime_multipart", "swagger/multipart_related", + "mime_multipart", "swagger/multipart_related", "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition -mime_0_2 = { package = "mime", version = "0.2.6", optional = true } -multipart = { version = "0.16", default-features = false, optional = true } +multipart = { version = "0.18", default-features = false, optional = true } # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -mime_multipart = {version = "0.5", optional = true} -hyper_0_10 = {package = "hyper", version = "0.10", default-features = false, optional=true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +mime_multipart = { version = "0.10", optional = true, package = "mime-multipart-hyper1" } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/multipart-v3/bin/cli.rs b/samples/server/petstore/rust-server/output/multipart-v3/bin/cli.rs index cc14190181fb..ff6a1dfd926d 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -10,7 +11,6 @@ use multipart_v3::{ MultipleIdenticalMimeTypesPostResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -20,65 +20,65 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "Multipart OpenAPI V3 Rust Server Test", version = "1.0.7", about = "CLI access to Multipart OpenAPI V3 Rust Server Test" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { MultipartRelatedRequestPost { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] required_binary_field: swagger::ByteArray, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] object_field: Option, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] optional_binary_field: Option, }, MultipartRequestPost { string_field: String, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] binary_field: swagger::ByteArray, optional_string_field: Option, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] object_field: Option, }, MultipleIdenticalMimeTypesPost { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] binary1: Option, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] binary2: Option, }, } @@ -118,7 +118,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -210,6 +210,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs index f679dbf950f6..bfec3bbe3bef 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/client/main.rs @@ -9,7 +9,7 @@ use multipart_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, MultipartRequestPostResponse, MultipleIdenticalMimeTypesPostResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -32,27 +32,25 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ "MultipartRelatedRequestPost", "MultipartRequestPost", "MultipleIdenticalMimeTypesPost", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -76,22 +74,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -106,7 +104,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { Some("MultipartRelatedRequestPost") => { let result = rt.block_on(client.multipart_related_request_post( swagger::ByteArray(Vec::from("BINARY_DATA_HERE")), diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs index a0b4755e80c1..bb29d967957c 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs index 5b2d8a75d03d..c84b0f4f24ab 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use multipart_v3::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server_auth.rs index bf48130e2941..4e1903155914 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use multipart_v3::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -87,7 +87,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -124,4 +124,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/auth.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/auth.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs index 42a5fbc96b86..2317ae0da1f3 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,11 +20,12 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use mime::Mime; use std::io::Cursor; use multipart::client::lazy::Multipart; -use hyper_0_10::header::{Headers, ContentType}; +use hyper::header::HeaderMap; use mime_multipart::{Node, Part, write_multipart}; use crate::models; @@ -61,15 +64,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -86,8 +88,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -99,8 +100,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -114,8 +114,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -129,7 +140,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -138,8 +149,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -151,26 +162,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -181,7 +185,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -194,13 +198,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -217,13 +221,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -234,18 +249,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -258,7 +284,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -279,7 +305,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -307,8 +333,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -370,23 +395,25 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn multipart_related_request_post( &self, param_required_binary_field: swagger::ByteArray, @@ -395,6 +422,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multipart_related_request", self.base_path @@ -412,15 +440,15 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes multipart/related body @@ -430,9 +458,9 @@ impl Api for Client where if let Some(object_field) = param_object_field { let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("application/json".parse().unwrap())); - h.set_raw("Content-ID", vec![b"object_field".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("application/json")); + h.insert("Content-ID", HeaderValue::from_static("object_field")); h }, body: serde_json::to_string(&object_field) @@ -445,9 +473,9 @@ impl Api for Client where if let Some(optional_binary_field) = param_optional_binary_field { let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("application/zip".parse().unwrap())); - h.set_raw("Content-ID", vec![b"optional_binary_field".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("application/zip")); + h.insert("Content-ID", HeaderValue::from_static("optional_binary_field")); h }, body: optional_binary_field.0, @@ -458,9 +486,9 @@ impl Api for Client where { let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("image/png".parse().unwrap())); - h.set_raw("Content-ID", vec![b"required_binary_field".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("image/png")); + h.insert("Content-ID", HeaderValue::from_static("required_binary_field")); h }, body: param_required_binary_field.0, @@ -483,20 +511,20 @@ impl Api for Client where &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); // Add the message body to the request object. - *request.body_mut() = Body::from(body); + *request.body_mut() = BoxBody::new(Full::new(Bytes::from(body))); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -506,24 +534,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn multipart_request_post( &self, param_string_field: String, @@ -533,6 +560,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multipart_request", self.base_path @@ -550,15 +578,15 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes multipart/form body @@ -569,11 +597,11 @@ impl Api for Client where let string_field_str = match serde_json::to_string(¶m_string_field) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize string_field to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize string_field to string: {e}"))), }; let string_field_vec = string_field_str.as_bytes().to_vec(); - let string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let string_field_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let string_field_cursor = Cursor::new(string_field_vec); multipart.add_stream("string_field", string_field_cursor, None as Option<&str>, Some(string_field_mime)); @@ -581,11 +609,11 @@ impl Api for Client where let optional_string_field_str = match serde_json::to_string(¶m_optional_string_field) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize optional_string_field to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize optional_string_field to string: {e}"))), }; let optional_string_field_vec = optional_string_field_str.as_bytes().to_vec(); - let optional_string_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let optional_string_field_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let optional_string_field_cursor = Cursor::new(optional_string_field_vec); multipart.add_stream("optional_string_field", optional_string_field_cursor, None as Option<&str>, Some(optional_string_field_mime)); @@ -593,11 +621,11 @@ impl Api for Client where let object_field_str = match serde_json::to_string(¶m_object_field) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize object_field to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize object_field to string: {e}"))), }; let object_field_vec = object_field_str.as_bytes().to_vec(); - let object_field_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let object_field_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let object_field_cursor = Cursor::new(object_field_vec); multipart.add_stream("object_field", object_field_cursor, None as Option<&str>, Some(object_field_mime)); @@ -606,9 +634,9 @@ impl Api for Client where let binary_field_vec = param_binary_field.to_vec(); - let binary_field_mime = match mime_0_2::Mime::from_str("application/octet-stream") { + let binary_field_mime = match mime::Mime::from_str("application/octet-stream") { Ok(mime) => mime, - Err(err) => return Err(ApiError(format!("Unable to get mime type: {:?}", err))), + Err(err) => return Err(ApiError(format!("Unable to get mime type: {err:?}"))), }; let binary_field_cursor = Cursor::new(binary_field_vec); @@ -618,39 +646,39 @@ impl Api for Client where let mut fields = match multipart.prepare() { Ok(fields) => fields, - Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), }; let mut body_string = String::new(); match fields.read_to_string(&mut body_string) { Ok(_) => (), - Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), } let boundary = fields.boundary(); - let multipart_header = format!("multipart/form-data;boundary={}", boundary); + let multipart_header = format!("multipart/form-data;boundary={boundary}"); (body_string, multipart_header) }; - *request.body_mut() = Body::from(body_string); + *request.body_mut() = body_from_string(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -660,24 +688,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn multiple_identical_mime_types_post( &self, param_binary1: Option, @@ -685,6 +712,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multiple-identical-mime-types", self.base_path @@ -702,15 +730,15 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes multipart/related body @@ -720,9 +748,9 @@ impl Api for Client where if let Some(binary1) = param_binary1 { let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("application/octet-stream".parse().unwrap())); - h.set_raw("Content-ID", vec![b"binary1".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("application/octet-stream")); + h.insert("Content-ID", HeaderValue::from_static("binary1")); h }, body: binary1.0, @@ -733,9 +761,9 @@ impl Api for Client where if let Some(binary2) = param_binary2 { let part = Node::Part(Part { headers: { - let mut h = Headers::new(); - h.set(ContentType("application/octet-stream".parse().unwrap())); - h.set_raw("Content-ID", vec![b"binary2".to_vec()]); + let mut h = HeaderMap::new(); + h.insert(CONTENT_TYPE, HeaderValue::from_static("application/octet-stream")); + h.insert("Content-ID", HeaderValue::from_static("binary2")); h }, body: binary2.0, @@ -758,20 +786,20 @@ impl Api for Client where &[header.as_bytes(), "; boundary=".as_bytes(), &boundary, "; type=\"application/json\"".as_bytes()].concat() ) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); // Add the message body to the request object. - *request.body_mut() = Body::from(body); + *request.body_mut() = BoxBody::new(Full::new(Bytes::from(body))); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -781,18 +809,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs index ee8e118587bb..45180a543112 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,30 +87,23 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/header.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/header.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs index 8c41db6313c6..f4d488090a01 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/lib.rs @@ -42,10 +42,6 @@ pub enum MultipleIdenticalMimeTypesPostResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn multipart_related_request_post( &self, required_binary_field: swagger::ByteArray, @@ -74,8 +70,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn multipart_related_request_post( @@ -116,10 +110,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/models.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/models.rs index e4d230e6faf3..609c0faabb50 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/models.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/models.rs @@ -35,22 +35,22 @@ impl MultipartRelatedRequest { } /// Converts the MultipartRelatedRequest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MultipartRelatedRequest { - fn to_string(&self) -> String { +impl std::fmt::Display for MultipartRelatedRequest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type object_field in query parameter serialization // Skipping binary data optional_binary_field in query parameter serialization // Skipping binary data required_binary_field in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MultipartRelatedRequest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MultipartRelatedRequest { type Err = String; @@ -112,8 +112,7 @@ impl std::convert::TryFrom> for match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MultipartRelatedRequest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MultipartRelatedRequest - value: {hdr_value} is invalid {e}")) } } } @@ -128,13 +127,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipartRelatedRequest - {}", - value, err)) + format!("Unable to convert header value '{value}' into MultipartRelatedRequest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -150,8 +147,7 @@ impl std::convert::TryFrom> match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -171,16 +167,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipartRelatedRequest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MultipartRelatedRequest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -209,10 +203,10 @@ impl MultipartRequestObjectField { } /// Converts the MultipartRequestObjectField value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MultipartRequestObjectField { - fn to_string(&self) -> String { +impl std::fmt::Display for MultipartRequestObjectField { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("field_a".to_string()), Some(self.field_a.to_string()), @@ -224,12 +218,12 @@ impl std::string::ToString for MultipartRequestObjectField { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MultipartRequestObjectField value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MultipartRequestObjectField { type Err = String; @@ -288,8 +282,7 @@ impl std::convert::TryFrom> match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MultipartRequestObjectField - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MultipartRequestObjectField - value: {hdr_value} is invalid {e}")) } } } @@ -304,13 +297,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipartRequestObjectField - {}", - value, err)) + format!("Unable to convert header value '{value}' into MultipartRequestObjectField - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -326,8 +317,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -347,16 +337,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipartRequestObjectField - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MultipartRequestObjectField - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -386,21 +374,21 @@ impl MultipleIdenticalMimeTypesPostRequest { } /// Converts the MultipleIdenticalMimeTypesPostRequest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MultipleIdenticalMimeTypesPostRequest { - fn to_string(&self) -> String { +impl std::fmt::Display for MultipleIdenticalMimeTypesPostRequest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping binary data binary1 in query parameter serialization // Skipping binary data binary2 in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MultipleIdenticalMimeTypesPostRequest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MultipleIdenticalMimeTypesPostRequest { type Err = String; @@ -458,8 +446,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MultipleIdenticalMimeTypesPostRequest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MultipleIdenticalMimeTypesPostRequest - value: {hdr_value} is invalid {e}")) } } } @@ -474,13 +461,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipleIdenticalMimeTypesPostRequest - {}", - value, err)) + format!("Unable to convert header value '{value}' into MultipleIdenticalMimeTypesPostRequest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -496,8 +481,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -517,16 +501,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultipleIdenticalMimeTypesPostRequest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MultipleIdenticalMimeTypesPostRequest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs index 442c54a8db74..88b6300c0225 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -12,8 +14,6 @@ use swagger::{ApiError, BodyExt, Has, RequestParser, XSpanIdString}; pub use swagger::auth::Authorization; use swagger::auth::Scopes; use url::form_urlencoded; -use hyper_0_10::header::{Headers, ContentType}; -use mime_0_2::{TopLevel, SubLevel, Mime as Mime2}; use mime_multipart::{read_multipart_body, Node, Part}; use multipart::server::Multipart; use multipart::server::save::{PartialReason, SaveResult}; @@ -23,7 +23,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, MultipartRelatedRequestPostResponse, @@ -50,7 +50,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -59,7 +60,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -82,7 +84,22 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -90,11 +107,7 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()) .multipart_form_size_limit(self.multipart_form_size_limit); @@ -102,10 +115,10 @@ impl hyper::service::Service for MakeService where } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -155,26 +168,38 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), + req: (Request, C), multipart_form_size_limit: Option, - ) -> Result, crate::ServiceError> where + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -188,7 +213,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; @@ -200,7 +225,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(e)) + .body(BoxBody::new(e.to_string())) .expect("Unable to create Bad Request response due to unable to read content-type header for MultipartRelatedRequestPost")); } }; @@ -212,7 +237,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Could not read multipart body for MultipartRelatedRequestPost: {}", e))) + .body(BoxBody::new(format!("Could not read multipart body for MultipartRelatedRequestPost: {e}"))) .expect("Unable to create Bad Request response due to unable to read multipart body for MultipartRelatedRequestPost")); } }; @@ -223,19 +248,19 @@ impl hyper::service::Service<(Request, C)> for Service where for node in nodes { if let Node::Part(part) = node { - let content_type = part.content_type().map(|x| format!("{}",x)); + let content_type = part.content_type().map(|x| format!("{x}")); match content_type.as_deref() { Some("application/json") if param_object_field.is_none() => { // Extract JSON part. let deserializer = &mut serde_json::Deserializer::from_slice(part.body.as_slice()); let json_data: models::MultipartRequestObjectField = match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in JSON part: {}", path); + warn!("Ignoring unknown field in JSON part: {path}"); unused_elements.push(path.to_string()); }) { Ok(json_data) => json_data, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter models::MultipartRequestObjectField - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter models::MultipartRequestObjectField - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter models::MultipartRequestObjectField due to schema")) }; // Push JSON part to return object. @@ -248,7 +273,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_required_binary_field.get_or_insert(swagger::ByteArray(part.body)); }, Some(content_type) => { - warn!("Ignoring unexpected content type: {}", content_type); + warn!("Ignoring unexpected content type: {content_type}"); unused_elements.push(content_type.to_string()); }, None => { @@ -266,7 +291,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(x) => x, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required multipart/related parameter required_binary_field".to_string())) + .body(BoxBody::new("Missing required multipart/related parameter required_binary_field".to_string())) .expect("Unable to create Bad Request response for missing multipart/related parameter required_binary_field due to schema")) }; @@ -277,7 +302,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_optional_binary_field, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -286,7 +311,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -301,7 +326,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -309,7 +334,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -319,14 +344,14 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let boundary = match swagger::multipart::form::boundary(&headers) { Some(boundary) => boundary.to_string(), None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Couldn't find valid multipart body".to_string())) + .body(BoxBody::new("Couldn't find valid multipart body".to_string())) .expect("Unable to create Bad Request response for incorrect boundary")), }; @@ -344,31 +369,31 @@ impl hyper::service::Service<(Request, C)> for Service where SaveResult::Partial(_, PartialReason::CountLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive parts".to_string())) .expect("Unable to create Bad Request response due to excessive parts")) }, SaveResult::Partial(_, PartialReason::SizeLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive data".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive data".to_string())) .expect("Unable to create Bad Request response due to excessive data")) }, SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to invalid data".to_string())) + .body(BoxBody::new("Unable to process message part due to invalid data".to_string())) .expect("Unable to create Bad Request response due to invalid data")) }, SaveResult::Partial(_, PartialReason::IoError(_)) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process message part due an internal error".to_string())) + .body(BoxBody::new("Failed to process message part due an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, SaveResult::Error(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .body(BoxBody::new("Failed to process all message parts due to an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, }; @@ -384,7 +409,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("string_field data does not match API definition : {}", e))) + .body(BoxBody::new(format!("string_field data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter string_field")) } }; @@ -394,7 +419,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required form parameter string_field".to_string())) + .body(BoxBody::new("Missing required form parameter string_field".to_string())) .expect("Unable to create Bad Request due to missing required form parameter string_field")) } }; @@ -411,7 +436,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("optional_string_field data does not match API definition : {}", e))) + .body(BoxBody::new(format!("optional_string_field data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter optional_string_field")) } }; @@ -435,7 +460,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("object_field data does not match API definition : {}", e))) + .body(BoxBody::new(format!("object_field data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter object_field")) } }; @@ -458,7 +483,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required form parameter binary_field".to_string())) + .body(BoxBody::new("Missing required form parameter binary_field".to_string())) .expect("Unable to create Bad Request due to missing required form parameter binary_field")) } }; @@ -471,7 +496,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_object_field, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -489,7 +514,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -497,7 +522,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -507,7 +532,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; @@ -519,7 +544,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(e)) + .body(BoxBody::new(e.to_string())) .expect("Unable to create Bad Request response due to unable to read content-type header for MultipleIdenticalMimeTypesPost")); } }; @@ -531,7 +556,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Could not read multipart body for MultipleIdenticalMimeTypesPost: {}", e))) + .body(BoxBody::new(format!("Could not read multipart body for MultipleIdenticalMimeTypesPost: {e}"))) .expect("Unable to create Bad Request response due to unable to read multipart body for MultipleIdenticalMimeTypesPost")); } }; @@ -541,7 +566,7 @@ impl hyper::service::Service<(Request, C)> for Service where for node in nodes { if let Node::Part(part) = node { - let content_type = part.content_type().map(|x| format!("{}",x)); + let content_type = part.content_type().map(|x| format!("{x}")); match content_type.as_deref() { Some("application/octet-stream") if param_binary1.is_none() => { param_binary1.get_or_insert(swagger::ByteArray(part.body)); @@ -550,7 +575,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_binary2.get_or_insert(swagger::ByteArray(part.body)); }, Some(content_type) => { - warn!("Ignoring unexpected content type: {}", content_type); + warn!("Ignoring unexpected content type: {content_type}"); unused_elements.push(content_type.to_string()); }, None => { @@ -571,7 +596,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_binary2, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -580,7 +605,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -595,7 +620,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -603,7 +628,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -612,7 +637,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_MULTIPART_REQUEST) => method_not_allowed(), _ if path.matched(paths::ID_MULTIPLE_IDENTICAL_MIME_TYPES) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/multipart-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/multipart-v3/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/no-example-v3/.cargo/config.toml b/samples/server/petstore/rust-server/output/no-example-v3/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/no-example-v3/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/no-example-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/no-example-v3/.openapi-generator/FILES index 7c4254323479..b1a97ff266dd 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/no-example-v3/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml index 4315116e7edf..1e4463cc6e4c 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml @@ -10,73 +10,80 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/no-example-v3/bin/cli.rs b/samples/server/petstore/rust-server/output/no-example-v3/bin/cli.rs index 1f77caa4a8f6..cb16d5acbd2d 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -8,7 +9,6 @@ use no_example_v3::{ OpGetResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -18,47 +18,47 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "Regression test for an API which doesn't have any example", version = "0.0.1", about = "CLI access to Regression test for an API which doesn't have any example" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { OpGet { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] op_get_request: models::OpGetRequest, }, } @@ -98,7 +98,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -146,6 +146,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs index 79405fc5d227..5d41ca4cb1f5 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/client/main.rs @@ -7,7 +7,7 @@ use futures::{future, Stream, stream}; use no_example_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, OpGetResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -30,24 +30,23 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ + "OpGet", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -71,22 +70,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -101,7 +100,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { /* Disabled because there's no example. Some("OpGet") => { let result = rt.block_on(client.op_get( diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs index ae01015501e5..d9dcb53b00cd 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs index c4e6006fb34e..47b77f5710e2 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use no_example_v3::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server_auth.rs index a807460bd9a1..b5b26c5c51e4 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use no_example_v3::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -87,7 +87,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -124,4 +124,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/auth.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/auth.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs index 218967ec7a60..f55b94c32e49 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -54,15 +57,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -79,8 +81,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -92,8 +93,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -107,8 +107,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -122,7 +133,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -131,8 +142,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -144,26 +155,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -174,7 +178,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -187,13 +191,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -210,13 +214,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -227,18 +242,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -251,7 +277,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -272,7 +298,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -300,8 +326,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -363,29 +388,32 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn op_get( &self, param_op_get_request: models::OpGetRequest, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op", self.base_path @@ -403,36 +431,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_op_get_request).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -442,18 +470,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs index ee8e118587bb..45180a543112 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,30 +87,23 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/header.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/header.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs index 009a31837355..6499665e9aa3 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/lib.rs @@ -30,10 +30,6 @@ pub enum OpGetResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn op_get( &self, op_get_request: models::OpGetRequest, @@ -46,8 +42,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn op_get( @@ -72,10 +66,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/models.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/models.rs index 6d87b86882ff..085f2383b98e 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/models.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/models.rs @@ -25,21 +25,21 @@ impl OpGetRequest { } /// Converts the OpGetRequest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for OpGetRequest { - fn to_string(&self) -> String { +impl std::fmt::Display for OpGetRequest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("property".to_string()), Some(self.property.to_string()), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a OpGetRequest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for OpGetRequest { type Err = String; @@ -95,8 +95,7 @@ impl std::convert::TryFrom> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OpGetRequest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OpGetRequest - value: {hdr_value} is invalid {e}")) } } } @@ -111,13 +110,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OpGetRequest - {}", - value, err)) + format!("Unable to convert header value '{value}' into OpGetRequest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -133,8 +130,7 @@ impl std::convert::TryFrom>> for hyper match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -154,16 +150,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OpGetRequest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OpGetRequest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs index c9632d351d20..22b3ed7b67f9 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,7 +20,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, OpGetResponse @@ -39,7 +41,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -47,7 +50,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -59,7 +63,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -67,21 +85,17 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -118,25 +132,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -150,22 +176,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_op_get_request: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_op_get_request) => param_op_get_request, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter OpGetRequest - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter OpGetRequest - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter OpGetRequest due to schema")), } + } else { None }; @@ -173,7 +200,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_op_get_request) => param_op_get_request, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter OpGetRequest")) + .body(BoxBody::new("Missing required body parameter OpGetRequest".to_string())) .expect("Unable to create Bad Request response for missing body parameter OpGetRequest")), }; @@ -182,7 +209,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_op_get_request, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -191,7 +218,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -206,7 +233,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -214,14 +241,14 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, _ if path.matched(paths::ID_OP) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/no-example-v3/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/no-example-v3/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/openapi-v3/.cargo/config.toml b/samples/server/petstore/rust-server/output/openapi-v3/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/openapi-v3/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/openapi-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/openapi-v3/.openapi-generator/FILES index 5f799d4f657d..7025e5bf9838 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/openapi-v3/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml index 4f8d249eb265..931919cbd406 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml @@ -12,79 +12,86 @@ default = ["client", "server"] client = [ "serde_urlencoded", "serde_ignored", "regex", "percent-encoding", "lazy_static", - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "native-tls", "hyper-openssl", "hyper-tls", "openssl", "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # TODO: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} -uuid = {version = "1.3.1", features = ["serde", "v4"]} +uuid = { version = "1.17.0", features = ["serde", "v4"]} # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific -serde_urlencoded = {version = "0.6.1", optional = true} +serde_urlencoded = { version = "0.6.1", optional = true } +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/openapi-v3/README.md b/samples/server/petstore/rust-server/output/openapi-v3/README.md index 89ec8eff87c5..674a864139d1 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/README.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/README.md @@ -89,6 +89,7 @@ To run a client, follow one of the following simple steps: cargo run --example client AnyOfGet cargo run --example client CallbackWithHeaderPost cargo run --example client ComplexQueryParamGet +cargo run --example client ExamplesTest cargo run --example client FormTest cargo run --example client GetWithBooleanParameter cargo run --example client JsonComplexQueryParamGet @@ -153,6 +154,7 @@ Method | HTTP request | Description [****](docs/default_api.md#) | **GET** /any-of | [****](docs/default_api.md#) | **POST** /callback-with-header | [****](docs/default_api.md#) | **GET** /complex-query-param | +[**ExamplesTest**](docs/default_api.md#ExamplesTest) | **GET** /examples-test | Test examples [**FormTest**](docs/default_api.md#FormTest) | **POST** /form-test | Test a Form Post [**GetWithBooleanParameter**](docs/default_api.md#GetWithBooleanParameter) | **GET** /get-with-bool | [****](docs/default_api.md#) | **GET** /json-complex-query-param | diff --git a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml index c639270b3c37..326b81e29b6f 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml +++ b/samples/server/petstore/rust-server/output/openapi-v3/api/openapi.yaml @@ -538,7 +538,58 @@ paths: "200": description: OK summary: Test a Form Post + /examples-test: + get: + description: Test examples in OpenAPI + operationId: ExamplesTest + parameters: + - description: A list of IDs to get + examples: + oneId: + value: + - foo + multipleIds: + value: + - foo + - bar + explode: false + in: query + name: ids + required: false + schema: + items: + type: string + type: array + style: form + responses: + "200": + content: + application/json: + schema: + $ref: "#/components/schemas/AdditionalPropertiesReferencedAnyOfObject" + description: OK + summary: Test examples components: + parameters: + ids: + description: A list of IDs to get + examples: + oneId: + value: + - foo + multipleIds: + value: + - foo + - bar + explode: false + in: query + name: ids + required: false + schema: + items: + type: string + type: array + style: form schemas: AnyOfProperty: description: Test containing an anyOf object diff --git a/samples/server/petstore/rust-server/output/openapi-v3/bin/cli.rs b/samples/server/petstore/rust-server/output/openapi-v3/bin/cli.rs index fcfb954b6c84..1df4255024eb 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -8,6 +9,7 @@ use openapi_v3::{ AnyOfGetResponse, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, + ExamplesTestResponse, FormTestResponse, GetWithBooleanParameterResponse, JsonComplexQueryParamGetResponse, @@ -37,7 +39,6 @@ use openapi_v3::{ GetRepoInfoResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -47,73 +48,79 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "My title", version = "1.0.7", about = "CLI access to My title" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, /// Bearer token if used for authentication - #[structopt(env = "OPENAPI_V3_BEARER_TOKEN", hide_env_values = true)] + #[arg(env = "OPENAPI_V3_BEARER_TOKEN", hide_env = true)] bearer_token: Option, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { AnyOfGet { /// list of any of objects - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] any_of: Option>, }, CallbackWithHeaderPost { url: String, }, ComplexQueryParamGet { - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] list_of_strings: Option>, }, + /// Test examples + ExamplesTest { + /// A list of IDs to get + #[clap(value_parser = parse_json::>, long)] + ids: Option>, + }, /// Test a Form Post FormTest { - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] required_array: Option>, }, GetWithBooleanParameter { /// Let's check apostrophes get encoded properly! - #[structopt(short, long)] + #[clap(short, long)] iambool: bool, }, JsonComplexQueryParamGet { - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] list_of_strings: Option>, }, MandatoryRequestHeaderGet { @@ -133,13 +140,13 @@ enum Operation { /// Get some stuff with parameters. ParamgetGet { /// The stuff to get - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] uuid: Option, /// Some object to pass as query parameter - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] some_object: Option, /// Some list to pass as query parameter - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] some_list: Option, }, ReadonlyAuthSchemeGet { @@ -148,7 +155,7 @@ enum Operation { url: String, }, RequiredOctetStreamPut { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: swagger::ByteArray, }, ResponsesWithHeadersGet { @@ -156,40 +163,40 @@ enum Operation { Rfc7807Get { }, TwoFirstLetterHeaders { - #[structopt(long)] + #[clap(long)] x_header_one: Option, - #[structopt(long)] + #[clap(long)] x_header_two: Option, }, UntypedPropertyGet { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] object_untyped_props: Option, }, UuidGet { }, XmlExtraPost { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] duplicate_xml_object: Option, }, XmlOtherPost { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] another_xml_object: Option, }, XmlOtherPut { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] another_xml_array: Option, }, /// Post an array. It's important we test apostrophes, so include one here. XmlPost { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] xml_array: Option, }, XmlPut { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] xml_object: Option, }, EnumInPathPathParamGet { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] path_param: models::StringEnum, }, MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet { @@ -197,7 +204,7 @@ enum Operation { path_param_b: String, }, CreateRepo { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] object_param: models::ObjectParam, }, GetRepoInfo { @@ -240,7 +247,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -251,7 +258,7 @@ async fn main() -> Result<()> { if let Some(ref bearer_token) = args.bearer_token { debug!("Using bearer token"); - auth_data = Some(AuthData::bearer(bearer_token)); + auth_data = AuthData::bearer(bearer_token); } #[allow(trivial_casts)] @@ -325,6 +332,24 @@ async fn main() -> Result<()> { , } } + Operation::ExamplesTest { + ids, + } => { + info!("Performing a ExamplesTest request"); + + let result = client.examples_test( + ids.as_ref(), + ).await?; + debug!("Result: {:?}", result); + + match result { + ExamplesTestResponse::OK + (body) + => "OK\n".to_string() + + + &serde_json::to_string_pretty(&body)?, + } + } Operation::FormTest { required_array, } => { @@ -871,6 +896,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md index b48d91600ffc..9ec0b3c33516 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/docs/default_api.md @@ -7,6 +7,7 @@ Method | HTTP request | Description ****](default_api.md#) | **GET** /any-of | ****](default_api.md#) | **POST** /callback-with-header | ****](default_api.md#) | **GET** /complex-query-param | +**ExamplesTest**](default_api.md#ExamplesTest) | **GET** /examples-test | Test examples **FormTest**](default_api.md#FormTest) | **POST** /form-test | Test a Form Post **GetWithBooleanParameter**](default_api.md#GetWithBooleanParameter) | **GET** /get-with-bool | ****](default_api.md#) | **GET** /json-complex-query-param | @@ -123,6 +124,40 @@ No authorization required [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **ExamplesTest** +> models::AdditionalPropertiesReferencedAnyOfObject ExamplesTest(optional) +Test examples + +Test examples in OpenAPI + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **optional** | **map[string]interface{}** | optional parameters | nil if no parameters + +### Optional Parameters +Optional parameters are passed through a map[string]interface{}. + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ids** | [**String**](String.md)| A list of IDs to get | + +### Return type + +[**models::AdditionalPropertiesReferencedAnyOfObject**](AdditionalPropertiesReferencedAnyOfObject.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **FormTest** > FormTest(optional) Test a Form Post diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs index 44797b0f7951..c0140794489b 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/main.rs @@ -9,6 +9,7 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, AnyOfGetResponse, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, + ExamplesTestResponse, FormTestResponse, GetWithBooleanParameterResponse, JsonComplexQueryParamGetResponse, @@ -37,7 +38,7 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, CreateRepoResponse, GetRepoInfoResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -60,13 +61,14 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ "AnyOfGet", "CallbackWithHeaderPost", "ComplexQueryParamGet", + "ExamplesTest", "FormTest", "GetWithBooleanParameter", "JsonComplexQueryParamGet", @@ -90,23 +92,22 @@ fn main() { "XmlOtherPut", "XmlPost", "XmlPut", + "EnumInPathPathParamGet", "MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet", "CreateRepo", "GetRepoInfo", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -135,22 +136,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -168,7 +169,7 @@ fn main() { // We could do HTTPS here, but for simplicity we don't rt.spawn(server::create("127.0.0.1:8081", false)); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { Some("AnyOfGet") => { let result = rt.block_on(client.any_of_get( Some(&Vec::new()) @@ -187,6 +188,12 @@ fn main() { )); info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); }, + Some("ExamplesTest") => { + let result = rt.block_on(client.examples_test( + Some(&vec!["foo".to_string()]) + )); + info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); + }, Some("FormTest") => { let result = rt.block_on(client.form_test( Some(&Vec::new()) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs index fc466245a56d..6a136da4e50c 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/client/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use openapi_v3::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use openapi_v3::CallbackApi; use openapi_v3::CallbackCallbackWithHeaderPostResponse; use openapi_v3::CallbackCallbackPostResponse; diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs index 08af24903e54..65a3a706bb43 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs index 1c0537f1df86..bc8a98341705 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use openapi_v3::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; @@ -105,6 +142,7 @@ use openapi_v3::{ AnyOfGetResponse, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, + ExamplesTestResponse, FormTestResponse, GetWithBooleanParameterResponse, JsonComplexQueryParamGetResponse, @@ -167,6 +205,16 @@ impl Api for Server where C: Has + Send + Sync Err(ApiError("Api-Error: Operation is NOT implemented".into())) } + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + context: &C) -> Result + { + info!("examples_test({:?}) - X-Span-ID: {:?}", ids, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + /// Test a Form Post async fn form_test( &self, diff --git a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server_auth.rs index 1c9b18394f21..794d112a3e5c 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use openapi_v3::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -92,7 +92,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -129,4 +129,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/auth.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/auth.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs index 97198a90b7eb..df0d62a45b6b 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/callbacks.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,7 +20,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::CallbackApi as Api; use crate::CallbackCallbackWithHeaderPostResponse; @@ -52,7 +54,8 @@ mod paths { -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -60,7 +63,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -72,7 +76,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -80,11 +98,7 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) @@ -92,10 +106,10 @@ impl hyper::service::Service for MakeService where } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -132,25 +146,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -181,7 +207,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header Information - {}", err))) + .body(body_from_string(format!("Invalid header Information - {err}"))) .expect("Unable to create Bad Request response for invalid header Information")); }, @@ -196,7 +222,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_information, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -214,7 +240,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -237,7 +263,7 @@ impl hyper::service::Service<(Request, C)> for Service where callback_request_query_url, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -255,7 +281,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -265,7 +291,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK) => method_not_allowed(), _ if path.matched(paths::ID_REQUEST_QUERY_URL_CALLBACK_WITH_HEADER) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs index d90cd75e2e2f..90ea467c4bca 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -39,6 +42,7 @@ use crate::{Api, AnyOfGetResponse, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, + ExamplesTestResponse, FormTestResponse, GetWithBooleanParameterResponse, JsonComplexQueryParamGetResponse, @@ -85,15 +89,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -110,8 +113,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -123,8 +125,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -138,8 +139,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -153,7 +165,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -162,8 +174,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -175,26 +187,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -205,7 +210,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -218,13 +223,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -241,13 +246,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -258,18 +274,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -282,7 +309,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -303,7 +330,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -331,8 +358,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -394,29 +420,32 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Has> + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn any_of_get( &self, param_any_of: Option<&Vec>, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/any-of", self.base_path @@ -438,37 +467,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(AnyOfGetResponse::Success @@ -477,14 +507,15 @@ impl Api for Client where } 201 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(AnyOfGetResponse::AlternateSuccess @@ -493,14 +524,15 @@ impl Api for Client where } 202 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(AnyOfGetResponse::AnyOfSuccess @@ -509,30 +541,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn callback_with_header_post( &self, param_url: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/callback-with-header", self.base_path @@ -552,25 +584,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -580,30 +612,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn complex_query_param_get( &self, param_list_of_strings: Option<&Vec>, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/complex-query-param", self.base_path @@ -625,25 +657,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -653,30 +685,115 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", + match body { + Ok(body) => match String::from_utf8(body) { + Ok(body) => body, + Err(e) => format!(""), + }, + Err(e) => format!("", Into::::into(e)), + } + ))) + } + } + } + + #[allow(clippy::vec_init_then_push)] + async fn examples_test( + &self, + param_ids: Option<&Vec>, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/examples-test", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + if let Some(param_ids) = param_ids { + query_string.append_pair("ids", + ¶m_ids.iter().map(ToString::to_string).collect::>().join(",")); + } + query_string.finish() + }; + if !query_string.is_empty() { + uri += "?"; + uri += &query_string; + } + + let uri = match Uri::from_str(&uri) { + Ok(uri) => uri, + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), + }; + + let mut request = match Request::builder() + .method("GET") + .uri(uri) + .body(BoxBody::new(http_body_util::Empty::new())) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + let header = HeaderValue::from_str(Has::::get(context).0.as_str()); + request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { + Ok(h) => h, + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) + }); + + let response = client_service.call((request, context.clone())) + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; + + match response.status().as_u16() { + 200 => { + let body = response.into_body(); + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; + + let body = str::from_utf8(&body) + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; + let body = serde_json::from_str::(body) + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; + + + Ok(ExamplesTestResponse::OK + (body) + ) + } + code => { + let headers = response.headers().clone(); + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn form_test( &self, param_required_array: Option<&Vec>, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/form-test", self.base_path @@ -694,15 +811,15 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes form body @@ -710,6 +827,7 @@ impl Api for Client where if let Some(param_required_array) = param_required_array { // style=form,explode=true for param_required_array in param_required_array { + #[allow(clippy::uninlined_format_args)] params.push(("requiredArray", format!("{:?}", param_required_array) )); @@ -718,22 +836,22 @@ impl Api for Client where let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -743,30 +861,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_with_boolean_parameter( &self, param_iambool: bool, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/get-with-bool", self.base_path @@ -786,25 +904,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -814,30 +932,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn json_complex_query_param_get( &self, param_list_of_strings: Option<&Vec>, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/json-complex-query-param", self.base_path @@ -850,7 +968,7 @@ impl Api for Client where query_string.append_pair("list-of-strings", &match serde_json::to_string(¶m_list_of_strings) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize list_of_strings to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize list_of_strings to string: {e}"))), }); } query_string.finish() @@ -862,25 +980,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -890,30 +1008,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn mandatory_request_header_get( &self, param_x_header: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/mandatory-request-header", self.base_path @@ -931,37 +1049,37 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); // Header parameters request.headers_mut().append( HeaderName::from_static("x-header"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_x_header.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header x_header - {}", e))); + "Invalid header x_header - {e}"))); }, }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -971,29 +1089,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn merge_patch_json_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/merge-patch-json", self.base_path @@ -1011,37 +1129,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MergePatchJsonGetResponse::Merge @@ -1050,29 +1169,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn multiget_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multiget", self.base_path @@ -1090,37 +1209,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MultigetGetResponse::JSONRsp @@ -1129,16 +1249,17 @@ impl Api for Client where } 201 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MultigetGetResponse::XMLRsp @@ -1147,9 +1268,10 @@ impl Api for Client where } 202 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = swagger::ByteArray(body.to_vec()); @@ -1160,12 +1282,13 @@ impl Api for Client where } 203 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = body.to_string(); @@ -1175,14 +1298,15 @@ impl Api for Client where } 204 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MultigetGetResponse::DuplicateResponseLongText @@ -1191,14 +1315,15 @@ impl Api for Client where } 205 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MultigetGetResponse::DuplicateResponseLongText_2 @@ -1207,14 +1332,15 @@ impl Api for Client where } 206 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(MultigetGetResponse::DuplicateResponseLongText_3 @@ -1223,29 +1349,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn multiple_auth_scheme_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multiple_auth_scheme", self.base_path @@ -1263,43 +1389,43 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1309,29 +1435,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn one_of_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/one-of", self.base_path @@ -1349,37 +1475,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(OneOfGetResponse::Success @@ -1388,29 +1515,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn override_server_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/override/override-server", self.base_path @@ -1428,25 +1555,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -1456,24 +1583,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn paramget_get( &self, param_uuid: Option, @@ -1482,6 +1608,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/paramget", self.base_path @@ -1511,37 +1638,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(ParamgetGetResponse::JSONRsp @@ -1550,29 +1678,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn readonly_auth_scheme_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/readonly_auth_scheme", self.base_path @@ -1590,43 +1718,43 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1636,30 +1764,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn register_callback_post( &self, param_url: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/register-callback", self.base_path @@ -1679,25 +1807,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -1707,30 +1835,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn required_octet_stream_put( &self, param_body: swagger::ByteArray, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/required_octet_stream", self.base_path @@ -1748,36 +1876,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter - let body = param_body.0; - *request.body_mut() = Body::from(body); + let body = String::from_utf8(param_body.0).expect("Body was not valid UTF8"); + *request.body_mut() = body_from_string(body); let header = "application/octet-stream"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1787,29 +1915,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn responses_with_headers_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/responses_with_headers", self.base_path @@ -1827,25 +1955,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1855,7 +1983,7 @@ impl Api for Client where let response_success_info = match TryInto::>::try_into(response_success_info) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header Success-Info for response 200 - {}", e))); + return Err(ApiError(format!("Invalid response header Success-Info for response 200 - {e}"))); }, }; response_success_info.0 @@ -1869,7 +1997,7 @@ impl Api for Client where let response_bool_header = match TryInto::>::try_into(response_bool_header) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header Bool-Header for response 200 - {}", e))); + return Err(ApiError(format!("Invalid response header Bool-Header for response 200 - {e}"))); }, }; Some(response_bool_header.0) @@ -1883,7 +2011,7 @@ impl Api for Client where let response_object_header = match TryInto::>::try_into(response_object_header) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header Object-Header for response 200 - {}", e))); + return Err(ApiError(format!("Invalid response header Object-Header for response 200 - {e}"))); }, }; Some(response_object_header.0) @@ -1892,14 +2020,15 @@ impl Api for Client where }; let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(ResponsesWithHeadersGetResponse::Success @@ -1918,7 +2047,7 @@ impl Api for Client where let response_further_info = match TryInto::>::try_into(response_further_info) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header Further-Info for response 412 - {}", e))); + return Err(ApiError(format!("Invalid response header Further-Info for response 412 - {e}"))); }, }; Some(response_further_info.0) @@ -1932,7 +2061,7 @@ impl Api for Client where let response_failure_info = match TryInto::>::try_into(response_failure_info) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header Failure-Info for response 412 - {}", e))); + return Err(ApiError(format!("Invalid response header Failure-Info for response 412 - {e}"))); }, }; Some(response_failure_info.0) @@ -1950,29 +2079,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn rfc7807_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/rfc7807", self.base_path @@ -1990,37 +2119,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(Rfc7807GetResponse::OK @@ -2029,14 +2159,15 @@ impl Api for Client where } 404 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(Rfc7807GetResponse::NotFound @@ -2045,16 +2176,17 @@ impl Api for Client where } 406 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(Rfc7807GetResponse::NotAcceptable @@ -2063,24 +2195,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn two_first_letter_headers( &self, param_x_header_one: Option, @@ -2088,6 +2219,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/operation-two-first-letter-headers", self.base_path @@ -2105,21 +2237,21 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); // Header parameters @@ -2128,12 +2260,12 @@ impl Api for Client where Some(param_x_header_one) => { request.headers_mut().append( HeaderName::from_static("x-header-one"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_x_header_one.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header x_header_one - {}", e))); + "Invalid header x_header_one - {e}"))); }, }); }, @@ -2145,12 +2277,12 @@ impl Api for Client where Some(param_x_header_two) => { request.headers_mut().append( HeaderName::from_static("x-header-two"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_x_header_two.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header x_header_two - {}", e))); + "Invalid header x_header_two - {e}"))); }, }); }, @@ -2158,7 +2290,7 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2168,30 +2300,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn untyped_property_get( &self, param_object_untyped_props: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/untyped_property", self.base_path @@ -2209,38 +2341,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_object_untyped_props) = param_object_untyped_props { let body = serde_json::to_string(¶m_object_untyped_props).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2250,29 +2382,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn uuid_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/uuid", self.base_path @@ -2290,37 +2422,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(UuidGetResponse::DuplicateResponseLongText @@ -2329,30 +2462,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn xml_extra_post( &self, param_duplicate_xml_object: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/xml_extra", self.base_path @@ -2370,38 +2503,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_duplicate_xml_object) = param_duplicate_xml_object { let body = param_duplicate_xml_object.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -2416,30 +2549,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn xml_other_post( &self, param_another_xml_object: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/xml_other", self.base_path @@ -2457,52 +2590,53 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_another_xml_object) = param_another_xml_object { let body = param_another_xml_object.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "text/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(XmlOtherPostResponse::OK @@ -2516,30 +2650,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn xml_other_put( &self, param_another_xml_array: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/xml_other", self.base_path @@ -2557,38 +2691,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_another_xml_array) = param_another_xml_array { let body = param_another_xml_array.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -2603,30 +2737,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn xml_post( &self, param_xml_array: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/xml", self.base_path @@ -2644,38 +2778,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_xml_array) = param_xml_array { let body = param_xml_array.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -2690,30 +2824,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn xml_put( &self, param_xml_object: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/xml", self.base_path @@ -2731,38 +2865,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_xml_object) = param_xml_object { let body = param_xml_object.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/xml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -2777,30 +2911,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn enum_in_path_path_param_get( &self, param_path_param: models::StringEnum, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/enum_in_path/{path_param}", self.base_path @@ -2819,25 +2953,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2847,24 +2981,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn multiple_path_params_with_very_long_path_to_test_formatting_path_param_a_path_param_b_get( &self, param_path_param_a: String, @@ -2872,6 +3005,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/multiple-path-params-with-very-long-path-to-test-formatting/{path_param_a}/{path_param_b}", self.base_path @@ -2891,25 +3025,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2919,30 +3053,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn create_repo( &self, param_object_param: models::ObjectParam, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/repos", self.base_path @@ -2960,36 +3094,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_object_param).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2999,30 +3133,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_repo_info( &self, param_repo_id: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/repos/{repo_id}", self.base_path @@ -3041,37 +3175,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(GetRepoInfoResponse::OK @@ -3080,18 +3215,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs index 2b3485f7bbe8..a7ec3155349e 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,68 +87,41 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); { - use swagger::auth::Bearer; + use headers::authorization::Bearer; use std::ops::Deref; - if let Some(bearer) = swagger::auth::from_headers::(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } } { - use swagger::auth::Bearer; + use headers::authorization::Bearer; use std::ops::Deref; - if let Some(bearer) = swagger::auth::from_headers::(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } } let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/header.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/header.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs index d6616df1fdc7..07dbe1f5bdd2 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/lib.rs @@ -48,6 +48,13 @@ pub enum ComplexQueryParamGetResponse { Success } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum ExamplesTestResponse { + /// OK + OK + (models::AdditionalPropertiesReferencedAnyOfObject) +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] pub enum FormTestResponse { /// OK @@ -306,10 +313,6 @@ pub enum GetRepoInfoResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn any_of_get( &self, any_of: Option<&Vec>, @@ -325,6 +328,12 @@ pub trait Api { list_of_strings: Option<&Vec>, context: &C) -> Result; + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + context: &C) -> Result; + /// Test a Form Post async fn form_test( &self, @@ -466,8 +475,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn any_of_get( @@ -485,6 +492,12 @@ pub trait ApiNoContext { list_of_strings: Option<&Vec>, ) -> Result; + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + ) -> Result; + /// Test a Form Post async fn form_test( &self, @@ -636,10 +649,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } @@ -671,6 +680,16 @@ impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for Contex self.api().complex_query_param_get(list_of_strings, &context).await } + /// Test examples + async fn examples_test( + &self, + ids: Option<&Vec>, + ) -> Result + { + let context = self.context().clone(); + self.api().examples_test(ids, &context).await + } + /// Test a Form Post async fn form_test( &self, @@ -932,9 +951,6 @@ pub enum CallbackCallbackPostResponse { /// Callback API #[async_trait] pub trait CallbackApi { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } async fn callback_callback_with_header_post( &self, @@ -952,7 +968,6 @@ pub trait CallbackApi { /// Callback API without a `Context` #[async_trait] pub trait CallbackApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; fn context(&self) -> &C; @@ -983,9 +998,6 @@ impl + Send + Sync, C: Clone + Send + Sync> CallbackContextWra #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> CallbackApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } fn context(&self) -> &C { ContextWrapper::context(self) diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs index df40ebcf12a2..de464d40b9c6 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/models.rs @@ -37,17 +37,17 @@ impl std::ops::DerefMut for AdditionalPropertiesReferencedAnyOfObject { } /// Converts the AdditionalPropertiesReferencedAnyOfObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AdditionalPropertiesReferencedAnyOfObject { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AdditionalPropertiesReferencedAnyOfObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesReferencedAnyOfObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AdditionalPropertiesReferencedAnyOfObject { type Err = &'static str; @@ -68,8 +68,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AdditionalPropertiesReferencedAnyOfObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AdditionalPropertiesReferencedAnyOfObject - value: {hdr_value} is invalid {e}")) } } } @@ -84,13 +83,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesReferencedAnyOfObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AdditionalPropertiesReferencedAnyOfObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -106,8 +103,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -127,16 +123,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesReferencedAnyOfObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesReferencedAnyOfObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -180,17 +174,17 @@ impl std::ops::DerefMut for AdditionalPropertiesWithList { } /// Converts the AdditionalPropertiesWithList value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AdditionalPropertiesWithList { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AdditionalPropertiesWithList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesWithList value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AdditionalPropertiesWithList { type Err = &'static str; @@ -211,8 +205,7 @@ impl std::convert::TryFrom match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AdditionalPropertiesWithList - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AdditionalPropertiesWithList - value: {hdr_value} is invalid {e}")) } } } @@ -227,13 +220,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesWithList - {}", - value, err)) + format!("Unable to convert header value '{value}' into AdditionalPropertiesWithList - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -249,8 +240,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -270,16 +260,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesWithList - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesWithList - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -320,10 +308,10 @@ impl AdditionalPropertiesWithNullable { } /// Converts the AdditionalPropertiesWithNullable value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AdditionalPropertiesWithNullable { - fn to_string(&self) -> String { +impl std::fmt::Display for AdditionalPropertiesWithNullable { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.nullable_string.as_ref().map(|nullable_string| { [ @@ -334,12 +322,12 @@ impl std::string::ToString for AdditionalPropertiesWithNullable { // Skipping map nullableMap in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesWithNullable value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AdditionalPropertiesWithNullable { type Err = String; @@ -397,8 +385,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AdditionalPropertiesWithNullable - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AdditionalPropertiesWithNullable - value: {hdr_value} is invalid {e}")) } } } @@ -413,13 +400,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesWithNullable - {}", - value, err)) + format!("Unable to convert header value '{value}' into AdditionalPropertiesWithNullable - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -435,8 +420,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -456,16 +440,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesWithNullable - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesWithNullable - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -554,16 +536,16 @@ impl std::ops::DerefMut for AnotherXmlArray { } /// Converts the AnotherXmlArray value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AnotherXmlArray { - fn to_string(&self) -> String { - self.iter().map(|x| x.to_string()).collect::>().join(",") +impl std::fmt::Display for AnotherXmlArray { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.iter().map(|x| x.to_string()).collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AnotherXmlArray value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AnotherXmlArray { type Err = ::Err; @@ -590,8 +572,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnotherXmlArray - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnotherXmlArray - value: {hdr_value} is invalid {e}")) } } } @@ -606,13 +587,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlArray - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnotherXmlArray - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -628,8 +607,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -649,16 +627,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlArray - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnotherXmlArray - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -702,9 +678,9 @@ impl std::ops::DerefMut for AnotherXmlInner { } } -impl std::string::ToString for AnotherXmlInner { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for AnotherXmlInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -726,8 +702,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnotherXmlInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnotherXmlInner - value: {hdr_value} is invalid {e}")) } } } @@ -742,13 +717,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnotherXmlInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -764,8 +737,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -785,16 +757,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnotherXmlInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -830,10 +800,10 @@ impl AnotherXmlObject { } /// Converts the AnotherXmlObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AnotherXmlObject { - fn to_string(&self) -> String { +impl std::fmt::Display for AnotherXmlObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.inner_string.as_ref().map(|inner_string| { [ @@ -843,12 +813,12 @@ impl std::string::ToString for AnotherXmlObject { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AnotherXmlObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AnotherXmlObject { type Err = String; @@ -904,8 +874,7 @@ impl std::convert::TryFrom> for hyper: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnotherXmlObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnotherXmlObject - value: {hdr_value} is invalid {e}")) } } } @@ -920,13 +889,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnotherXmlObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -942,8 +909,7 @@ impl std::convert::TryFrom>> for h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -963,16 +929,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnotherXmlObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnotherXmlObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1025,17 +989,17 @@ impl std::ops::DerefMut for AnyOfGet202Response { } /// Converts the AnyOfGet202Response value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AnyOfGet202Response { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AnyOfGet202Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AnyOfGet202Response value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AnyOfGet202Response { type Err = &'static str; @@ -1056,8 +1020,7 @@ impl std::convert::TryFrom> for hyp match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnyOfGet202Response - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnyOfGet202Response - value: {hdr_value} is invalid {e}")) } } } @@ -1072,13 +1035,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfGet202Response - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnyOfGet202Response - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1094,8 +1055,7 @@ impl std::convert::TryFrom>> fo match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1115,16 +1075,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfGet202Response - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnyOfGet202Response - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1169,17 +1127,17 @@ impl std::ops::DerefMut for AnyOfHashMapObject { } /// Converts the AnyOfHashMapObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AnyOfHashMapObject { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AnyOfHashMapObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AnyOfHashMapObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AnyOfHashMapObject { type Err = &'static str; @@ -1200,8 +1158,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnyOfHashMapObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnyOfHashMapObject - value: {hdr_value} is invalid {e}")) } } } @@ -1216,13 +1173,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfHashMapObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnyOfHashMapObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1238,8 +1193,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1259,16 +1213,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfHashMapObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnyOfHashMapObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1313,17 +1265,17 @@ impl std::ops::DerefMut for AnyOfObject { } /// Converts the AnyOfObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AnyOfObject { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AnyOfObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AnyOfObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AnyOfObject { type Err = &'static str; @@ -1344,8 +1296,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnyOfObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnyOfObject - value: {hdr_value} is invalid {e}")) } } } @@ -1360,13 +1311,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnyOfObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1382,8 +1331,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1403,16 +1351,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnyOfObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1456,7 +1402,7 @@ impl std::str::FromStr for AnyOfObjectAnyOf { match s { "FOO" => std::result::Result::Ok(AnyOfObjectAnyOf::Foo), "BAR" => std::result::Result::Ok(AnyOfObjectAnyOf::Bar), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -1472,8 +1418,7 @@ impl std::convert::TryFrom> for hyper: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnyOfObjectAnyOf - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnyOfObjectAnyOf - value: {hdr_value} is invalid {e}")) } } } @@ -1488,13 +1433,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfObjectAnyOf - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnyOfObjectAnyOf - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1510,8 +1453,7 @@ impl std::convert::TryFrom>> for h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1531,16 +1473,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfObjectAnyOf - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnyOfObjectAnyOf - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1579,21 +1519,21 @@ impl AnyOfProperty { } /// Converts the AnyOfProperty value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AnyOfProperty { - fn to_string(&self) -> String { +impl std::fmt::Display for AnyOfProperty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type requiredAnyOf in query parameter serialization // Skipping non-primitive type optionalAnyOf in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AnyOfProperty value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AnyOfProperty { type Err = String; @@ -1653,8 +1593,7 @@ impl std::convert::TryFrom> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnyOfProperty - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnyOfProperty - value: {hdr_value} is invalid {e}")) } } } @@ -1669,13 +1608,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfProperty - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnyOfProperty - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1691,8 +1628,7 @@ impl std::convert::TryFrom>> for hype match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1712,16 +1648,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnyOfProperty - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnyOfProperty - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1762,10 +1696,10 @@ impl DuplicateXmlObject { } /// Converts the DuplicateXmlObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for DuplicateXmlObject { - fn to_string(&self) -> String { +impl std::fmt::Display for DuplicateXmlObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.inner_string.as_ref().map(|inner_string| { [ @@ -1776,12 +1710,12 @@ impl std::string::ToString for DuplicateXmlObject { // Skipping non-primitive type inner_array in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a DuplicateXmlObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for DuplicateXmlObject { type Err = String; @@ -1841,8 +1775,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for DuplicateXmlObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for DuplicateXmlObject - value: {hdr_value} is invalid {e}")) } } } @@ -1857,13 +1790,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DuplicateXmlObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into DuplicateXmlObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1879,8 +1810,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1900,16 +1830,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DuplicateXmlObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into DuplicateXmlObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1967,7 +1895,7 @@ impl std::str::FromStr for EnumWithStarObject { "FOO" => std::result::Result::Ok(EnumWithStarObject::Foo), "BAR" => std::result::Result::Ok(EnumWithStarObject::Bar), "*" => std::result::Result::Ok(EnumWithStarObject::Star), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -1983,8 +1911,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumWithStarObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumWithStarObject - value: {hdr_value} is invalid {e}")) } } } @@ -1999,13 +1926,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumWithStarObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumWithStarObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2021,8 +1946,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2042,16 +1966,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumWithStarObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumWithStarObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2094,9 +2016,9 @@ impl std::ops::DerefMut for Err { } } -impl std::string::ToString for Err { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for Err { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -2118,8 +2040,7 @@ impl std::convert::TryFrom> for hyper::header::Head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Err - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Err - value: {hdr_value} is invalid {e}")) } } } @@ -2134,13 +2055,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Err - {}", - value, err)) + format!("Unable to convert header value '{value}' into Err - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2156,8 +2075,7 @@ impl std::convert::TryFrom>> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2177,16 +2095,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Err - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Err - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2229,9 +2145,9 @@ impl std::ops::DerefMut for Error { } } -impl std::string::ToString for Error { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -2253,8 +2169,7 @@ impl std::convert::TryFrom> for hyper::header::He match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Error - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Error - value: {hdr_value} is invalid {e}")) } } } @@ -2269,13 +2184,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Error - {}", - value, err)) + format!("Unable to convert header value '{value}' into Error - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2291,8 +2204,7 @@ impl std::convert::TryFrom>> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2312,16 +2224,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Error - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Error - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2366,17 +2276,17 @@ impl std::ops::DerefMut for Model12345AnyOfObject { } /// Converts the Model12345AnyOfObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for Model12345AnyOfObject { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for Model12345AnyOfObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a Model12345AnyOfObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for Model12345AnyOfObject { type Err = &'static str; @@ -2397,8 +2307,7 @@ impl std::convert::TryFrom> for h match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Model12345AnyOfObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Model12345AnyOfObject - value: {hdr_value} is invalid {e}")) } } } @@ -2413,13 +2322,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model12345AnyOfObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into Model12345AnyOfObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2435,8 +2342,7 @@ impl std::convert::TryFrom>> match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2456,16 +2362,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model12345AnyOfObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Model12345AnyOfObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2513,7 +2417,7 @@ impl std::str::FromStr for Model12345AnyOfObjectAnyOf { "FOO" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Foo), "BAR" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Bar), "*" => std::result::Result::Ok(Model12345AnyOfObjectAnyOf::Star), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -2529,8 +2433,7 @@ impl std::convert::TryFrom> match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Model12345AnyOfObjectAnyOf - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Model12345AnyOfObjectAnyOf - value: {hdr_value} is invalid {e}")) } } } @@ -2545,13 +2448,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model12345AnyOfObjectAnyOf - {}", - value, err)) + format!("Unable to convert header value '{value}' into Model12345AnyOfObjectAnyOf - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2567,8 +2468,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2588,16 +2488,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model12345AnyOfObjectAnyOf - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Model12345AnyOfObjectAnyOf - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2631,10 +2529,10 @@ impl MultigetGet201Response { } /// Converts the MultigetGet201Response value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MultigetGet201Response { - fn to_string(&self) -> String { +impl std::fmt::Display for MultigetGet201Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.foo.as_ref().map(|foo| { [ @@ -2644,12 +2542,12 @@ impl std::string::ToString for MultigetGet201Response { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MultigetGet201Response value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MultigetGet201Response { type Err = String; @@ -2705,8 +2603,7 @@ impl std::convert::TryFrom> for match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MultigetGet201Response - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MultigetGet201Response - value: {hdr_value} is invalid {e}")) } } } @@ -2721,13 +2618,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultigetGet201Response - {}", - value, err)) + format!("Unable to convert header value '{value}' into MultigetGet201Response - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2743,8 +2638,7 @@ impl std::convert::TryFrom>> match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2764,16 +2658,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MultigetGet201Response - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MultigetGet201Response - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2817,16 +2709,16 @@ impl std::ops::DerefMut for MyId { } /// Converts the MyId value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for MyId { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for MyId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a MyId value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for MyId { type Err = String; @@ -2834,7 +2726,7 @@ impl ::std::str::FromStr for MyId { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(MyId(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to MyId: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to MyId: {e:?}")), } } } @@ -2850,8 +2742,7 @@ impl std::convert::TryFrom> for hyper::header::Hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MyId - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MyId - value: {hdr_value} is invalid {e}")) } } } @@ -2866,13 +2757,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MyId - {}", - value, err)) + format!("Unable to convert header value '{value}' into MyId - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2888,8 +2777,7 @@ impl std::convert::TryFrom>> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2909,16 +2797,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MyId - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MyId - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2997,16 +2883,16 @@ impl std::ops::DerefMut for MyIdList { } /// Converts the MyIdList value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MyIdList { - fn to_string(&self) -> String { - self.iter().map(|x| x.to_string()).collect::>().join(",") +impl std::fmt::Display for MyIdList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.iter().map(|x| x.to_string()).collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MyIdList value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MyIdList { type Err = ::Err; @@ -3033,8 +2919,7 @@ impl std::convert::TryFrom> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MyIdList - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MyIdList - value: {hdr_value} is invalid {e}")) } } } @@ -3049,13 +2934,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MyIdList - {}", - value, err)) + format!("Unable to convert header value '{value}' into MyIdList - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3071,8 +2954,7 @@ impl std::convert::TryFrom>> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3092,16 +2974,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MyIdList - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MyIdList - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3144,9 +3024,9 @@ impl std::ops::DerefMut for NullableObject { } } -impl std::string::ToString for NullableObject { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for NullableObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -3168,8 +3048,7 @@ impl std::convert::TryFrom> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for NullableObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for NullableObject - value: {hdr_value} is invalid {e}")) } } } @@ -3184,13 +3063,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NullableObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into NullableObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3206,8 +3083,7 @@ impl std::convert::TryFrom>> for hyp match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3227,16 +3103,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NullableObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into NullableObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3321,10 +3195,10 @@ impl NullableTest { } /// Converts the NullableTest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for NullableTest { - fn to_string(&self) -> String { +impl std::fmt::Display for NullableTest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("nullable".to_string()), Some(self.nullable.as_ref().map_or("null".to_string(), |x| x.to_string())), @@ -3372,12 +3246,12 @@ impl std::string::ToString for NullableTest { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a NullableTest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for NullableTest { type Err = String; @@ -3453,8 +3327,7 @@ impl std::convert::TryFrom> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for NullableTest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for NullableTest - value: {hdr_value} is invalid {e}")) } } } @@ -3469,13 +3342,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NullableTest - {}", - value, err)) + format!("Unable to convert header value '{value}' into NullableTest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3491,8 +3362,7 @@ impl std::convert::TryFrom>> for hyper match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3512,16 +3382,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NullableTest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into NullableTest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3559,10 +3427,10 @@ impl ObjectHeader { } /// Converts the ObjectHeader value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectHeader { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectHeader { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("requiredObjectHeader".to_string()), Some(self.required_object_header.to_string()), @@ -3574,12 +3442,12 @@ impl std::string::ToString for ObjectHeader { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectHeader value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectHeader { type Err = String; @@ -3639,8 +3507,7 @@ impl std::convert::TryFrom> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectHeader - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectHeader - value: {hdr_value} is invalid {e}")) } } } @@ -3655,13 +3522,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectHeader - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectHeader - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3677,8 +3542,7 @@ impl std::convert::TryFrom>> for hyper match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3698,16 +3562,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectHeader - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectHeader - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3745,10 +3607,10 @@ impl ObjectParam { } /// Converts the ObjectParam value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectParam { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectParam { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("requiredParam".to_string()), Some(self.required_param.to_string()), @@ -3760,12 +3622,12 @@ impl std::string::ToString for ObjectParam { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectParam value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectParam { type Err = String; @@ -3825,8 +3687,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectParam - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectParam - value: {hdr_value} is invalid {e}")) } } } @@ -3841,13 +3702,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectParam - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectParam - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3863,8 +3722,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3884,16 +3742,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectParam - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectParam - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3940,10 +3796,10 @@ impl ObjectUntypedProps { } /// Converts the ObjectUntypedProps value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectUntypedProps { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectUntypedProps { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type required_untyped in query parameter serialization // Skipping non-primitive type required_untyped_nullable in query parameter serialization @@ -3951,12 +3807,12 @@ impl std::string::ToString for ObjectUntypedProps { // Skipping non-primitive type not_required_untyped_nullable in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectUntypedProps value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectUntypedProps { type Err = String; @@ -4023,8 +3879,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectUntypedProps - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectUntypedProps - value: {hdr_value} is invalid {e}")) } } } @@ -4039,13 +3894,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectUntypedProps - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectUntypedProps - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4061,8 +3914,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4082,16 +3934,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectUntypedProps - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectUntypedProps - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4125,10 +3975,10 @@ impl ObjectWithArrayOfObjects { } /// Converts the ObjectWithArrayOfObjects value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectWithArrayOfObjects { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectWithArrayOfObjects { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.object_array.as_ref().map(|object_array| { [ @@ -4138,12 +3988,12 @@ impl std::string::ToString for ObjectWithArrayOfObjects { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectWithArrayOfObjects value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectWithArrayOfObjects { type Err = String; @@ -4198,8 +4048,7 @@ impl std::convert::TryFrom> fo match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectWithArrayOfObjects - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectWithArrayOfObjects - value: {hdr_value} is invalid {e}")) } } } @@ -4214,13 +4063,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectWithArrayOfObjects - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectWithArrayOfObjects - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4236,8 +4083,7 @@ impl std::convert::TryFrom match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4257,16 +4103,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectWithArrayOfObjects - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectWithArrayOfObjects - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4309,9 +4153,9 @@ impl std::ops::DerefMut for Ok { } } -impl std::string::ToString for Ok { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for Ok { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -4333,8 +4177,7 @@ impl std::convert::TryFrom> for hyper::header::Heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Ok - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Ok - value: {hdr_value} is invalid {e}")) } } } @@ -4349,13 +4192,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Ok - {}", - value, err)) + format!("Unable to convert header value '{value}' into Ok - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4371,8 +4212,7 @@ impl std::convert::TryFrom>> for hyper::header:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4392,16 +4232,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Ok - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Ok - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4445,17 +4283,17 @@ impl std::ops::DerefMut for OneOfGet200Response { } /// Converts the OneOfGet200Response value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for OneOfGet200Response { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for OneOfGet200Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a OneOfGet200Response value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for OneOfGet200Response { type Err = &'static str; @@ -4476,8 +4314,7 @@ impl std::convert::TryFrom> for hyp match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OneOfGet200Response - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OneOfGet200Response - value: {hdr_value} is invalid {e}")) } } } @@ -4492,13 +4329,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OneOfGet200Response - {}", - value, err)) + format!("Unable to convert header value '{value}' into OneOfGet200Response - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4514,8 +4349,7 @@ impl std::convert::TryFrom>> fo match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4535,16 +4369,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OneOfGet200Response - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OneOfGet200Response - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4588,16 +4420,16 @@ impl std::ops::DerefMut for OptionalObjectHeader { } /// Converts the OptionalObjectHeader value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for OptionalObjectHeader { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for OptionalObjectHeader { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a OptionalObjectHeader value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for OptionalObjectHeader { type Err = String; @@ -4605,7 +4437,7 @@ impl ::std::str::FromStr for OptionalObjectHeader { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(OptionalObjectHeader(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to OptionalObjectHeader: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OptionalObjectHeader: {e:?}")), } } } @@ -4621,8 +4453,7 @@ impl std::convert::TryFrom> for hy match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OptionalObjectHeader - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OptionalObjectHeader - value: {hdr_value} is invalid {e}")) } } } @@ -4637,13 +4468,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OptionalObjectHeader - {}", - value, err)) + format!("Unable to convert header value '{value}' into OptionalObjectHeader - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4659,8 +4488,7 @@ impl std::convert::TryFrom>> f match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4680,16 +4508,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OptionalObjectHeader - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OptionalObjectHeader - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4733,16 +4559,16 @@ impl std::ops::DerefMut for RequiredObjectHeader { } /// Converts the RequiredObjectHeader value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for RequiredObjectHeader { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for RequiredObjectHeader { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a RequiredObjectHeader value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for RequiredObjectHeader { type Err = String; @@ -4750,7 +4576,7 @@ impl ::std::str::FromStr for RequiredObjectHeader { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(RequiredObjectHeader(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to RequiredObjectHeader: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to RequiredObjectHeader: {e:?}")), } } } @@ -4766,8 +4592,7 @@ impl std::convert::TryFrom> for hy match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for RequiredObjectHeader - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for RequiredObjectHeader - value: {hdr_value} is invalid {e}")) } } } @@ -4782,13 +4607,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into RequiredObjectHeader - {}", - value, err)) + format!("Unable to convert header value '{value}' into RequiredObjectHeader - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4804,8 +4627,7 @@ impl std::convert::TryFrom>> f match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4825,16 +4647,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into RequiredObjectHeader - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into RequiredObjectHeader - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4877,9 +4697,9 @@ impl std::ops::DerefMut for Result { } } -impl std::string::ToString for Result { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -4901,8 +4721,7 @@ impl std::convert::TryFrom> for hyper::header::H match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Result - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Result - value: {hdr_value} is invalid {e}")) } } } @@ -4917,13 +4736,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Result - {}", - value, err)) + format!("Unable to convert header value '{value}' into Result - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4939,8 +4756,7 @@ impl std::convert::TryFrom>> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4960,16 +4776,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Result - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Result - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5013,7 +4827,7 @@ impl std::str::FromStr for StringEnum { match s { "FOO" => std::result::Result::Ok(StringEnum::Foo), "BAR" => std::result::Result::Ok(StringEnum::Bar), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -5029,8 +4843,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for StringEnum - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for StringEnum - value: {hdr_value} is invalid {e}")) } } } @@ -5045,13 +4858,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into StringEnum - {}", - value, err)) + format!("Unable to convert header value '{value}' into StringEnum - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5067,8 +4878,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5088,16 +4898,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into StringEnum - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into StringEnum - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5140,9 +4948,9 @@ impl std::ops::DerefMut for StringObject { } } -impl std::string::ToString for StringObject { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for StringObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -5164,8 +4972,7 @@ impl std::convert::TryFrom> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for StringObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for StringObject - value: {hdr_value} is invalid {e}")) } } } @@ -5180,13 +4987,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into StringObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into StringObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5202,8 +5007,7 @@ impl std::convert::TryFrom>> for hyper match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5223,16 +5027,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into StringObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into StringObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5277,16 +5079,16 @@ impl std::ops::DerefMut for UuidObject { } /// Converts the UuidObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for UuidObject { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for UuidObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a UuidObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for UuidObject { type Err = String; @@ -5294,7 +5096,7 @@ impl ::std::str::FromStr for UuidObject { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(UuidObject(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to UuidObject: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to UuidObject: {e:?}")), } } } @@ -5310,8 +5112,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for UuidObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for UuidObject - value: {hdr_value} is invalid {e}")) } } } @@ -5326,13 +5127,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into UuidObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into UuidObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5348,8 +5147,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5369,16 +5167,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into UuidObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into UuidObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5467,16 +5263,16 @@ impl std::ops::DerefMut for XmlArray { } /// Converts the XmlArray value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for XmlArray { - fn to_string(&self) -> String { - self.iter().map(|x| x.to_string()).collect::>().join(",") +impl std::fmt::Display for XmlArray { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.iter().map(|x| x.to_string()).collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a XmlArray value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for XmlArray { type Err = ::Err; @@ -5503,8 +5299,7 @@ impl std::convert::TryFrom> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for XmlArray - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for XmlArray - value: {hdr_value} is invalid {e}")) } } } @@ -5519,13 +5314,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlArray - {}", - value, err)) + format!("Unable to convert header value '{value}' into XmlArray - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5541,8 +5334,7 @@ impl std::convert::TryFrom>> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5562,16 +5354,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlArray - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into XmlArray - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5615,9 +5405,9 @@ impl std::ops::DerefMut for XmlInner { } } -impl std::string::ToString for XmlInner { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for XmlInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -5639,8 +5429,7 @@ impl std::convert::TryFrom> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for XmlInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for XmlInner - value: {hdr_value} is invalid {e}")) } } } @@ -5655,13 +5444,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into XmlInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5677,8 +5464,7 @@ impl std::convert::TryFrom>> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5698,16 +5484,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into XmlInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5748,10 +5532,10 @@ impl XmlObject { } /// Converts the XmlObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for XmlObject { - fn to_string(&self) -> String { +impl std::fmt::Display for XmlObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.inner_string.as_ref().map(|inner_string| { [ @@ -5767,12 +5551,12 @@ impl std::string::ToString for XmlObject { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a XmlObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for XmlObject { type Err = String; @@ -5832,8 +5616,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for XmlObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for XmlObject - value: {hdr_value} is invalid {e}")) } } } @@ -5848,13 +5631,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into XmlObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5870,8 +5651,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5891,16 +5671,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into XmlObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into XmlObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs index 5bda72e889d5..5a96b66851d4 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/callbacks.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -42,9 +45,8 @@ use crate::CallbackCallbackPostResponse; /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -57,9 +59,8 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -70,9 +71,8 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -84,8 +84,8 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client>>, C>, C> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static { /// Create a client with a custom implementation of hyper::client::Connect. @@ -99,10 +99,11 @@ impl Client Self { - let client_service = hyper::client::Client::builder().build(connector); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = hyper_util::service::TowerToHyperService::new(client_service); let client_service = DropContextService::new(client_service); Self { @@ -112,7 +113,7 @@ impl Client Client, C>, C> where +impl Client>>, C>, C> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. @@ -123,12 +124,12 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; -impl Client, C>, C> where +impl Client>>, C>, C> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server. @@ -192,9 +193,8 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, C: Clone + Send + Sync + 'static { @@ -214,21 +214,14 @@ impl Client where #[async_trait] impl CallbackApi for Client where S: Service< - (Request, C), - Response=Response, - Error=hyper::Error> + Clone + Send + Sync, + (Request>, C), + Response=Response> + Send + Sync + Clone, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Has> + Clone + Send + Sync, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(Box::new(e))), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn callback_callback_with_header_post( &self, callback_request_query_url: String, @@ -236,6 +229,7 @@ impl CallbackApi for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{request_query_url}/callback-with-header" ,request_query_url=callback_request_query_url @@ -253,21 +247,21 @@ impl CallbackApi for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); // Header parameters @@ -276,12 +270,12 @@ impl CallbackApi for Client where Some(param_information) => { request.headers_mut().append( HeaderName::from_static("information"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_information.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header information - {}", e))); + "Invalid header information - {e}"))); }, }); }, @@ -289,7 +283,7 @@ impl CallbackApi for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -299,30 +293,30 @@ impl CallbackApi for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn callback_callback_post( &self, callback_request_query_url: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{request_query_url}/callback" ,request_query_url=callback_request_query_url @@ -340,25 +334,25 @@ impl CallbackApi for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -368,18 +362,16 @@ impl CallbackApi for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs index 580e29ef909d..5fc291aad0ba 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,12 +20,13 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, AnyOfGetResponse, CallbackWithHeaderPostResponse, ComplexQueryParamGetResponse, + ExamplesTestResponse, FormTestResponse, GetWithBooleanParameterResponse, JsonComplexQueryParamGetResponse, @@ -66,6 +69,7 @@ mod paths { r"^/callback-with-header$", r"^/complex-query-param$", r"^/enum_in_path/(?P[^/?#]*)$", + r"^/examples-test$", r"^/form-test$", r"^/get-with-bool$", r"^/json-complex-query-param$", @@ -103,46 +107,48 @@ mod paths { regex::Regex::new(r"^/enum_in_path/(?P[^/?#]*)$") .expect("Unable to create regex for ENUM_IN_PATH_PATH_PARAM"); } - pub(crate) static ID_FORM_TEST: usize = 4; - pub(crate) static ID_GET_WITH_BOOL: usize = 5; - pub(crate) static ID_JSON_COMPLEX_QUERY_PARAM: usize = 6; - pub(crate) static ID_MANDATORY_REQUEST_HEADER: usize = 7; - pub(crate) static ID_MERGE_PATCH_JSON: usize = 8; - pub(crate) static ID_MULTIGET: usize = 9; - pub(crate) static ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B: usize = 10; + pub(crate) static ID_EXAMPLES_TEST: usize = 4; + pub(crate) static ID_FORM_TEST: usize = 5; + pub(crate) static ID_GET_WITH_BOOL: usize = 6; + pub(crate) static ID_JSON_COMPLEX_QUERY_PARAM: usize = 7; + pub(crate) static ID_MANDATORY_REQUEST_HEADER: usize = 8; + pub(crate) static ID_MERGE_PATCH_JSON: usize = 9; + pub(crate) static ID_MULTIGET: usize = 10; + pub(crate) static ID_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B: usize = 11; lazy_static! { pub static ref REGEX_MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B: regex::Regex = #[allow(clippy::invalid_regex)] regex::Regex::new(r"^/multiple-path-params-with-very-long-path-to-test-formatting/(?P[^/?#]*)/(?P[^/?#]*)$") .expect("Unable to create regex for MULTIPLE_PATH_PARAMS_WITH_VERY_LONG_PATH_TO_TEST_FORMATTING_PATH_PARAM_A_PATH_PARAM_B"); } - pub(crate) static ID_MULTIPLE_AUTH_SCHEME: usize = 11; - pub(crate) static ID_ONE_OF: usize = 12; - pub(crate) static ID_OPERATION_TWO_FIRST_LETTER_HEADERS: usize = 13; - pub(crate) static ID_OVERRIDE_SERVER: usize = 14; - pub(crate) static ID_PARAMGET: usize = 15; - pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 16; - pub(crate) static ID_REGISTER_CALLBACK: usize = 17; - pub(crate) static ID_REPOS: usize = 18; - pub(crate) static ID_REPOS_REPOID: usize = 19; + pub(crate) static ID_MULTIPLE_AUTH_SCHEME: usize = 12; + pub(crate) static ID_ONE_OF: usize = 13; + pub(crate) static ID_OPERATION_TWO_FIRST_LETTER_HEADERS: usize = 14; + pub(crate) static ID_OVERRIDE_SERVER: usize = 15; + pub(crate) static ID_PARAMGET: usize = 16; + pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 17; + pub(crate) static ID_REGISTER_CALLBACK: usize = 18; + pub(crate) static ID_REPOS: usize = 19; + pub(crate) static ID_REPOS_REPOID: usize = 20; lazy_static! { pub static ref REGEX_REPOS_REPOID: regex::Regex = #[allow(clippy::invalid_regex)] regex::Regex::new(r"^/repos/(?P[^/?#]*)$") .expect("Unable to create regex for REPOS_REPOID"); } - pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 20; - pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 21; - pub(crate) static ID_RFC7807: usize = 22; - pub(crate) static ID_UNTYPED_PROPERTY: usize = 23; - pub(crate) static ID_UUID: usize = 24; - pub(crate) static ID_XML: usize = 25; - pub(crate) static ID_XML_EXTRA: usize = 26; - pub(crate) static ID_XML_OTHER: usize = 27; + pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 21; + pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 22; + pub(crate) static ID_RFC7807: usize = 23; + pub(crate) static ID_UNTYPED_PROPERTY: usize = 24; + pub(crate) static ID_UUID: usize = 25; + pub(crate) static ID_XML: usize = 26; + pub(crate) static ID_XML_EXTRA: usize = 27; + pub(crate) static ID_XML_OTHER: usize = 28; } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -150,7 +156,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -162,7 +169,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -170,21 +191,17 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -221,25 +238,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -265,7 +294,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_any_of.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -283,7 +312,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, AnyOfGetResponse::AlternateSuccess @@ -296,7 +325,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, AnyOfGetResponse::AnyOfSuccess @@ -309,7 +338,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -317,7 +346,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -339,7 +368,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_url) => Some(param_url), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter url - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter url")), } }, @@ -349,7 +378,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_url) => param_url, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter url")) + .body(body_from_str("Missing required query parameter url")) .expect("Unable to create Bad Request response for missing query parameter url")), }; @@ -357,7 +386,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_url, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -375,7 +404,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -399,7 +428,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_list_of_strings.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -417,7 +446,57 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); + }, + } + + Ok(response) + }, + + // ExamplesTest - GET /examples-test + hyper::Method::GET if path.matched(paths::ID_EXAMPLES_TEST) => { + // 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::>(); + let param_ids = query_params.iter().filter(|e| e.0 == "ids").map(|e| e.1.clone()) + .filter_map(|param_ids| param_ids.parse().ok()) + .collect::>(); + let param_ids = if !param_ids.is_empty() { + Some(param_ids) + } else { + None + }; + + let result = api_impl.examples_test( + param_ids.as_ref(), + &context + ).await; + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); + response.headers_mut().insert( + HeaderName::from_static("x-span-id"), + HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) + .expect("Unable to create X-Span-ID header value")); + + match result { + Ok(rsp) => match rsp { + ExamplesTestResponse::OK + (body) + => { + *response.status_mut() = StatusCode::from_u16(200).expect("Unable to turn 200 into a StatusCode"); + response.headers_mut().insert( + CONTENT_TYPE, + HeaderValue::from_str("application/json") + .expect("Unable to create Content-Type header for application/json")); + // JSON Body + let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); + *response.body_mut() = body_from_string(body); + + }, + }, + Err(_) => { + // Application code returned an error. This should not happen, as the implementation should + // return a valid response. + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -429,7 +508,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { // Form parameters @@ -441,7 +520,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_required_array.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -459,7 +538,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -467,7 +546,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -487,7 +566,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_iambool) => Some(param_iambool), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter iambool - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter iambool - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter iambool")), } }, @@ -497,7 +576,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_iambool) => param_iambool, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter iambool")) + .body(body_from_str("Missing required query parameter iambool")) .expect("Unable to create Bad Request response for missing query parameter iambool")), }; @@ -505,7 +584,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_iambool, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -523,7 +602,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -545,7 +624,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_list_of_strings) => Some(param_list_of_strings), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter list-of-strings - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter list-of-strings - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter list-of-strings")), } }, @@ -556,7 +635,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_list_of_strings.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -574,7 +653,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -593,7 +672,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header X-Header - {}", err))) + .body(body_from_string(format!("Invalid header X-Header - {err}"))) .expect("Unable to create Bad Request response for invalid header X-Header")); }, @@ -601,7 +680,7 @@ impl hyper::service::Service<(Request, C)> for Service where None => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required header X-Header")) + .body(body_from_str("Missing required header X-Header")) .expect("Unable to create Bad Request response for missing required header X-Header")); } }; @@ -610,7 +689,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_x_header, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -628,7 +707,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -640,7 +719,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.merge_patch_json_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -658,7 +737,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/merge-patch+json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -666,7 +745,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -678,7 +757,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.multiget_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -696,7 +775,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::XMLRsp @@ -709,7 +788,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::OctetRsp @@ -721,8 +800,8 @@ impl hyper::service::Service<(Request, C)> for Service where HeaderValue::from_str("application/octet-stream") .expect("Unable to create Content-Type header for application/octet-stream")); // Binary Body - let body = body.0; - *response.body_mut() = Body::from(body); + let body = String::from_utf8(body.0).expect("Error converting octet stream to string"); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::StringRsp @@ -734,8 +813,7 @@ impl hyper::service::Service<(Request, C)> for Service where HeaderValue::from_str("text/plain") .expect("Unable to create Content-Type header for text/plain")); // Plain text Body - let body = body; - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::DuplicateResponseLongText @@ -748,7 +826,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::DuplicateResponseLongText_2 @@ -761,7 +839,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, MultigetGetResponse::DuplicateResponseLongText_3 @@ -774,7 +852,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -782,7 +860,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -796,7 +874,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -811,9 +889,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -824,7 +902,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.multiple_auth_scheme_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -842,7 +920,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -854,7 +932,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.one_of_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -872,7 +950,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -880,7 +958,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -892,7 +970,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.override_server_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -910,7 +988,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -932,7 +1010,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_uuid) => Some(param_uuid), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter uuid - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter uuid - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter uuid")), } }, @@ -949,7 +1027,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_some_object) => Some(param_some_object), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter someObject - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter someObject - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter someObject")), } }, @@ -966,7 +1044,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_some_list) => Some(param_some_list), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter someList - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter someList - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter someList")), } }, @@ -979,7 +1057,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_some_list, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -997,7 +1075,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -1005,7 +1083,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1019,7 +1097,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1033,9 +1111,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1046,7 +1124,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.readonly_auth_scheme_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1064,7 +1142,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1086,7 +1164,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_url) => Some(param_url), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter url - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter url - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter url")), } }, @@ -1096,7 +1174,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_url) => param_url, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter url")) + .body(body_from_str("Missing required query parameter url")) .expect("Unable to create Bad Request response for missing query parameter url")), }; @@ -1104,7 +1182,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_url, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1122,7 +1200,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1134,7 +1212,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let param_body: Option = if !body.is_empty() { @@ -1146,7 +1224,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -1155,7 +1233,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1173,7 +1251,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1181,7 +1259,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1191,7 +1269,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.responses_with_headers_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1214,7 +1292,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling success_info header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling success_info header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -1230,7 +1308,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling bool_header header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling bool_header header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -1247,7 +1325,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling object_header header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling object_header header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -1263,7 +1341,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, ResponsesWithHeadersGetResponse::PreconditionFailed @@ -1280,7 +1358,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling further_info header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling further_info header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -1297,7 +1375,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling failure_info header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling failure_info header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -1314,7 +1392,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1326,7 +1404,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.rfc7807_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1344,7 +1422,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, Rfc7807GetResponse::NotFound @@ -1357,7 +1435,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/problem+json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, Rfc7807GetResponse::NotAcceptable @@ -1370,7 +1448,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/problem+xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -1378,7 +1456,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1397,7 +1475,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header x-header-one - {}", err))) + .body(body_from_string(format!("Invalid header x-header-one - {err}"))) .expect("Unable to create Bad Request response for invalid header x-header-one")); }, @@ -1415,7 +1493,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header x-header-two - {}", err))) + .body(body_from_string(format!("Invalid header x-header-two - {err}"))) .expect("Unable to create Bad Request response for invalid header x-header-two")); }, @@ -1430,7 +1508,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_x_header_two, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1448,7 +1526,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1460,19 +1538,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_object_untyped_props: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_object_untyped_props) => param_object_untyped_props, - Err(_) => None, - } + let deserializer = &mut serde_json::Deserializer::from_slice(&body); + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1482,7 +1558,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_object_untyped_props, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1491,7 +1567,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1506,7 +1582,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1514,7 +1590,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1524,7 +1600,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.uuid_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1542,7 +1618,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -1550,7 +1626,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1562,19 +1638,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_duplicate_xml_object: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_duplicate_xml_object) => param_duplicate_xml_object, - Err(_) => None, - } + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1584,7 +1658,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_duplicate_xml_object, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1593,7 +1667,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1613,7 +1687,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1621,7 +1695,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1631,19 +1705,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_another_xml_object: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_another_xml_object) => param_another_xml_object, - Err(_) => None, - } + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1653,7 +1725,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_another_xml_object, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1662,7 +1734,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1681,7 +1753,7 @@ impl hyper::service::Service<(Request, C)> for Service where // An empty string is used to indicate a global namespace in xmltree. namespaces.insert("".to_string(), models::AnotherXmlObject::NAMESPACE.to_string()); let body = serde_xml_rs::to_string_with_namespaces(&body, namespaces).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, XmlOtherPostResponse::BadRequest @@ -1694,7 +1766,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1702,7 +1774,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1712,19 +1784,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_another_xml_array: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_another_xml_array) => param_another_xml_array, - Err(_) => None, - } + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1734,7 +1804,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_another_xml_array, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1743,7 +1813,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1763,7 +1833,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1771,7 +1841,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1781,19 +1851,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_xml_array: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_xml_array) => param_xml_array, - Err(_) => None, - } + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1803,7 +1871,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_xml_array, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1812,7 +1880,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1832,7 +1900,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1840,7 +1908,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1850,19 +1918,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_xml_object: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_xml_object) => param_xml_object, - Err(_) => None, - } + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -1872,7 +1938,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_xml_object, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1881,7 +1947,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1901,7 +1967,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1909,7 +1975,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1930,12 +1996,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_path_param) => param_path_param, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter path_param: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter path_param: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -1943,7 +2009,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_path_param, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1961,7 +2027,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1984,12 +2050,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_path_param_a) => param_path_param_a, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter path_param_a: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter path_param_a: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_a"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_a"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -1998,12 +2064,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_path_param_b) => param_path_param_b, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter path_param_b: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter path_param_b: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_b"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["path_param_b"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -2012,7 +2078,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_path_param_b, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2030,7 +2096,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2042,22 +2108,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_object_param: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_object_param) => param_object_param, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter ObjectParam - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter ObjectParam - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter ObjectParam due to schema")), } + } else { None }; @@ -2065,7 +2132,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_object_param) => param_object_param, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter ObjectParam")) + .body(BoxBody::new("Missing required body parameter ObjectParam".to_string())) .expect("Unable to create Bad Request response for missing body parameter ObjectParam")), }; @@ -2074,7 +2141,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_object_param, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2083,7 +2150,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -2098,7 +2165,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2106,7 +2173,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2127,12 +2194,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_repo_id) => param_repo_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter repoId: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter repoId: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["repoId"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["repoId"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -2140,7 +2207,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_repo_id, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2158,7 +2225,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -2166,7 +2233,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2177,6 +2244,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_CALLBACK_WITH_HEADER) => method_not_allowed(), _ if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => method_not_allowed(), _ if path.matched(paths::ID_ENUM_IN_PATH_PATH_PARAM) => method_not_allowed(), + _ if path.matched(paths::ID_EXAMPLES_TEST) => method_not_allowed(), _ if path.matched(paths::ID_FORM_TEST) => method_not_allowed(), _ if path.matched(paths::ID_GET_WITH_BOOL) => method_not_allowed(), _ if path.matched(paths::ID_JSON_COMPLEX_QUERY_PARAM) => method_not_allowed(), @@ -2202,7 +2270,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_XML_EXTRA) => method_not_allowed(), _ if path.matched(paths::ID_XML_OTHER) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } @@ -2225,6 +2293,8 @@ impl RequestParser for ApiRequestParser { hyper::Method::POST if path.matched(paths::ID_CALLBACK_WITH_HEADER) => Some("CallbackWithHeaderPost"), // ComplexQueryParamGet - GET /complex-query-param hyper::Method::GET if path.matched(paths::ID_COMPLEX_QUERY_PARAM) => Some("ComplexQueryParamGet"), + // ExamplesTest - GET /examples-test + hyper::Method::GET if path.matched(paths::ID_EXAMPLES_TEST) => Some("ExamplesTest"), // FormTest - POST /form-test hyper::Method::POST if path.matched(paths::ID_FORM_TEST) => Some("FormTest"), // GetWithBooleanParameter - GET /get-with-bool diff --git a/samples/server/petstore/rust-server/output/openapi-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/openapi-v3/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/openapi-v3/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/ops-v3/.cargo/config.toml b/samples/server/petstore/rust-server/output/ops-v3/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/ops-v3/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/ops-v3/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/ops-v3/.openapi-generator/FILES index ce2109b1de2e..913ced3d98a4 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/ops-v3/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml index 0c33be7b5ea2..8328f10a786f 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml @@ -10,73 +10,80 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/ops-v3/bin/cli.rs b/samples/server/petstore/rust-server/output/ops-v3/bin/cli.rs index 39f3ad4646cd..31a94281e196 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -44,7 +45,6 @@ use ops_v3::{ Op9GetResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -54,44 +54,44 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "Regression test for large number of operations", version = "0.0.1", about = "CLI access to Regression test for large number of operations" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { Op10Get { }, @@ -204,7 +204,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -754,6 +754,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs index 9d9bfc6d9589..b829ce8b9a4d 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/client/main.rs @@ -43,7 +43,7 @@ use ops_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, Op8GetResponse, Op9GetResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -66,10 +66,10 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ "Op10Get", "Op11Get", "Op12Get", @@ -110,17 +110,15 @@ fn main() { ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -144,22 +142,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -174,7 +172,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { Some("Op10Get") => { let result = rt.block_on(client.op10_get( )); diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs index 227fe7e73155..b1a734a43442 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs index d51ecdd70289..599ae2176571 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use ops_v3::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server_auth.rs index 19eb6c6add4a..6e331a6b7ab1 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use ops_v3::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -87,7 +87,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -124,4 +124,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/auth.rs b/samples/server/petstore/rust-server/output/ops-v3/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/auth.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs index f3dbc73c9892..90bfb329b0d0 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -90,15 +93,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -115,8 +117,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -128,8 +129,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -143,8 +143,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -158,7 +169,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -167,8 +178,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -180,26 +191,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -210,7 +214,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -223,13 +227,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -246,13 +250,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -263,18 +278,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -287,7 +313,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -308,7 +334,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -336,8 +362,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -399,28 +424,31 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn op10_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op10", self.base_path @@ -438,25 +466,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -466,29 +494,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op11_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op11", self.base_path @@ -506,25 +534,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -534,29 +562,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op12_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op12", self.base_path @@ -574,25 +602,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -602,29 +630,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op13_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op13", self.base_path @@ -642,25 +670,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -670,29 +698,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op14_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op14", self.base_path @@ -710,25 +738,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -738,29 +766,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op15_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op15", self.base_path @@ -778,25 +806,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -806,29 +834,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op16_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op16", self.base_path @@ -846,25 +874,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -874,29 +902,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op17_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op17", self.base_path @@ -914,25 +942,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -942,29 +970,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op18_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op18", self.base_path @@ -982,25 +1010,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1010,29 +1038,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op19_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op19", self.base_path @@ -1050,25 +1078,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1078,29 +1106,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op1_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op1", self.base_path @@ -1118,25 +1146,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1146,29 +1174,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op20_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op20", self.base_path @@ -1186,25 +1214,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1214,29 +1242,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op21_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op21", self.base_path @@ -1254,25 +1282,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1282,29 +1310,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op22_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op22", self.base_path @@ -1322,25 +1350,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1350,29 +1378,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op23_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op23", self.base_path @@ -1390,25 +1418,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1418,29 +1446,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op24_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op24", self.base_path @@ -1458,25 +1486,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1486,29 +1514,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op25_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op25", self.base_path @@ -1526,25 +1554,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1554,29 +1582,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op26_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op26", self.base_path @@ -1594,25 +1622,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1622,29 +1650,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op27_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op27", self.base_path @@ -1662,25 +1690,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1690,29 +1718,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op28_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op28", self.base_path @@ -1730,25 +1758,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1758,29 +1786,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op29_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op29", self.base_path @@ -1798,25 +1826,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1826,29 +1854,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op2_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op2", self.base_path @@ -1866,25 +1894,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1894,29 +1922,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op30_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op30", self.base_path @@ -1934,25 +1962,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1962,29 +1990,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op31_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op31", self.base_path @@ -2002,25 +2030,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2030,29 +2058,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op32_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op32", self.base_path @@ -2070,25 +2098,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2098,29 +2126,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op33_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op33", self.base_path @@ -2138,25 +2166,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2166,29 +2194,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op34_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op34", self.base_path @@ -2206,25 +2234,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2234,29 +2262,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op35_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op35", self.base_path @@ -2274,25 +2302,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2302,29 +2330,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op36_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op36", self.base_path @@ -2342,25 +2370,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2370,29 +2398,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op37_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op37", self.base_path @@ -2410,25 +2438,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2438,29 +2466,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op3_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op3", self.base_path @@ -2478,25 +2506,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2506,29 +2534,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op4_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op4", self.base_path @@ -2546,25 +2574,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2574,29 +2602,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op5_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op5", self.base_path @@ -2614,25 +2642,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2642,29 +2670,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op6_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op6", self.base_path @@ -2682,25 +2710,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2710,29 +2738,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op7_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op7", self.base_path @@ -2750,25 +2778,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2778,29 +2806,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op8_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op8", self.base_path @@ -2818,25 +2846,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2846,29 +2874,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn op9_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/op9", self.base_path @@ -2886,25 +2914,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -2914,18 +2942,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/context.rs b/samples/server/petstore/rust-server/output/ops-v3/src/context.rs index ee8e118587bb..45180a543112 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/context.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,30 +87,23 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/header.rs b/samples/server/petstore/rust-server/output/ops-v3/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/header.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs b/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs index 866ce4e4654a..d41c95464cb2 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/lib.rs @@ -246,10 +246,6 @@ pub enum Op9GetResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn op10_get( &self, context: &C) -> Result; @@ -405,8 +401,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn op10_get( @@ -574,10 +568,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs b/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs index 47846655bfb7..239200f7e8dd 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,7 +20,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, Op10GetResponse, @@ -147,7 +149,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -155,7 +158,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -167,7 +171,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -175,21 +193,17 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -226,25 +240,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -258,7 +284,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op10_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -276,7 +302,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -288,7 +314,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op11_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -306,7 +332,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -318,7 +344,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op12_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -336,7 +362,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -348,7 +374,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op13_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -366,7 +392,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -378,7 +404,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op14_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -396,7 +422,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -408,7 +434,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op15_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -426,7 +452,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -438,7 +464,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op16_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -456,7 +482,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -468,7 +494,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op17_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -486,7 +512,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -498,7 +524,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op18_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -516,7 +542,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -528,7 +554,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op19_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -546,7 +572,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -558,7 +584,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op1_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -576,7 +602,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -588,7 +614,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op20_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -606,7 +632,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -618,7 +644,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op21_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -636,7 +662,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -648,7 +674,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op22_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -666,7 +692,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -678,7 +704,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op23_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -696,7 +722,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -708,7 +734,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op24_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -726,7 +752,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -738,7 +764,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op25_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -756,7 +782,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -768,7 +794,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op26_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -786,7 +812,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -798,7 +824,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op27_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -816,7 +842,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -828,7 +854,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op28_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -846,7 +872,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -858,7 +884,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op29_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -876,7 +902,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -888,7 +914,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op2_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -906,7 +932,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -918,7 +944,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op30_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -936,7 +962,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -948,7 +974,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op31_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -966,7 +992,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -978,7 +1004,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op32_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -996,7 +1022,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1008,7 +1034,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op33_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1026,7 +1052,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1038,7 +1064,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op34_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1056,7 +1082,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1068,7 +1094,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op35_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1086,7 +1112,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1098,7 +1124,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op36_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1116,7 +1142,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1128,7 +1154,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op37_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1146,7 +1172,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1158,7 +1184,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op3_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1176,7 +1202,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1188,7 +1214,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op4_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1206,7 +1232,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1218,7 +1244,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op5_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1236,7 +1262,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1248,7 +1274,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op6_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1266,7 +1292,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1278,7 +1304,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op7_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1296,7 +1322,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1308,7 +1334,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op8_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1326,7 +1352,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1338,7 +1364,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.op9_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1356,7 +1382,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1401,7 +1427,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_OP8) => method_not_allowed(), _ if path.matched(paths::ID_OP9) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/ops-v3/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/ops-v3/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/ops-v3/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config.toml b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES index 6d35ed812fa6..5332ab08344d 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml index 0c809c91fdd6..a96e9a14f634 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml @@ -10,87 +10,91 @@ publish = ["crates-io"] [features] default = ["client", "server"] client = [ - "mime_0_2", "multipart", "multipart/client", "swagger/multipart_form", "serde_urlencoded", - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ - "mime_0_2", "multipart", "multipart/server", "swagger/multipart_form", "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ "dialoguer", - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # TODO: this should be updated to point at the official crate once # https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream serde-xml-rs = {git = "https://github.com/Metaswitch/serde-xml-rs" , branch = "master"} -mime_0_2 = { package = "mime", version = "0.2.6", optional = true } -multipart = { version = "0.16", default-features = false, optional = true } -uuid = {version = "1.3.1", features = ["serde", "v4"]} +multipart = { version = "0.18", default-features = false, optional = true } +uuid = { version = "1.17.0", features = ["serde", "v4"]} # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific -serde_urlencoded = {version = "0.6.1", optional = true} +serde_urlencoded = { version = "0.6.1", optional = true } +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } dialoguer = { version = "0.8", optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs index 9141802f5891..5cc7d996d9a2 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use dialoguer::Confirm; use log::{debug, info}; // models may be unused if all inputs are primitive types @@ -43,7 +44,6 @@ use petstore_with_fake_endpoints_models_for_testing::{ UpdateUserResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -53,93 +53,93 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "OpenAPI Petstore", version = "1.0.0", about = "CLI access to OpenAPI Petstore" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, /// Don't ask for any confirmation prompts #[allow(dead_code)] - #[structopt(short, long)] + #[clap(short, long)] force: bool, /// Bearer token if used for authentication - #[structopt(env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_BEARER_TOKEN", hide_env_values = true)] + #[arg(env = "PETSTORE_WITH_FAKE_ENDPOINTS_MODELS_FOR_TESTING_BEARER_TOKEN", hide_env = true)] bearer_token: Option, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { /// To test special tags TestSpecialTags { /// client model - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Client, }, Call123example { }, FakeOuterBooleanSerialize { /// Input boolean as post body - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: Option, }, FakeOuterCompositeSerialize { /// Input composite as post body - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: Option, }, FakeOuterNumberSerialize { /// Input number as post body - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: Option, }, FakeOuterStringSerialize { /// Input string as post body - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: Option, }, FakeResponseWithNumericalDescription { }, TestBodyWithQueryParams { query: String, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::User, }, /// To test \"client\" model TestClientModel { /// client model - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Client, }, /// Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 @@ -151,7 +151,7 @@ enum Operation { /// None pattern_without_delimiter: String, /// None - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] byte: swagger::ByteArray, /// None integer: Option, @@ -164,7 +164,7 @@ enum Operation { /// None string: Option, /// None - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] binary: Option, /// None date: Option, @@ -178,30 +178,30 @@ enum Operation { /// To test enum parameters TestEnumParameters { /// Header parameter enum test (string array) - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] enum_header_string_array: Option>, /// Header parameter enum test (string) - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] enum_header_string: Option, /// Query parameter enum test (string array) - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] enum_query_string_array: Option>, /// Query parameter enum test (string) - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] enum_query_string: Option, /// Query parameter enum test (double) - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] enum_query_integer: Option, /// Query parameter enum test (double) - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] enum_query_double: Option, - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] enum_form_string: Option, }, /// test inline additionalProperties TestInlineAdditionalProperties { /// request body - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::>)] param: std::collections::HashMap, }, /// test json serialization of form data @@ -218,31 +218,31 @@ enum Operation { /// To test class name in snake case TestClassname { /// client model - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Client, }, /// Add a new pet to the store AddPet { /// Pet object that needs to be added to the store - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Pet, }, /// Finds Pets by status FindPetsByStatus { /// Status values that need to be considered for filter - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] status: Vec, }, /// Finds Pets by tags FindPetsByTags { /// Tags to filter by - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] tags: Vec, }, /// Update an existing pet UpdatePet { /// Pet object that needs to be added to the store - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Pet, }, /// Deletes a pet @@ -272,7 +272,7 @@ enum Operation { /// Additional data to pass to server additional_metadata: Option, /// file to upload - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] file: Option, }, /// Returns pet inventories by status @@ -281,7 +281,7 @@ enum Operation { /// Place an order for a pet PlaceOrder { /// order placed for purchasing the pet - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::Order, }, /// Delete purchase order by ID @@ -297,19 +297,19 @@ enum Operation { /// Create user CreateUser { /// Created user object - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::User, }, /// Creates list of users with given input array CreateUsersWithArrayInput { /// List of user object - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] body: Vec, }, /// Creates list of users with given input array CreateUsersWithListInput { /// List of user object - #[structopt(parse(try_from_str = parse_json), long)] + #[clap(value_parser = parse_json::>, long)] body: Vec, }, /// Logs user into the system @@ -337,7 +337,7 @@ enum Operation { /// name that need to be deleted username: String, /// Updated user object - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] body: models::User, }, } @@ -377,7 +377,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -388,7 +388,7 @@ async fn main() -> Result<()> { if let Some(ref bearer_token) = args.bearer_token { debug!("Using bearer token"); - auth_data = Some(AuthData::bearer(bearer_token)); + auth_data = AuthData::bearer(bearer_token); } #[allow(trivial_casts)] @@ -1148,6 +1148,6 @@ fn prompt(force: bool, text: &str) -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs index 62b1a8c1389b..b635a60f7498 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/client/main.rs @@ -41,7 +41,7 @@ use petstore_with_fake_endpoints_models_for_testing::{Api, ApiNoContext, Claims, GetUserByNameResponse, UpdateUserResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -64,49 +64,57 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ + "TestSpecialTags", "Call123example", "FakeOuterBooleanSerialize", "FakeOuterCompositeSerialize", "FakeOuterNumberSerialize", "FakeOuterStringSerialize", "FakeResponseWithNumericalDescription", + "TestBodyWithQueryParams", + "TestClientModel", "TestEndpointParameters", "TestEnumParameters", + "TestInlineAdditionalProperties", "TestJsonFormData", "HyphenParam", + "TestClassname", + "AddPet", "FindPetsByStatus", "FindPetsByTags", + "UpdatePet", "DeletePet", "GetPetById", "UpdatePetWithForm", "UploadFile", "GetInventory", + "PlaceOrder", "DeleteOrder", "GetOrderById", + "CreateUser", "CreateUsersWithArrayInput", "CreateUsersWithListInput", "LoginUser", "LogoutUser", "DeleteUser", "GetUserByName", + "UpdateUser", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("petstore.swagger.io") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("80") .help("Port to contact")) .get_matches(); @@ -133,22 +141,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -163,7 +171,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { /* Disabled because there's no example. Some("TestSpecialTags") => { let result = rt.block_on(client.test_special_tags( diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs index 63e175c3dc90..2b3cd2612d79 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); - let addr = "127.0.0.1:80"; + let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs index 2920da486195..b4e002adff73 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use petstore_with_fake_endpoints_models_for_testing::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs index 1593a36e2c41..ec3b16b195d6 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use petstore_with_fake_endpoints_models_for_testing::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -90,7 +90,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -127,4 +127,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs index 8c35448de11c..9c4ba3298b05 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use mime::Mime; use std::io::Cursor; @@ -91,15 +94,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -116,8 +118,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -129,8 +130,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -144,8 +144,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -159,7 +170,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -168,8 +179,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -181,26 +192,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } - - fn call(&mut self, req: Request) -> Self::Future { - match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -211,7 +215,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -224,13 +228,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -247,13 +251,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -264,18 +279,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -288,7 +314,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -309,7 +335,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -337,8 +363,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -400,29 +425,32 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Has> + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn test_special_tags( &self, param_body: models::Client, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/another-fake/dummy", self.base_path @@ -440,48 +468,49 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PATCH") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(TestSpecialTagsResponse::SuccessfulOperation @@ -490,29 +519,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn call123example( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/operation-with-numeric-id", self.base_path @@ -530,25 +559,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -558,30 +587,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn fake_outer_boolean_serialize( &self, param_body: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/outer/boolean", self.base_path @@ -599,50 +628,51 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_body) = param_body { let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FakeOuterBooleanSerializeResponse::OutputBoolean @@ -651,30 +681,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn fake_outer_composite_serialize( &self, param_body: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/outer/composite", self.base_path @@ -692,50 +722,51 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_body) = param_body { let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FakeOuterCompositeSerializeResponse::OutputComposite @@ -744,30 +775,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn fake_outer_number_serialize( &self, param_body: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/outer/number", self.base_path @@ -785,50 +816,51 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_body) = param_body { let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FakeOuterNumberSerializeResponse::OutputNumber @@ -837,30 +869,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn fake_outer_string_serialize( &self, param_body: Option, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/outer/string", self.base_path @@ -878,50 +910,51 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter if let Some(param_body) = param_body { let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); } let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FakeOuterStringSerializeResponse::OutputString @@ -930,29 +963,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn fake_response_with_numerical_description( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/response-with-numerical-description", self.base_path @@ -970,25 +1003,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -998,24 +1031,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_body_with_query_params( &self, param_query: String, @@ -1023,6 +1055,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/body-with-query-params", self.base_path @@ -1042,36 +1075,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1081,30 +1114,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_client_model( &self, param_body: models::Client, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake", self.base_path @@ -1122,48 +1155,49 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PATCH") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(TestClientModelResponse::SuccessfulOperation @@ -1172,24 +1206,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_endpoint_parameters( &self, param_number: f64, @@ -1209,6 +1242,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake", self.base_path @@ -1226,77 +1260,91 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes form body let mut params = vec![]; if let Some(param_integer) = param_integer { + #[allow(clippy::uninlined_format_args)] params.push(("integer", format!("{:?}", param_integer) )); } if let Some(param_int32) = param_int32 { + #[allow(clippy::uninlined_format_args)] params.push(("int32", format!("{:?}", param_int32) )); } if let Some(param_int64) = param_int64 { + #[allow(clippy::uninlined_format_args)] params.push(("int64", format!("{:?}", param_int64) )); } + #[allow(clippy::uninlined_format_args)] params.push(("number", format!("{}", param_number) )); if let Some(param_float) = param_float { + #[allow(clippy::uninlined_format_args)] params.push(("float", format!("{:?}", param_float) )); } + #[allow(clippy::uninlined_format_args)] params.push(("double", format!("{}", param_double) )); if let Some(param_string) = param_string { + #[allow(clippy::uninlined_format_args)] params.push(("string", param_string )); } + #[allow(clippy::uninlined_format_args)] params.push(("pattern_without_delimiter", param_pattern_without_delimiter )); + #[allow(clippy::uninlined_format_args)] params.push(("byte", format!("{:?}", param_byte) )); if let Some(param_binary) = param_binary { + #[allow(clippy::uninlined_format_args)] params.push(("binary", format!("{:?}", param_binary) )); } if let Some(param_date) = param_date { + #[allow(clippy::uninlined_format_args)] params.push(("date", format!("{:?}", param_date) )); } if let Some(param_date_time) = param_date_time { + #[allow(clippy::uninlined_format_args)] params.push(("dateTime", format!("{:?}", param_date_time) )); } if let Some(param_password) = param_password { + #[allow(clippy::uninlined_format_args)] params.push(("password", param_password )); } if let Some(param_callback) = param_callback { + #[allow(clippy::uninlined_format_args)] params.push(("callback", param_callback )); @@ -1304,40 +1352,37 @@ impl Api for Client where let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Basic(basic_header) => { - let auth = swagger::auth::Header(basic_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { - Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) - }; + AuthData::Basic(ref basic_user, ref basic_password) => { + let auth = headers::Authorization::basic(basic_user.as_str(), basic_password.as_str()); request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + auth.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -1352,24 +1397,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_enum_parameters( &self, param_enum_header_string_array: Option<&Vec>, @@ -1382,6 +1426,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake", self.base_path @@ -1415,20 +1460,21 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes form body let mut params = vec![]; if let Some(param_enum_form_string) = param_enum_form_string { + #[allow(clippy::uninlined_format_args)] params.push(("enum_form_string", format!("{:?}", param_enum_form_string) )); @@ -1436,18 +1482,18 @@ impl Api for Client where let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); // Header parameters @@ -1456,12 +1502,12 @@ impl Api for Client where Some(param_enum_header_string_array) => { request.headers_mut().append( HeaderName::from_static("enum_header_string_array"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_enum_header_string_array.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header enum_header_string_array - {}", e))); + "Invalid header enum_header_string_array - {e}"))); }, }); }, @@ -1473,12 +1519,12 @@ impl Api for Client where Some(param_enum_header_string) => { request.headers_mut().append( HeaderName::from_static("enum_header_string"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_enum_header_string.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header enum_header_string - {}", e))); + "Invalid header enum_header_string - {e}"))); }, }); }, @@ -1486,7 +1532,7 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -1501,30 +1547,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_inline_additional_properties( &self, param_param: std::collections::HashMap, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/inline-additionalProperties", self.base_path @@ -1542,36 +1588,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_param).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1581,24 +1627,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_json_form_data( &self, param_param: String, @@ -1606,6 +1651,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/jsonFormData", self.base_path @@ -1623,44 +1669,46 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes form body let mut params = vec![]; + #[allow(clippy::uninlined_format_args)] params.push(("param", param_param )); + #[allow(clippy::uninlined_format_args)] params.push(("param2", param_param2 )); let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1670,30 +1718,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn hyphen_param( &self, param_hyphen_param: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake/hyphenParam/{hyphen_param}", self.base_path @@ -1712,25 +1760,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -1740,30 +1788,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn test_classname( &self, param_body: models::Client, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/fake_classname_test", self.base_path @@ -1784,36 +1832,37 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PATCH") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { _ => {} @@ -1821,19 +1870,20 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(TestClassnameResponse::SuccessfulOperation @@ -1842,30 +1892,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn add_pet( &self, param_body: models::Pet, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet", self.base_path @@ -1883,54 +1933,54 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = param_body.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 405 => { @@ -1940,30 +1990,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn find_pets_by_status( &self, param_status: &Vec, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/findByStatus", self.base_path @@ -1983,57 +2033,58 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FindPetsByStatusResponse::SuccessfulOperation @@ -2047,30 +2098,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn find_pets_by_tags( &self, param_tags: &Vec, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/findByTags", self.base_path @@ -2090,57 +2141,58 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FindPetsByTagsResponse::SuccessfulOperation @@ -2154,30 +2206,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn update_pet( &self, param_body: models::Pet, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet", self.base_path @@ -2195,54 +2247,54 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = param_body.as_xml(); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -2262,24 +2314,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn delete_pet( &self, param_pet_id: i64, @@ -2287,6 +2338,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -2305,36 +2357,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("DELETE") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } @@ -2346,12 +2398,12 @@ impl Api for Client where Some(param_api_key) => { request.headers_mut().append( HeaderName::from_static("api_key"), - #[allow(clippy::redundant_clone)] + #[allow(clippy::redundant_clone, clippy::clone_on_copy)] match header::IntoHeaderValue(param_api_key.clone()).try_into() { Ok(header) => header, Err(e) => { return Err(ApiError(format!( - "Invalid header api_key - {}", e))); + "Invalid header api_key - {e}"))); }, }); }, @@ -2359,7 +2411,7 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -2369,30 +2421,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_pet_by_id( &self, param_pet_id: i64, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -2411,25 +2463,26 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { _ => {} @@ -2437,21 +2490,22 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(GetPetByIdResponse::SuccessfulOperation @@ -2470,24 +2524,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn update_pet_with_form( &self, param_pet_id: i64, @@ -2496,6 +2549,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/{pet_id}", self.base_path @@ -2514,25 +2568,27 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes form body let mut params = vec![]; if let Some(param_name) = param_name { + #[allow(clippy::uninlined_format_args)] params.push(("name", param_name )); } if let Some(param_status) = param_status { + #[allow(clippy::uninlined_format_args)] params.push(("status", param_status )); @@ -2540,40 +2596,40 @@ impl Api for Client where let body = serde_urlencoded::to_string(params).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body.into_bytes()); + *request.body_mut() = body_from_string(body); let header = "application/x-www-form-urlencoded"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 405 => { @@ -2583,24 +2639,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn upload_file( &self, param_pet_id: i64, @@ -2609,6 +2664,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/pet/{pet_id}/uploadImage", self.base_path @@ -2627,15 +2683,15 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes multipart/form body @@ -2646,11 +2702,11 @@ impl Api for Client where let additional_metadata_str = match serde_json::to_string(¶m_additional_metadata) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize additional_metadata to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize additional_metadata to string: {e}"))), }; let additional_metadata_vec = additional_metadata_str.as_bytes().to_vec(); - let additional_metadata_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let additional_metadata_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let additional_metadata_cursor = Cursor::new(additional_metadata_vec); multipart.add_stream("additional_metadata", additional_metadata_cursor, None as Option<&str>, Some(additional_metadata_mime)); @@ -2658,11 +2714,11 @@ impl Api for Client where let file_str = match serde_json::to_string(¶m_file) { Ok(str) => str, - Err(e) => return Err(ApiError(format!("Unable to serialize file to string: {}", e))), + Err(e) => return Err(ApiError(format!("Unable to serialize file to string: {e}"))), }; let file_vec = file_str.as_bytes().to_vec(); - let file_mime = mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); + let file_mime = mime::Mime::from_str("application/json").expect("impossible to fail to parse"); let file_cursor = Cursor::new(file_vec); multipart.add_stream("file", file_cursor, None as Option<&str>, Some(file_mime)); @@ -2670,69 +2726,70 @@ impl Api for Client where let mut fields = match multipart.prepare() { Ok(fields) => fields, - Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build request: {err}"))), }; let mut body_string = String::new(); match fields.read_to_string(&mut body_string) { Ok(_) => (), - Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build body: {err}"))), } let boundary = fields.boundary(); - let multipart_header = format!("multipart/form-data;boundary={}", boundary); + let multipart_header = format!("multipart/form-data;boundary={boundary}"); (body_string, multipart_header) }; - *request.body_mut() = Body::from(body_string); + *request.body_mut() = body_from_string(body_string); request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(&multipart_header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", multipart_header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {multipart_header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(UploadFileResponse::SuccessfulOperation @@ -2741,29 +2798,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_inventory( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/store/inventory", self.base_path @@ -2781,25 +2838,26 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { _ => {} @@ -2807,19 +2865,20 @@ impl Api for Client where } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::>(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(GetInventoryResponse::SuccessfulOperation @@ -2828,30 +2887,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn place_order( &self, param_body: models::Order, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/store/order", self.base_path @@ -2869,50 +2928,51 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(PlaceOrderResponse::SuccessfulOperation @@ -2926,30 +2986,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn delete_order( &self, param_order_id: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/store/order/{order_id}", self.base_path @@ -2968,25 +3028,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("DELETE") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -3001,30 +3061,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_order_by_id( &self, param_order_id: i64, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/store/order/{order_id}", self.base_path @@ -3043,39 +3103,40 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(GetOrderByIdResponse::SuccessfulOperation @@ -3094,30 +3155,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn create_user( &self, param_body: models::User, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user", self.base_path @@ -3135,36 +3196,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 0 => { @@ -3174,30 +3235,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn create_users_with_array_input( &self, param_body: &Vec, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/createWithArray", self.base_path @@ -3215,36 +3276,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 0 => { @@ -3254,30 +3315,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn create_users_with_list_input( &self, param_body: &Vec, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/createWithList", self.base_path @@ -3295,36 +3356,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 0 => { @@ -3334,24 +3395,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn login_user( &self, param_username: String, @@ -3359,6 +3419,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/login", self.base_path @@ -3380,25 +3441,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -3408,7 +3469,7 @@ impl Api for Client where let response_x_rate_limit = match TryInto::>::try_into(response_x_rate_limit) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header X-Rate-Limit for response 200 - {}", e))); + return Err(ApiError(format!("Invalid response header X-Rate-Limit for response 200 - {e}"))); }, }; Some(response_x_rate_limit.0) @@ -3422,7 +3483,7 @@ impl Api for Client where let response_x_expires_after = match TryInto::>>::try_into(response_x_expires_after) { Ok(value) => value, Err(e) => { - return Err(ApiError(format!("Invalid response header X-Expires-After for response 200 - {}", e))); + return Err(ApiError(format!("Invalid response header X-Expires-After for response 200 - {e}"))); }, }; Some(response_x_expires_after.0) @@ -3431,16 +3492,17 @@ impl Api for Client where }; let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(LoginUserResponse::SuccessfulOperation @@ -3458,29 +3520,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn logout_user( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/logout", self.base_path @@ -3498,25 +3560,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 0 => { @@ -3526,30 +3588,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn delete_user( &self, param_username: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3568,25 +3630,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("DELETE") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -3601,30 +3663,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_user_by_name( &self, param_username: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3643,39 +3705,40 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; // ToDo: this will move to swagger-rs and become a standard From conversion trait // once https://github.com/RReverser/serde-xml-rs/pull/45 is accepted upstream let body = serde_xml_rs::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(GetUserByNameResponse::SuccessfulOperation @@ -3694,24 +3757,23 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn update_user( &self, param_username: String, @@ -3719,6 +3781,7 @@ impl Api for Client where context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/v2/user/{username}", self.base_path @@ -3737,36 +3800,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_body).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 400 => { @@ -3781,18 +3844,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs index d821895b62ad..b3678c91f4b3 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,42 +87,26 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); { - use swagger::auth::Bearer; + use headers::authorization::Bearer; use std::ops::Deref; - if let Some(bearer) = swagger::auth::from_headers::(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } @@ -127,18 +114,9 @@ impl Service> for AddContext context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; return self.inner.call((request, context)) } @@ -149,43 +127,22 @@ impl Service> for AddContext context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; - return self.inner.call((request, context)) } } { - use swagger::auth::Basic; use std::ops::Deref; - if let Some(basic) = swagger::auth::from_headers::(headers) { - let authorization = self.inner.basic_authorization(&basic); - let auth_data = AuthData::Basic(basic); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(auth) = swagger::auth::from_headers(headers) { + let context = context.push(Some(auth)); return self.inner.call((request, context)) } } let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs index b910c9ae6b23..e483f7e1075c 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs @@ -325,10 +325,6 @@ pub enum UpdateUserResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - /// To test special tags async fn test_special_tags( &self, @@ -562,8 +558,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; /// To test special tags @@ -809,10 +803,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs index 6692bd124009..be2a06d7643e 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/models.rs @@ -31,21 +31,21 @@ impl AdditionalPropertiesClass { } /// Converts the AdditionalPropertiesClass value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AdditionalPropertiesClass { - fn to_string(&self) -> String { +impl std::fmt::Display for AdditionalPropertiesClass { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping map map_property in query parameter serialization // Skipping map map_of_map_property in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesClass value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AdditionalPropertiesClass { type Err = String; @@ -103,8 +103,7 @@ impl std::convert::TryFrom> f match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AdditionalPropertiesClass - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AdditionalPropertiesClass - value: {hdr_value} is invalid {e}")) } } } @@ -119,13 +118,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesClass - {}", - value, err)) + format!("Unable to convert header value '{value}' into AdditionalPropertiesClass - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -141,8 +138,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -162,16 +158,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesClass - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesClass - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -209,10 +203,10 @@ impl Animal { } /// Converts the Animal value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Animal { - fn to_string(&self) -> String { +impl std::fmt::Display for Animal { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("className".to_string()), Some(self.class_name.to_string()), @@ -224,12 +218,12 @@ impl std::string::ToString for Animal { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Animal value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Animal { type Err = String; @@ -289,8 +283,7 @@ impl std::convert::TryFrom> for hyper::header::H match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Animal - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Animal - value: {hdr_value} is invalid {e}")) } } } @@ -305,13 +298,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Animal - {}", - value, err)) + format!("Unable to convert header value '{value}' into Animal - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -327,8 +318,7 @@ impl std::convert::TryFrom>> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -348,16 +338,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Animal - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Animal - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -436,16 +424,16 @@ impl std::ops::DerefMut for AnimalFarm { } /// Converts the AnimalFarm value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AnimalFarm { - fn to_string(&self) -> String { - self.iter().map(|x| x.to_string()).collect::>().join(",") +impl std::fmt::Display for AnimalFarm { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.iter().map(|x| x.to_string()).collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AnimalFarm value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AnimalFarm { type Err = ::Err; @@ -472,8 +460,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AnimalFarm - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AnimalFarm - value: {hdr_value} is invalid {e}")) } } } @@ -488,13 +475,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnimalFarm - {}", - value, err)) + format!("Unable to convert header value '{value}' into AnimalFarm - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -510,8 +495,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -531,16 +515,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AnimalFarm - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AnimalFarm - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -584,10 +566,10 @@ impl ApiResponse { } /// Converts the ApiResponse value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ApiResponse { - fn to_string(&self) -> String { +impl std::fmt::Display for ApiResponse { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.code.as_ref().map(|code| { [ @@ -609,12 +591,12 @@ impl std::string::ToString for ApiResponse { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ApiResponse value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ApiResponse { type Err = String; @@ -678,8 +660,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ApiResponse - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ApiResponse - value: {hdr_value} is invalid {e}")) } } } @@ -694,13 +675,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ApiResponse - {}", - value, err)) + format!("Unable to convert header value '{value}' into ApiResponse - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -716,8 +695,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -737,16 +715,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ApiResponse - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ApiResponse - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -780,20 +756,20 @@ impl ArrayOfArrayOfNumberOnly { } /// Converts the ArrayOfArrayOfNumberOnly value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ArrayOfArrayOfNumberOnly { - fn to_string(&self) -> String { +impl std::fmt::Display for ArrayOfArrayOfNumberOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type ArrayArrayNumber in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ArrayOfArrayOfNumberOnly value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ArrayOfArrayOfNumberOnly { type Err = String; @@ -848,8 +824,7 @@ impl std::convert::TryFrom> fo match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ArrayOfArrayOfNumberOnly - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ArrayOfArrayOfNumberOnly - value: {hdr_value} is invalid {e}")) } } } @@ -864,13 +839,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayOfArrayOfNumberOnly - {}", - value, err)) + format!("Unable to convert header value '{value}' into ArrayOfArrayOfNumberOnly - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -886,8 +859,7 @@ impl std::convert::TryFrom match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -907,16 +879,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayOfArrayOfNumberOnly - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ArrayOfArrayOfNumberOnly - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -950,10 +920,10 @@ impl ArrayOfNumberOnly { } /// Converts the ArrayOfNumberOnly value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ArrayOfNumberOnly { - fn to_string(&self) -> String { +impl std::fmt::Display for ArrayOfNumberOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.array_number.as_ref().map(|array_number| { [ @@ -963,12 +933,12 @@ impl std::string::ToString for ArrayOfNumberOnly { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ArrayOfNumberOnly value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ArrayOfNumberOnly { type Err = String; @@ -1023,8 +993,7 @@ impl std::convert::TryFrom> for hyper match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ArrayOfNumberOnly - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ArrayOfNumberOnly - value: {hdr_value} is invalid {e}")) } } } @@ -1039,13 +1008,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayOfNumberOnly - {}", - value, err)) + format!("Unable to convert header value '{value}' into ArrayOfNumberOnly - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1061,8 +1028,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1082,16 +1048,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayOfNumberOnly - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ArrayOfNumberOnly - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1140,10 +1104,10 @@ impl ArrayTest { } /// Converts the ArrayTest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ArrayTest { - fn to_string(&self) -> String { +impl std::fmt::Display for ArrayTest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.array_of_string.as_ref().map(|array_of_string| { [ @@ -1156,12 +1120,12 @@ impl std::string::ToString for ArrayTest { // Skipping non-primitive type array_of_enum in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ArrayTest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ArrayTest { type Err = String; @@ -1225,8 +1189,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ArrayTest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ArrayTest - value: {hdr_value} is invalid {e}")) } } } @@ -1241,13 +1204,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayTest - {}", - value, err)) + format!("Unable to convert header value '{value}' into ArrayTest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1263,8 +1224,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1284,16 +1244,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ArrayTest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ArrayTest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1353,10 +1311,10 @@ impl Capitalization { } /// Converts the Capitalization value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Capitalization { - fn to_string(&self) -> String { +impl std::fmt::Display for Capitalization { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.small_camel.as_ref().map(|small_camel| { [ @@ -1396,12 +1354,12 @@ impl std::string::ToString for Capitalization { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Capitalization value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Capitalization { type Err = String; @@ -1477,8 +1435,7 @@ impl std::convert::TryFrom> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Capitalization - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Capitalization - value: {hdr_value} is invalid {e}")) } } } @@ -1493,13 +1450,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Capitalization - {}", - value, err)) + format!("Unable to convert header value '{value}' into Capitalization - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1515,8 +1470,7 @@ impl std::convert::TryFrom>> for hyp match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1536,16 +1490,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Capitalization - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Capitalization - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1588,10 +1540,10 @@ impl Cat { } /// Converts the Cat value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Cat { - fn to_string(&self) -> String { +impl std::fmt::Display for Cat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("className".to_string()), Some(self.class_name.to_string()), @@ -1609,12 +1561,12 @@ impl std::string::ToString for Cat { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Cat value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Cat { type Err = String; @@ -1678,8 +1630,7 @@ impl std::convert::TryFrom> for hyper::header::Head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Cat - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Cat - value: {hdr_value} is invalid {e}")) } } } @@ -1694,13 +1645,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Cat - {}", - value, err)) + format!("Unable to convert header value '{value}' into Cat - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1716,8 +1665,7 @@ impl std::convert::TryFrom>> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1737,16 +1685,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Cat - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Cat - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1786,10 +1732,10 @@ impl Category { } /// Converts the Category value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Category { - fn to_string(&self) -> String { +impl std::fmt::Display for Category { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.id.as_ref().map(|id| { [ @@ -1805,12 +1751,12 @@ impl std::string::ToString for Category { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Category value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Category { type Err = String; @@ -1870,8 +1816,7 @@ impl std::convert::TryFrom> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Category - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Category - value: {hdr_value} is invalid {e}")) } } } @@ -1886,13 +1831,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Category - {}", - value, err)) + format!("Unable to convert header value '{value}' into Category - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1908,8 +1851,7 @@ impl std::convert::TryFrom>> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1929,16 +1871,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Category - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Category - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1973,10 +1913,10 @@ impl ClassModel { } /// Converts the ClassModel value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ClassModel { - fn to_string(&self) -> String { +impl std::fmt::Display for ClassModel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self._class.as_ref().map(|_class| { [ @@ -1986,12 +1926,12 @@ impl std::string::ToString for ClassModel { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ClassModel value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ClassModel { type Err = String; @@ -2047,8 +1987,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ClassModel - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ClassModel - value: {hdr_value} is invalid {e}")) } } } @@ -2063,13 +2002,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ClassModel - {}", - value, err)) + format!("Unable to convert header value '{value}' into ClassModel - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2085,8 +2022,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2106,16 +2042,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ClassModel - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ClassModel - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2149,10 +2083,10 @@ impl Client { } /// Converts the Client value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Client { - fn to_string(&self) -> String { +impl std::fmt::Display for Client { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.client.as_ref().map(|client| { [ @@ -2162,12 +2096,12 @@ impl std::string::ToString for Client { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Client value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Client { type Err = String; @@ -2223,8 +2157,7 @@ impl std::convert::TryFrom> for hyper::header::H match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Client - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Client - value: {hdr_value} is invalid {e}")) } } } @@ -2239,13 +2172,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Client - {}", - value, err)) + format!("Unable to convert header value '{value}' into Client - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2261,8 +2192,7 @@ impl std::convert::TryFrom>> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2282,16 +2212,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Client - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Client - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2334,10 +2262,10 @@ impl Dog { } /// Converts the Dog value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Dog { - fn to_string(&self) -> String { +impl std::fmt::Display for Dog { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("className".to_string()), Some(self.class_name.to_string()), @@ -2355,12 +2283,12 @@ impl std::string::ToString for Dog { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Dog value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Dog { type Err = String; @@ -2424,8 +2352,7 @@ impl std::convert::TryFrom> for hyper::header::Head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Dog - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Dog - value: {hdr_value} is invalid {e}")) } } } @@ -2440,13 +2367,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Dog - {}", - value, err)) + format!("Unable to convert header value '{value}' into Dog - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2462,8 +2387,7 @@ impl std::convert::TryFrom>> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2483,16 +2407,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Dog - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Dog - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2527,10 +2449,10 @@ impl DollarSpecialLeftSquareBracketModelNameRightSquareBracket { } /// Converts the DollarSpecialLeftSquareBracketModelNameRightSquareBracket value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for DollarSpecialLeftSquareBracketModelNameRightSquareBracket { - fn to_string(&self) -> String { +impl std::fmt::Display for DollarSpecialLeftSquareBracketModelNameRightSquareBracket { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.dollar_special_left_square_bracket_property_name_right_square_bracket.as_ref().map(|dollar_special_left_square_bracket_property_name_right_square_bracket| { [ @@ -2540,12 +2462,12 @@ impl std::string::ToString for DollarSpecialLeftSquareBracketModelNameRightSquar }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a DollarSpecialLeftSquareBracketModelNameRightSquareBracket value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for DollarSpecialLeftSquareBracketModelNameRightSquareBracket { type Err = String; @@ -2601,8 +2523,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for DollarSpecialLeftSquareBracketModelNameRightSquareBracket - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for DollarSpecialLeftSquareBracketModelNameRightSquareBracket - value: {hdr_value} is invalid {e}")) } } } @@ -2617,13 +2538,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {}", - value, err)) + format!("Unable to convert header value '{value}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2639,8 +2558,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2660,16 +2578,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into DollarSpecialLeftSquareBracketModelNameRightSquareBracket - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2713,22 +2629,22 @@ impl EnumArrays { } /// Converts the EnumArrays value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for EnumArrays { - fn to_string(&self) -> String { +impl std::fmt::Display for EnumArrays { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type just_symbol in query parameter serialization // Skipping non-primitive type array_enum in query parameter serialization // Skipping non-primitive type array_array_enum in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a EnumArrays value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for EnumArrays { type Err = String; @@ -2790,8 +2706,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumArrays - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumArrays - value: {hdr_value} is invalid {e}")) } } } @@ -2806,13 +2721,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArrays - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumArrays - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2828,8 +2741,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2849,16 +2761,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArrays - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumArrays - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -2902,7 +2812,7 @@ impl std::str::FromStr for EnumArraysArrayArrayEnumInnerInner { match s { "Cat" => std::result::Result::Ok(EnumArraysArrayArrayEnumInnerInner::Cat), "Dog" => std::result::Result::Ok(EnumArraysArrayArrayEnumInnerInner::Dog), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -2918,8 +2828,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumArraysArrayArrayEnumInnerInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumArraysArrayArrayEnumInnerInner - value: {hdr_value} is invalid {e}")) } } } @@ -2934,13 +2843,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysArrayArrayEnumInnerInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumArraysArrayArrayEnumInnerInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -2956,8 +2863,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -2977,16 +2883,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysArrayArrayEnumInnerInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumArraysArrayArrayEnumInnerInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3030,7 +2934,7 @@ impl std::str::FromStr for EnumArraysArrayEnumInner { match s { "fish" => std::result::Result::Ok(EnumArraysArrayEnumInner::Fish), "crab" => std::result::Result::Ok(EnumArraysArrayEnumInner::Crab), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3046,8 +2950,7 @@ impl std::convert::TryFrom> fo match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumArraysArrayEnumInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumArraysArrayEnumInner - value: {hdr_value} is invalid {e}")) } } } @@ -3062,13 +2965,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysArrayEnumInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumArraysArrayEnumInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3084,8 +2985,7 @@ impl std::convert::TryFrom match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3105,16 +3005,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysArrayEnumInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumArraysArrayEnumInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3158,7 +3056,7 @@ impl std::str::FromStr for EnumArraysJustSymbol { match s { ">=" => std::result::Result::Ok(EnumArraysJustSymbol::GreaterThanEqual), "$" => std::result::Result::Ok(EnumArraysJustSymbol::Dollar), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3174,8 +3072,7 @@ impl std::convert::TryFrom> for hy match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumArraysJustSymbol - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumArraysJustSymbol - value: {hdr_value} is invalid {e}")) } } } @@ -3190,13 +3087,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysJustSymbol - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumArraysJustSymbol - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3212,8 +3107,7 @@ impl std::convert::TryFrom>> f match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3233,16 +3127,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumArraysJustSymbol - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumArraysJustSymbol - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3290,7 +3182,7 @@ impl std::str::FromStr for EnumClass { "_abc" => std::result::Result::Ok(EnumClass::Abc), "-efg" => std::result::Result::Ok(EnumClass::Efg), "(xyz)" => std::result::Result::Ok(EnumClass::LeftParenthesisXyzRightParenthesis), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3306,8 +3198,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumClass - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumClass - value: {hdr_value} is invalid {e}")) } } } @@ -3322,13 +3213,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumClass - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumClass - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3344,8 +3233,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3365,16 +3253,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumClass - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumClass - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3427,10 +3313,10 @@ impl EnumTest { } /// Converts the EnumTest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for EnumTest { - fn to_string(&self) -> String { +impl std::fmt::Display for EnumTest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type enum_string in query parameter serialization // Skipping non-primitive type enum_string_required in query parameter serialization @@ -3439,12 +3325,12 @@ impl std::string::ToString for EnumTest { // Skipping non-primitive type outerEnum in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a EnumTest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for EnumTest { type Err = String; @@ -3516,8 +3402,7 @@ impl std::convert::TryFrom> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumTest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumTest - value: {hdr_value} is invalid {e}")) } } } @@ -3532,13 +3417,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTest - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumTest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3554,8 +3437,7 @@ impl std::convert::TryFrom>> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3575,16 +3457,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumTest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3628,7 +3508,7 @@ impl std::str::FromStr for EnumTestEnumInteger { match s { "1" => std::result::Result::Ok(EnumTestEnumInteger::Variant1), "-1" => std::result::Result::Ok(EnumTestEnumInteger::Variant12), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3644,8 +3524,7 @@ impl std::convert::TryFrom> for hyp match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumTestEnumInteger - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumTestEnumInteger - value: {hdr_value} is invalid {e}")) } } } @@ -3660,13 +3539,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTestEnumInteger - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumTestEnumInteger - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3682,8 +3559,7 @@ impl std::convert::TryFrom>> fo match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3703,16 +3579,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTestEnumInteger - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumTestEnumInteger - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3760,7 +3634,7 @@ impl std::str::FromStr for EnumTestEnumString { "UPPER" => std::result::Result::Ok(EnumTestEnumString::Upper), "lower" => std::result::Result::Ok(EnumTestEnumString::Lower), "" => std::result::Result::Ok(EnumTestEnumString::Empty), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3776,8 +3650,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for EnumTestEnumString - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for EnumTestEnumString - value: {hdr_value} is invalid {e}")) } } } @@ -3792,13 +3665,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTestEnumString - {}", - value, err)) + format!("Unable to convert header value '{value}' into EnumTestEnumString - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3814,8 +3685,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3835,16 +3705,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into EnumTestEnumString - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into EnumTestEnumString - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -3892,7 +3760,7 @@ impl std::str::FromStr for FindPetsByStatusStatusParameterInner { "available" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Available), "pending" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Pending), "sold" => std::result::Result::Ok(FindPetsByStatusStatusParameterInner::Sold), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -3908,8 +3776,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for FindPetsByStatusStatusParameterInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for FindPetsByStatusStatusParameterInner - value: {hdr_value} is invalid {e}")) } } } @@ -3924,13 +3791,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into FindPetsByStatusStatusParameterInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into FindPetsByStatusStatusParameterInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -3946,8 +3811,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -3967,16 +3831,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into FindPetsByStatusStatusParameterInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into FindPetsByStatusStatusParameterInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4033,14 +3895,14 @@ pub struct FormatTest { #[serde(rename = "string")] #[validate( - regex = "RE_FORMATTEST_STRING", + regex(path = *RE_FORMATTEST_STRING), )] #[serde(skip_serializing_if="Option::is_none")] pub string: Option, #[serde(rename = "byte")] #[validate( - custom ="validate_byte_formattest_byte" + custom(function = "validate_byte_formattest_byte") )] pub byte: swagger::ByteArray, @@ -4104,10 +3966,10 @@ impl FormatTest { } /// Converts the FormatTest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for FormatTest { - fn to_string(&self) -> String { +impl std::fmt::Display for FormatTest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.integer.as_ref().map(|integer| { [ @@ -4156,12 +4018,12 @@ impl std::string::ToString for FormatTest { Some(self.password.to_string()), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a FormatTest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for FormatTest { type Err = String; @@ -4263,8 +4125,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for FormatTest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for FormatTest - value: {hdr_value} is invalid {e}")) } } } @@ -4279,13 +4140,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into FormatTest - {}", - value, err)) + format!("Unable to convert header value '{value}' into FormatTest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4301,8 +4160,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4322,16 +4180,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into FormatTest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into FormatTest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4370,10 +4226,10 @@ impl HasOnlyReadOnly { } /// Converts the HasOnlyReadOnly value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for HasOnlyReadOnly { - fn to_string(&self) -> String { +impl std::fmt::Display for HasOnlyReadOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.bar.as_ref().map(|bar| { [ @@ -4389,12 +4245,12 @@ impl std::string::ToString for HasOnlyReadOnly { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a HasOnlyReadOnly value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for HasOnlyReadOnly { type Err = String; @@ -4454,8 +4310,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for HasOnlyReadOnly - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for HasOnlyReadOnly - value: {hdr_value} is invalid {e}")) } } } @@ -4470,13 +4325,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into HasOnlyReadOnly - {}", - value, err)) + format!("Unable to convert header value '{value}' into HasOnlyReadOnly - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4492,8 +4345,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4513,16 +4365,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into HasOnlyReadOnly - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into HasOnlyReadOnly - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4556,10 +4406,10 @@ impl List { } /// Converts the List value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for List { - fn to_string(&self) -> String { +impl std::fmt::Display for List { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.param_123_list.as_ref().map(|param_123_list| { [ @@ -4569,12 +4419,12 @@ impl std::string::ToString for List { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a List value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for List { type Err = String; @@ -4630,8 +4480,7 @@ impl std::convert::TryFrom> for hyper::header::Hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for List - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for List - value: {hdr_value} is invalid {e}")) } } } @@ -4646,13 +4495,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into List - {}", - value, err)) + format!("Unable to convert header value '{value}' into List - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4668,8 +4515,7 @@ impl std::convert::TryFrom>> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4689,16 +4535,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into List - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into List - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4742,22 +4586,22 @@ impl MapTest { } /// Converts the MapTest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MapTest { - fn to_string(&self) -> String { +impl std::fmt::Display for MapTest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping map map_map_of_string in query parameter serialization // Skipping map map_map_of_enum in query parameter serialization // Skipping map map_of_enum_string in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MapTest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MapTest { type Err = String; @@ -4818,8 +4662,7 @@ impl std::convert::TryFrom> for hyper::header:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MapTest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MapTest - value: {hdr_value} is invalid {e}")) } } } @@ -4834,13 +4677,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MapTest - {}", - value, err)) + format!("Unable to convert header value '{value}' into MapTest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4856,8 +4697,7 @@ impl std::convert::TryFrom>> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -4877,16 +4717,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MapTest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MapTest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -4930,7 +4768,7 @@ impl std::str::FromStr for MapTestMapMapOfEnumValueValue { match s { "UPPER" => std::result::Result::Ok(MapTestMapMapOfEnumValueValue::Upper), "lower" => std::result::Result::Ok(MapTestMapMapOfEnumValueValue::Lower), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -4946,8 +4784,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MapTestMapMapOfEnumValueValue - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MapTestMapMapOfEnumValueValue - value: {hdr_value} is invalid {e}")) } } } @@ -4962,13 +4799,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MapTestMapMapOfEnumValueValue - {}", - value, err)) + format!("Unable to convert header value '{value}' into MapTestMapMapOfEnumValueValue - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -4984,8 +4819,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5005,16 +4839,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MapTestMapMapOfEnumValueValue - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MapTestMapMapOfEnumValueValue - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5058,22 +4890,22 @@ impl MixedPropertiesAndAdditionalPropertiesClass { } /// Converts the MixedPropertiesAndAdditionalPropertiesClass value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for MixedPropertiesAndAdditionalPropertiesClass { - fn to_string(&self) -> String { +impl std::fmt::Display for MixedPropertiesAndAdditionalPropertiesClass { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type uuid in query parameter serialization // Skipping non-primitive type dateTime in query parameter serialization // Skipping map map in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a MixedPropertiesAndAdditionalPropertiesClass value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for MixedPropertiesAndAdditionalPropertiesClass { type Err = String; @@ -5136,8 +4968,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for MixedPropertiesAndAdditionalPropertiesClass - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for MixedPropertiesAndAdditionalPropertiesClass - value: {hdr_value} is invalid {e}")) } } } @@ -5152,13 +4983,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MixedPropertiesAndAdditionalPropertiesClass - {}", - value, err)) + format!("Unable to convert header value '{value}' into MixedPropertiesAndAdditionalPropertiesClass - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5174,8 +5003,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5195,16 +5023,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into MixedPropertiesAndAdditionalPropertiesClass - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into MixedPropertiesAndAdditionalPropertiesClass - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5245,10 +5071,10 @@ impl Model200Response { } /// Converts the Model200Response value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Model200Response { - fn to_string(&self) -> String { +impl std::fmt::Display for Model200Response { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.name.as_ref().map(|name| { [ @@ -5264,12 +5090,12 @@ impl std::string::ToString for Model200Response { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Model200Response value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Model200Response { type Err = String; @@ -5329,8 +5155,7 @@ impl std::convert::TryFrom> for hyper: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Model200Response - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Model200Response - value: {hdr_value} is invalid {e}")) } } } @@ -5345,13 +5170,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model200Response - {}", - value, err)) + format!("Unable to convert header value '{value}' into Model200Response - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5367,8 +5190,7 @@ impl std::convert::TryFrom>> for h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5388,16 +5210,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Model200Response - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Model200Response - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5447,10 +5267,10 @@ impl Name { } /// Converts the Name value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Name { - fn to_string(&self) -> String { +impl std::fmt::Display for Name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("name".to_string()), Some(self.name.to_string()), @@ -5474,12 +5294,12 @@ impl std::string::ToString for Name { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Name value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Name { type Err = String; @@ -5547,8 +5367,7 @@ impl std::convert::TryFrom> for hyper::header::Hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Name - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Name - value: {hdr_value} is invalid {e}")) } } } @@ -5563,13 +5382,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Name - {}", - value, err)) + format!("Unable to convert header value '{value}' into Name - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5585,8 +5402,7 @@ impl std::convert::TryFrom>> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5606,16 +5422,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Name - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Name - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5649,10 +5463,10 @@ impl NumberOnly { } /// Converts the NumberOnly value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for NumberOnly { - fn to_string(&self) -> String { +impl std::fmt::Display for NumberOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.just_number.as_ref().map(|just_number| { [ @@ -5662,12 +5476,12 @@ impl std::string::ToString for NumberOnly { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a NumberOnly value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for NumberOnly { type Err = String; @@ -5723,8 +5537,7 @@ impl std::convert::TryFrom> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for NumberOnly - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for NumberOnly - value: {hdr_value} is invalid {e}")) } } } @@ -5739,13 +5552,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NumberOnly - {}", - value, err)) + format!("Unable to convert header value '{value}' into NumberOnly - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5761,8 +5572,7 @@ impl std::convert::TryFrom>> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5782,16 +5592,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into NumberOnly - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into NumberOnly - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -5825,20 +5633,20 @@ impl ObjectContainingObjectWithOnlyAdditionalProperties { } /// Converts the ObjectContainingObjectWithOnlyAdditionalProperties value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectContainingObjectWithOnlyAdditionalProperties { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectContainingObjectWithOnlyAdditionalProperties { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type inner in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectContainingObjectWithOnlyAdditionalProperties value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectContainingObjectWithOnlyAdditionalProperties { type Err = String; @@ -5894,8 +5702,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectContainingObjectWithOnlyAdditionalProperties - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectContainingObjectWithOnlyAdditionalProperties - value: {hdr_value} is invalid {e}")) } } } @@ -5910,13 +5717,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectContainingObjectWithOnlyAdditionalProperties - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectContainingObjectWithOnlyAdditionalProperties - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -5932,8 +5737,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -5953,16 +5757,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectContainingObjectWithOnlyAdditionalProperties - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectContainingObjectWithOnlyAdditionalProperties - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6006,17 +5808,17 @@ impl std::ops::DerefMut for ObjectWithOnlyAdditionalProperties { } /// Converts the ObjectWithOnlyAdditionalProperties value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for ObjectWithOnlyAdditionalProperties { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for ObjectWithOnlyAdditionalProperties { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectWithOnlyAdditionalProperties value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for ObjectWithOnlyAdditionalProperties { type Err = &'static str; @@ -6037,8 +5839,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectWithOnlyAdditionalProperties - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectWithOnlyAdditionalProperties - value: {hdr_value} is invalid {e}")) } } } @@ -6053,13 +5854,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectWithOnlyAdditionalProperties - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectWithOnlyAdditionalProperties - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6075,8 +5874,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6096,16 +5894,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectWithOnlyAdditionalProperties - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectWithOnlyAdditionalProperties - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6165,10 +5961,10 @@ impl Order { } /// Converts the Order value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Order { - fn to_string(&self) -> String { +impl std::fmt::Display for Order { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.id.as_ref().map(|id| { [ @@ -6198,12 +5994,12 @@ impl std::string::ToString for Order { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Order value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Order { type Err = String; @@ -6279,8 +6075,7 @@ impl std::convert::TryFrom> for hyper::header::He match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Order - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Order - value: {hdr_value} is invalid {e}")) } } } @@ -6295,13 +6090,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Order - {}", - value, err)) + format!("Unable to convert header value '{value}' into Order - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6317,8 +6110,7 @@ impl std::convert::TryFrom>> for hyper::heade match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6338,16 +6130,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Order - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Order - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6396,7 +6186,7 @@ impl std::str::FromStr for OrderStatus { "placed" => std::result::Result::Ok(OrderStatus::Placed), "approved" => std::result::Result::Ok(OrderStatus::Approved), "delivered" => std::result::Result::Ok(OrderStatus::Delivered), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -6412,8 +6202,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OrderStatus - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OrderStatus - value: {hdr_value} is invalid {e}")) } } } @@ -6428,13 +6217,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OrderStatus - {}", - value, err)) + format!("Unable to convert header value '{value}' into OrderStatus - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6450,8 +6237,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6471,16 +6257,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OrderStatus - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OrderStatus - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6524,16 +6308,16 @@ impl std::ops::DerefMut for OuterBoolean { } /// Converts the OuterBoolean value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for OuterBoolean { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for OuterBoolean { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a OuterBoolean value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for OuterBoolean { type Err = String; @@ -6541,7 +6325,7 @@ impl ::std::str::FromStr for OuterBoolean { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(OuterBoolean(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to OuterBoolean: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OuterBoolean: {e:?}")), } } } @@ -6557,8 +6341,7 @@ impl std::convert::TryFrom> for hyper::hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OuterBoolean - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OuterBoolean - value: {hdr_value} is invalid {e}")) } } } @@ -6573,13 +6356,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterBoolean - {}", - value, err)) + format!("Unable to convert header value '{value}' into OuterBoolean - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6595,8 +6376,7 @@ impl std::convert::TryFrom>> for hyper match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6616,16 +6396,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterBoolean - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OuterBoolean - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6669,10 +6447,10 @@ impl OuterComposite { } /// Converts the OuterComposite value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for OuterComposite { - fn to_string(&self) -> String { +impl std::fmt::Display for OuterComposite { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.my_number.as_ref().map(|my_number| { [ @@ -6694,12 +6472,12 @@ impl std::string::ToString for OuterComposite { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a OuterComposite value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for OuterComposite { type Err = String; @@ -6763,8 +6541,7 @@ impl std::convert::TryFrom> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OuterComposite - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OuterComposite - value: {hdr_value} is invalid {e}")) } } } @@ -6779,13 +6556,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterComposite - {}", - value, err)) + format!("Unable to convert header value '{value}' into OuterComposite - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6801,8 +6576,7 @@ impl std::convert::TryFrom>> for hyp match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6822,16 +6596,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterComposite - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OuterComposite - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -6879,7 +6651,7 @@ impl std::str::FromStr for OuterEnum { "placed" => std::result::Result::Ok(OuterEnum::Placed), "approved" => std::result::Result::Ok(OuterEnum::Approved), "delivered" => std::result::Result::Ok(OuterEnum::Delivered), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -6895,8 +6667,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OuterEnum - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OuterEnum - value: {hdr_value} is invalid {e}")) } } } @@ -6911,13 +6682,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterEnum - {}", - value, err)) + format!("Unable to convert header value '{value}' into OuterEnum - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -6933,8 +6702,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -6954,16 +6722,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterEnum - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OuterEnum - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7007,16 +6773,16 @@ impl std::ops::DerefMut for OuterNumber { } /// Converts the OuterNumber value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for OuterNumber { - fn to_string(&self) -> String { - self.0.to_string() +impl std::fmt::Display for OuterNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) } } /// Converts Query Parameters representation (style=form, explode=false) to a OuterNumber value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for OuterNumber { type Err = String; @@ -7024,7 +6790,7 @@ impl ::std::str::FromStr for OuterNumber { fn from_str(s: &str) -> std::result::Result { match std::str::FromStr::from_str(s) { std::result::Result::Ok(r) => std::result::Result::Ok(OuterNumber(r)), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {} to OuterNumber: {:?}", s, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {s} to OuterNumber: {e:?}")), } } } @@ -7040,8 +6806,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OuterNumber - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OuterNumber - value: {hdr_value} is invalid {e}")) } } } @@ -7056,13 +6821,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterNumber - {}", - value, err)) + format!("Unable to convert header value '{value}' into OuterNumber - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7078,8 +6841,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7099,16 +6861,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterNumber - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OuterNumber - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7151,9 +6911,9 @@ impl std::ops::DerefMut for OuterString { } } -impl std::string::ToString for OuterString { - fn to_string(&self) -> String { - self.0.clone() +impl std::fmt::Display for OuterString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.clone()) } } @@ -7175,8 +6935,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for OuterString - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for OuterString - value: {hdr_value} is invalid {e}")) } } } @@ -7191,13 +6950,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterString - {}", - value, err)) + format!("Unable to convert header value '{value}' into OuterString - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7213,8 +6970,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7234,16 +6990,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into OuterString - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into OuterString - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7301,10 +7055,10 @@ impl Pet { } /// Converts the Pet value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Pet { - fn to_string(&self) -> String { +impl std::fmt::Display for Pet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.id.as_ref().map(|id| { [ @@ -7321,12 +7075,12 @@ impl std::string::ToString for Pet { // Skipping non-primitive type status in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Pet value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Pet { type Err = String; @@ -7400,8 +7154,7 @@ impl std::convert::TryFrom> for hyper::header::Head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Pet - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Pet - value: {hdr_value} is invalid {e}")) } } } @@ -7416,13 +7169,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Pet - {}", - value, err)) + format!("Unable to convert header value '{value}' into Pet - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7438,8 +7189,7 @@ impl std::convert::TryFrom>> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7459,16 +7209,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Pet - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Pet - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7517,7 +7265,7 @@ impl std::str::FromStr for PetStatus { "available" => std::result::Result::Ok(PetStatus::Available), "pending" => std::result::Result::Ok(PetStatus::Pending), "sold" => std::result::Result::Ok(PetStatus::Sold), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -7533,8 +7281,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for PetStatus - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for PetStatus - value: {hdr_value} is invalid {e}")) } } } @@ -7549,13 +7296,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into PetStatus - {}", - value, err)) + format!("Unable to convert header value '{value}' into PetStatus - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7571,8 +7316,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7592,16 +7336,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into PetStatus - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into PetStatus - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7640,10 +7382,10 @@ impl ReadOnlyFirst { } /// Converts the ReadOnlyFirst value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ReadOnlyFirst { - fn to_string(&self) -> String { +impl std::fmt::Display for ReadOnlyFirst { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.bar.as_ref().map(|bar| { [ @@ -7659,12 +7401,12 @@ impl std::string::ToString for ReadOnlyFirst { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ReadOnlyFirst value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ReadOnlyFirst { type Err = String; @@ -7724,8 +7466,7 @@ impl std::convert::TryFrom> for hyper::he match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ReadOnlyFirst - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ReadOnlyFirst - value: {hdr_value} is invalid {e}")) } } } @@ -7740,13 +7481,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ReadOnlyFirst - {}", - value, err)) + format!("Unable to convert header value '{value}' into ReadOnlyFirst - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7762,8 +7501,7 @@ impl std::convert::TryFrom>> for hype match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7783,16 +7521,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ReadOnlyFirst - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ReadOnlyFirst - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -7828,10 +7564,10 @@ impl Return { } /// Converts the Return value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Return { - fn to_string(&self) -> String { +impl std::fmt::Display for Return { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.r#return.as_ref().map(|r#return| { [ @@ -7841,12 +7577,12 @@ impl std::string::ToString for Return { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Return value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Return { type Err = String; @@ -7902,8 +7638,7 @@ impl std::convert::TryFrom> for hyper::header::H match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Return - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Return - value: {hdr_value} is invalid {e}")) } } } @@ -7918,13 +7653,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Return - {}", - value, err)) + format!("Unable to convert header value '{value}' into Return - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -7940,8 +7673,7 @@ impl std::convert::TryFrom>> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -7961,16 +7693,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Return - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Return - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8010,10 +7740,10 @@ impl Tag { } /// Converts the Tag value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for Tag { - fn to_string(&self) -> String { +impl std::fmt::Display for Tag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.id.as_ref().map(|id| { [ @@ -8029,12 +7759,12 @@ impl std::string::ToString for Tag { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a Tag value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for Tag { type Err = String; @@ -8094,8 +7824,7 @@ impl std::convert::TryFrom> for hyper::header::Head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for Tag - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for Tag - value: {hdr_value} is invalid {e}")) } } } @@ -8110,13 +7839,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Tag - {}", - value, err)) + format!("Unable to convert header value '{value}' into Tag - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8132,8 +7859,7 @@ impl std::convert::TryFrom>> for hyper::header: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8153,16 +7879,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into Tag - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into Tag - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8206,7 +7930,7 @@ impl std::str::FromStr for TestEnumParametersEnumHeaderStringArrayParameterInner match s { ">" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringArrayParameterInner::GreaterThan), "$" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringArrayParameterInner::Dollar), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -8222,8 +7946,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for TestEnumParametersEnumHeaderStringArrayParameterInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for TestEnumParametersEnumHeaderStringArrayParameterInner - value: {hdr_value} is invalid {e}")) } } } @@ -8238,13 +7961,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8260,8 +7981,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8281,16 +8001,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumHeaderStringArrayParameterInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8338,7 +8056,7 @@ impl std::str::FromStr for TestEnumParametersEnumHeaderStringParameter { "_abc" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::Abc), "-efg" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::Efg), "(xyz)" => std::result::Result::Ok(TestEnumParametersEnumHeaderStringParameter::LeftParenthesisXyzRightParenthesis), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -8354,8 +8072,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for TestEnumParametersEnumHeaderStringParameter - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for TestEnumParametersEnumHeaderStringParameter - value: {hdr_value} is invalid {e}")) } } } @@ -8370,13 +8087,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumHeaderStringParameter - {}", - value, err)) + format!("Unable to convert header value '{value}' into TestEnumParametersEnumHeaderStringParameter - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8392,8 +8107,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8413,16 +8127,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumHeaderStringParameter - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumHeaderStringParameter - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8466,7 +8178,7 @@ impl std::str::FromStr for TestEnumParametersEnumQueryDoubleParameter { match s { "1.1" => std::result::Result::Ok(TestEnumParametersEnumQueryDoubleParameter::Variant11), "-1.2" => std::result::Result::Ok(TestEnumParametersEnumQueryDoubleParameter::Variant12), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -8482,8 +8194,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for TestEnumParametersEnumQueryDoubleParameter - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for TestEnumParametersEnumQueryDoubleParameter - value: {hdr_value} is invalid {e}")) } } } @@ -8498,13 +8209,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumQueryDoubleParameter - {}", - value, err)) + format!("Unable to convert header value '{value}' into TestEnumParametersEnumQueryDoubleParameter - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8520,8 +8229,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8541,16 +8249,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumQueryDoubleParameter - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumQueryDoubleParameter - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8594,7 +8300,7 @@ impl std::str::FromStr for TestEnumParametersEnumQueryIntegerParameter { match s { "1" => std::result::Result::Ok(TestEnumParametersEnumQueryIntegerParameter::Variant1), "-2" => std::result::Result::Ok(TestEnumParametersEnumQueryIntegerParameter::Variant2), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -8610,8 +8316,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for TestEnumParametersEnumQueryIntegerParameter - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for TestEnumParametersEnumQueryIntegerParameter - value: {hdr_value} is invalid {e}")) } } } @@ -8626,13 +8331,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumQueryIntegerParameter - {}", - value, err)) + format!("Unable to convert header value '{value}' into TestEnumParametersEnumQueryIntegerParameter - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8648,8 +8351,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8669,16 +8371,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersEnumQueryIntegerParameter - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersEnumQueryIntegerParameter - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8727,7 +8427,7 @@ impl std::str::FromStr for TestEnumParametersRequestEnumFormString { "_abc" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::Abc), "-efg" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::Efg), "(xyz)" => std::result::Result::Ok(TestEnumParametersRequestEnumFormString::LeftParenthesisXyzRightParenthesis), - _ => std::result::Result::Err(format!("Value not valid: {}", s)), + _ => std::result::Result::Err(format!("Value not valid: {s}")), } } } @@ -8743,8 +8443,7 @@ impl std::convert::TryFrom std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for TestEnumParametersRequestEnumFormString - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for TestEnumParametersRequestEnumFormString - value: {hdr_value} is invalid {e}")) } } } @@ -8759,13 +8458,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersRequestEnumFormString - {}", - value, err)) + format!("Unable to convert header value '{value}' into TestEnumParametersRequestEnumFormString - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -8781,8 +8478,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -8802,16 +8498,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into TestEnumParametersRequestEnumFormString - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into TestEnumParametersRequestEnumFormString - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -8882,10 +8576,10 @@ impl User { } /// Converts the User value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for User { - fn to_string(&self) -> String { +impl std::fmt::Display for User { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.id.as_ref().map(|id| { [ @@ -8937,12 +8631,12 @@ impl std::string::ToString for User { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a User value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for User { type Err = String; @@ -9026,8 +8720,7 @@ impl std::convert::TryFrom> for hyper::header::Hea match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for User - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for User - value: {hdr_value} is invalid {e}")) } } } @@ -9042,13 +8735,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into User - {}", - value, err)) + format!("Unable to convert header value '{value}' into User - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -9064,8 +8755,7 @@ impl std::convert::TryFrom>> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -9085,16 +8775,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into User - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into User - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs index 0b0af66381ed..1213dfae3c09 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -20,7 +22,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, TestSpecialTagsResponse, @@ -157,7 +159,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -166,7 +169,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -189,7 +193,22 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + multipart_form_size_limit: Some(8 * 1024 * 1024), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -197,11 +216,7 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()) .multipart_form_size_limit(self.multipart_form_size_limit); @@ -209,10 +224,10 @@ impl hyper::service::Service for MakeService where } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -262,26 +277,38 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), + req: (Request, C), multipart_form_size_limit: Option, - ) -> Result, crate::ServiceError> where + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -295,22 +322,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -318,7 +346,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -327,7 +355,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -336,7 +364,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -351,7 +379,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -359,7 +387,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -367,7 +395,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -377,7 +405,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.call123example( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -395,7 +423,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -407,19 +435,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - Err(_) => None, - } + let deserializer = &mut serde_json::Deserializer::from_slice(&body); + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -429,7 +455,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -438,7 +464,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -453,7 +479,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -461,7 +487,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -469,7 +495,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -479,19 +505,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - Err(_) => None, - } + let deserializer = &mut serde_json::Deserializer::from_slice(&body); + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -501,7 +525,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -510,7 +534,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -525,7 +549,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -533,7 +557,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -541,7 +565,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -551,19 +575,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - Err(_) => None, - } + let deserializer = &mut serde_json::Deserializer::from_slice(&body); + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -573,7 +595,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -582,7 +604,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -597,7 +619,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -605,7 +627,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -613,7 +635,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -623,19 +645,17 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); - match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); - unused_elements.push(path.to_string()); - }) { - Ok(param_body) => param_body, - Err(_) => None, - } + let deserializer = &mut serde_json::Deserializer::from_slice(&body); + serde_ignored::deserialize(deserializer, |path| { + warn!("Ignoring unknown field in body: {path}"); + unused_elements.push(path.to_string()); + }).unwrap_or_default() + } else { None }; @@ -645,7 +665,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -654,7 +674,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -669,7 +689,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -677,7 +697,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -685,7 +705,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -695,7 +715,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.fake_response_with_numerical_description( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -713,7 +733,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -735,7 +755,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_query) => Some(param_query), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter query - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter query - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter query")), } }, @@ -745,29 +765,30 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_query) => param_query, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter query")) + .body(body_from_str("Missing required query parameter query")) .expect("Unable to create Bad Request response for missing query parameter query")), }; // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -775,7 +796,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -785,7 +806,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -794,7 +815,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -809,7 +830,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -817,7 +838,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -827,22 +848,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -850,7 +872,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -859,7 +881,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -868,7 +890,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -883,7 +905,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -891,7 +913,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -899,7 +921,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -911,7 +933,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; } @@ -919,7 +941,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { // Form parameters @@ -970,7 +992,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_callback, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -993,7 +1015,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1001,7 +1023,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1018,7 +1040,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header enum_header_string_array - {}", err))) + .body(body_from_string(format!("Invalid header enum_header_string_array - {err}"))) .expect("Unable to create Bad Request response for invalid header enum_header_string_array")); }, @@ -1036,7 +1058,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header enum_header_string - {}", err))) + .body(body_from_string(format!("Invalid header enum_header_string - {err}"))) .expect("Unable to create Bad Request response for invalid header enum_header_string")); }, @@ -1067,7 +1089,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_enum_query_string) => Some(param_enum_query_string), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter enum_query_string - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter enum_query_string - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter enum_query_string")), } }, @@ -1084,7 +1106,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_enum_query_integer) => Some(param_enum_query_integer), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter enum_query_integer - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter enum_query_integer - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter enum_query_integer")), } }, @@ -1101,7 +1123,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_enum_query_double) => Some(param_enum_query_double), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter enum_query_double - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter enum_query_double - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter enum_query_double")), } }, @@ -1111,7 +1133,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { // Form parameters @@ -1129,7 +1151,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_enum_form_string, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1152,7 +1174,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1160,7 +1182,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1170,22 +1192,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_param: Option> = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_param) => param_param, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter param - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter param - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter param due to schema")), } + } else { None }; @@ -1193,7 +1216,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_param) => param_param, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter param")) + .body(BoxBody::new("Missing required body parameter param".to_string())) .expect("Unable to create Bad Request response for missing body parameter param")), }; @@ -1202,7 +1225,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_param, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1211,7 +1234,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1226,7 +1249,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1234,7 +1257,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1244,7 +1267,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { // Form parameters @@ -1259,7 +1282,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_param2, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1277,7 +1300,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1285,7 +1308,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1306,12 +1329,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_hyphen_param) => param_hyphen_param, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter hyphen-param: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter hyphen-param: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["hyphen-param"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["hyphen-param"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -1319,7 +1342,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_hyphen_param, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1337,7 +1360,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1351,7 +1374,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; } @@ -1359,22 +1382,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -1382,7 +1406,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -1391,7 +1415,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1400,7 +1424,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1415,7 +1439,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -1423,7 +1447,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1431,7 +1455,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1443,7 +1467,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1458,9 +1482,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1471,22 +1495,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -1494,7 +1519,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -1503,7 +1528,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1512,7 +1537,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1527,7 +1552,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1535,7 +1560,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1547,7 +1572,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1562,9 +1587,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1582,7 +1607,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_status.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1600,7 +1625,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, FindPetsByStatusResponse::InvalidStatusValue @@ -1613,7 +1638,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1627,7 +1652,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1642,9 +1667,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1662,7 +1687,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_tags.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1680,7 +1705,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, FindPetsByTagsResponse::InvalidTagValue @@ -1693,7 +1718,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1707,7 +1732,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1722,9 +1747,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1735,22 +1760,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { let deserializer = &mut serde_xml_rs::de::Deserializer::new_from_reader(&*body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -1758,7 +1784,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -1767,7 +1793,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1776,7 +1802,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -1801,7 +1827,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1809,7 +1835,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -1821,7 +1847,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -1836,9 +1862,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -1860,12 +1886,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_pet_id) => param_pet_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter petId: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -1879,7 +1905,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(err) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Invalid header api_key - {}", err))) + .body(body_from_string(format!("Invalid header api_key - {err}"))) .expect("Unable to create Bad Request response for invalid header api_key")); }, @@ -1894,7 +1920,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_api_key, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1912,7 +1938,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -1926,7 +1952,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; } @@ -1945,12 +1971,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_pet_id) => param_pet_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter petId: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -1958,7 +1984,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_pet_id, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -1976,7 +2002,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, GetPetByIdResponse::InvalidIDSupplied @@ -1994,7 +2020,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2008,7 +2034,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -2023,9 +2049,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -2047,19 +2073,19 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_pet_id) => param_pet_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter petId: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { // Form parameters @@ -2075,7 +2101,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_status, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2093,7 +2119,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2101,7 +2127,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2113,7 +2139,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; @@ -2128,9 +2154,9 @@ impl hyper::service::Service<(Request, C)> for Service where let missing_scopes = required_scopes.difference(scopes); return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from(missing_scopes.fold( + .body(BoxBody::new(missing_scopes.fold( "Insufficient authorization, missing scopes".to_string(), - |s, scope| format!("{} {}", s, scope)) + |s, scope| format!("{s} {scope}")) )) .expect("Unable to create Authentication Insufficient response") ); @@ -2152,26 +2178,26 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_pet_id) => param_pet_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter petId: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter petId: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["petId"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let boundary = match swagger::multipart::form::boundary(&headers) { Some(boundary) => boundary.to_string(), None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Couldn't find valid multipart body".to_string())) + .body(BoxBody::new("Couldn't find valid multipart body".to_string())) .expect("Unable to create Bad Request response for incorrect boundary")), }; @@ -2189,31 +2215,31 @@ impl hyper::service::Service<(Request, C)> for Service where SaveResult::Partial(_, PartialReason::CountLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive parts".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive parts".to_string())) .expect("Unable to create Bad Request response due to excessive parts")) }, SaveResult::Partial(_, PartialReason::SizeLimit) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to excessive data".to_string())) + .body(BoxBody::new("Unable to process message part due to excessive data".to_string())) .expect("Unable to create Bad Request response due to excessive data")) }, SaveResult::Partial(_, PartialReason::Utf8Error(_)) => { return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Unable to process message part due to invalid data".to_string())) + .body(BoxBody::new("Unable to process message part due to invalid data".to_string())) .expect("Unable to create Bad Request response due to invalid data")) }, SaveResult::Partial(_, PartialReason::IoError(_)) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process message part due an internal error".to_string())) + .body(BoxBody::new("Failed to process message part due an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, SaveResult::Error(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from("Failed to process all message parts due to an internal error".to_string())) + .body(BoxBody::new("Failed to process all message parts due to an internal error".to_string())) .expect("Unable to create Internal Server Error response due to an internal error")) }, }; @@ -2230,7 +2256,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("additional_metadata data does not match API definition : {}", e))) + .body(BoxBody::new(format!("additional_metadata data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter additional_metadata")) } }; @@ -2254,7 +2280,7 @@ impl hyper::service::Service<(Request, C)> for Service where return Ok( Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("file data does not match API definition : {}", e))) + .body(BoxBody::new(format!("file data does not match API definition : {e}"))) .expect("Unable to create Bad Request due to missing required form parameter file")) } }; @@ -2273,7 +2299,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_file, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2291,7 +2317,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -2299,7 +2325,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2307,7 +2333,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2319,7 +2345,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; } @@ -2327,7 +2353,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.get_inventory( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2345,7 +2371,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -2353,7 +2379,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2365,22 +2391,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -2388,7 +2415,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -2397,7 +2424,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2406,7 +2433,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -2421,7 +2448,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, PlaceOrderResponse::InvalidOrder @@ -2434,7 +2461,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2442,7 +2469,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2463,12 +2490,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_order_id) => param_order_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter order_id: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter order_id: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -2476,7 +2503,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_order_id, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2499,7 +2526,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2522,12 +2549,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_order_id) => param_order_id, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter order_id: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter order_id: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["order_id"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -2535,7 +2562,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_order_id, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2553,7 +2580,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, GetOrderByIdResponse::InvalidIDSupplied @@ -2571,7 +2598,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2583,22 +2610,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -2606,7 +2634,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -2615,7 +2643,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2624,7 +2652,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -2639,7 +2667,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2647,7 +2675,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2657,22 +2685,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option> = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -2680,7 +2709,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -2689,7 +2718,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2698,7 +2727,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -2713,7 +2742,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2721,7 +2750,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2731,22 +2760,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option> = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -2754,7 +2784,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -2763,7 +2793,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body.as_ref(), &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2772,7 +2802,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -2787,7 +2817,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2795,7 +2825,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -2815,7 +2845,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_username) => Some(param_username), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter username - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter username - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter username")), } }, @@ -2825,7 +2855,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_username) => param_username, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter username")) + .body(body_from_str("Missing required query parameter username")) .expect("Unable to create Bad Request response for missing query parameter username")), }; let param_password = query_params.iter().filter(|e| e.0 == "password").map(|e| e.1.clone()) @@ -2839,7 +2869,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_password) => Some(param_password), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse query parameter password - doesn't match schema: {}", e))) + .body(body_from_string(format!("Couldn't parse query parameter password - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid query parameter password")), } }, @@ -2849,7 +2879,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_password) => param_password, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required query parameter password")) + .body(body_from_str("Missing required query parameter password")) .expect("Unable to create Bad Request response for missing query parameter password")), }; @@ -2858,7 +2888,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_password, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2881,7 +2911,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling x_rate_limit header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling x_rate_limit header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -2898,7 +2928,7 @@ impl hyper::service::Service<(Request, C)> for Service where Err(e) => { return Ok(Response::builder() .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(format!("An internal server error occurred handling x_expires_after header - {}", e))) + .body(body_from_string(format!("An internal server error occurred handling x_expires_after header - {e}"))) .expect("Unable to create Internal Server Error for invalid response header")) } }; @@ -2914,7 +2944,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, LoginUserResponse::InvalidUsername @@ -2927,7 +2957,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2939,7 +2969,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.logout_user( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -2957,7 +2987,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -2980,12 +3010,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_username) => param_username, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter username: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -2993,7 +3023,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_username, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -3016,7 +3046,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -3039,12 +3069,12 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_username) => param_username, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter username: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; @@ -3052,7 +3082,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_username, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -3070,7 +3100,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/xml")); // XML Body let body = serde_xml_rs::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, GetUserByNameResponse::InvalidUsernameSupplied @@ -3088,7 +3118,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -3111,34 +3141,35 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_username) => param_username, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse path parameter username: {}", e))) + .body(body_from_string(format!("Couldn't parse path parameter username: {e}"))) .expect("Unable to create Bad Request response for invalid path parameter")), }, Err(_) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) + .body(body_from_string(format!("Couldn't percent-decode path parameter as UTF-8: {}", &path_params["username"]))) .expect("Unable to create Bad Request response for invalid percent decode")) }; // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_body: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_body) => param_body, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to schema")), } + } else { None }; @@ -3146,7 +3177,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -3156,7 +3187,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -3165,7 +3196,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -3185,7 +3216,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -3193,7 +3224,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -3226,7 +3257,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_USER_LOGOUT) => method_not_allowed(), _ if path.matched(paths::ID_USER_USERNAME) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/.cargo/config.toml b/samples/server/petstore/rust-server/output/ping-bearer-auth/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/ping-bearer-auth/.openapi-generator/FILES index ce2109b1de2e..913ced3d98a4 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml index c8e60c539bba..6ab9a74369e1 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml @@ -10,73 +10,80 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/bin/cli.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/bin/cli.rs index 5838290c33a9..74286933066e 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -8,7 +9,6 @@ use ping_bearer_auth::{ PingGetResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -18,48 +18,48 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "ping test", version = "1.0", about = "CLI access to ping test" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, /// Bearer token if used for authentication - #[structopt(env = "PING_BEARER_AUTH_BEARER_TOKEN", hide_env_values = true)] + #[arg(env = "PING_BEARER_AUTH_BEARER_TOKEN", hide_env = true)] bearer_token: Option, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { PingGet { }, @@ -100,7 +100,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -111,7 +111,7 @@ async fn main() -> Result<()> { if let Some(ref bearer_token) = args.bearer_token { debug!("Using bearer token"); - auth_data = Some(AuthData::bearer(bearer_token)); + auth_data = AuthData::bearer(bearer_token); } #[allow(trivial_casts)] @@ -151,6 +151,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/client/main.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/client/main.rs index e19f556283f4..24d1f7fe28ef 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/client/main.rs @@ -7,7 +7,7 @@ use futures::{future, Stream, stream}; use ping_bearer_auth::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, PingGetResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -30,25 +30,23 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ "PingGet", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -72,22 +70,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -102,7 +100,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { Some("PingGet") => { let result = rt.block_on(client.ping_get( )); diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/main.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/main.rs index 6b54873a7e94..dd1bc41aaea0 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server.rs index 7cac3452a975..8ab78be8cb33 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use ping_bearer_auth::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server_auth.rs index 15b1fc1a4443..072c7f2a3d43 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use ping_bearer_auth::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -87,7 +87,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -124,4 +124,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/auth.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/auth.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/client/mod.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/client/mod.rs index 9e6dfec94b3f..7918d022c501 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -54,15 +57,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -79,8 +81,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -92,8 +93,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -107,8 +107,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -122,7 +133,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -131,8 +142,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -144,26 +155,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -174,7 +178,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -187,13 +191,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -210,13 +214,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -227,18 +242,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -251,7 +277,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -272,7 +298,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -300,8 +326,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -363,28 +388,31 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Has> + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn ping_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/ping", self.base_path @@ -402,43 +430,43 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); #[allow(clippy::collapsible_match)] if let Some(auth_data) = Has::>::get(context).as_ref() { + use headers::authorization::Credentials; #[allow(clippy::single_match, clippy::match_single_binding)] match auth_data { - AuthData::Bearer(bearer_header) => { - let auth = swagger::auth::Header(bearer_header.clone()); - let header = match HeaderValue::from_str(&format!("{}", auth)) { + AuthData::Bearer(ref bearer_header) => { + let header = match headers::Authorization::bearer(&bearer_header.to_string()) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create Authorization header: {e}"))) }; request.headers_mut().insert( hyper::header::AUTHORIZATION, - header); + header.0.encode()); }, _ => {} } } let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 201 => { @@ -448,18 +476,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/context.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/context.rs index e01187ca3c82..7a52731cc064 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/context.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,49 +87,32 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); { - use swagger::auth::Bearer; + use headers::authorization::Bearer; use std::ops::Deref; - if let Some(bearer) = swagger::auth::from_headers::(headers) { - let authorization = self.inner.bearer_authorization(&bearer); - let auth_data = AuthData::Bearer(bearer); - - let context = context.push(Some(auth_data)); - let context = match authorization { - Ok(auth) => context.push(Some(auth)), - Err(err) => { - error!("Error during Authorization: {err:?}"); - context.push(None::) - } - }; + if let Some(bearer) = swagger::auth::from_headers(headers) { + let context = context.push(Some(bearer)); return self.inner.call((request, context)) } } let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/header.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/header.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/lib.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/lib.rs index 495d022b04a3..def1947605e2 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/lib.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/lib.rs @@ -30,10 +30,6 @@ pub enum PingGetResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn ping_get( &self, context: &C) -> Result; @@ -45,8 +41,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn ping_get( @@ -70,10 +64,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/mod.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/mod.rs index 04b60fe04545..18d45e899da7 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,7 +20,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, PingGetResponse @@ -39,7 +41,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -47,7 +50,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -59,7 +63,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Has> + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Has> + Send + Sync + 'static { @@ -67,21 +85,17 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -118,25 +132,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Has> + Send + Sync + 'static + C: Has + Has> + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -152,7 +178,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(ref authorization) => authorization, None => return Ok(Response::builder() .status(StatusCode::FORBIDDEN) - .body(Body::from("Unauthenticated")) + .body(body_from_str("Unauthenticated")) .expect("Unable to create Authentication Forbidden response")), }; } @@ -160,7 +186,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.ping_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -178,7 +204,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -187,7 +213,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_PING) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/samples/server/petstore/rust-server/output/rust-server-test/.cargo/config.toml b/samples/server/petstore/rust-server/output/rust-server-test/.cargo/config.toml new file mode 100644 index 000000000000..df91f0f117f3 --- /dev/null +++ b/samples/server/petstore/rust-server/output/rust-server-test/.cargo/config.toml @@ -0,0 +1,19 @@ +[build] +rustflags = [ + "-W", "missing_docs", # detects missing documentation for public members + + "-W", "trivial_casts", # detects trivial casts which could be removed + + "-W", "trivial_numeric_casts", # detects trivial casts of numeric types which could be removed + + # unsafe is used in `TokioIo` bridging code copied from `hyper`. + # "-W", "unsafe_code", # usage of `unsafe` code + + "-W", "unused_qualifications", # detects unnecessarily qualified names + + "-W", "unused_extern_crates", # extern crates that are never used + + "-W", "unused_import_braces", # unnecessary braces around an imported item + + "-D", "warnings", # all warnings should be denied +] diff --git a/samples/server/petstore/rust-server/output/rust-server-test/.openapi-generator/FILES b/samples/server/petstore/rust-server/output/rust-server-test/.openapi-generator/FILES index e27ac4b0b61a..0d2f1da19df9 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/.openapi-generator/FILES +++ b/samples/server/petstore/rust-server/output/rust-server-test/.openapi-generator/FILES @@ -1,4 +1,4 @@ -.cargo/config +.cargo/config.toml .gitignore Cargo.toml README.md diff --git a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml index f85aaea14517..1c6252b9e823 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml +++ b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml @@ -10,73 +10,80 @@ edition = "2018" [features] default = ["client", "server"] client = [ - "hyper", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" + "hyper", "hyper-util/http1", "hyper-util/http2", "hyper-openssl", "hyper-tls", "native-tls", "openssl", "url" ] server = [ "serde_ignored", "hyper", "regex", "percent-encoding", "url", "lazy_static" ] cli = [ - "anyhow", "clap-verbosity-flag", "simple_logger", "structopt", "tokio" + "anyhow", "clap", "clap-verbosity-flag", "simple_logger", "tokio" ] conversion = ["frunk", "frunk_derives", "frunk_core", "frunk-enum-core", "frunk-enum-derive"] [target.'cfg(any(target_os = "macos", target_os = "windows", target_os = "ios"))'.dependencies] native-tls = { version = "0.2", optional = true } -hyper-tls = { version = "0.5", optional = true } +hyper-tls = { version = "0.6", optional = true } [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dependencies] -hyper-openssl = { version = "0.9", optional = true } -openssl = {version = "0.10", optional = true } +hyper-openssl = { version = "0.10", optional = true } +openssl = { version = "0.10", optional = true } [dependencies] # Common -async-trait = "0.1.24" +async-trait = "0.1.88" chrono = { version = "0.4", features = ["serde"] } futures = "0.3" -swagger = { version = "6.1", features = ["serdejson", "server", "client", "tls", "tcp"] } -log = "0.4.0" +swagger = { version = "7.0.0-rc2", features = ["serdejson", "server", "client", "tls"] } +headers = "0.4.0" +log = "0.4.27" mime = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -validator = { version = "0.16", features = ["derive"] } +validator = { version = "0.20", features = ["derive"] } # Crates included if required by the API definition # Common between server and client features -hyper = {version = "0.14", features = ["full"], optional = true} -serde_ignored = {version = "0.1.1", optional = true} -url = {version = "2.1", optional = true} +bytes = "1.10.1" +http-body-util = "0.1.3" +hyper = { version = "1.6", features = ["full"], optional = true } +hyper-util = { version = "0.1.12", features = ["service"] } +serde_ignored = { version = "0.1.12", optional = true } +url = { version = "2.5", optional = true } # Client-specific +tower-service = "0.3.3" # Server, and client callback-specific -lazy_static = { version = "1.4", optional = true } -percent-encoding = {version = "2.1.0", optional = true} -regex = {version = "1.3", optional = true} +lazy_static = { version = "1.5", optional = true } +percent-encoding = { version = "2.3.1", optional = true } +regex = { version = "1.11", optional = true } # CLI-specific anyhow = { version = "1", optional = true } -clap-verbosity-flag = { version = "0.3", optional = true } -simple_logger = { version = "2.0", features = ["stderr"], optional = true } -structopt = { version = "0.3", optional = true } -tokio = { version = "0.2", features = ["rt-threaded", "macros", "stream"], optional = true } +clap = { version = "4.5", features = ["env"], optional = true } +clap-verbosity-flag = { version = "3.0", optional = true } +simple_logger = { version = "5.0", features = ["stderr"], optional = true } +tokio = { version = "1.45", features = ["rt-multi-thread", "macros"], optional = true } # Conversion -frunk = { version = "0.4.0", optional = true } -frunk_derives = { version = "0.4.0", optional = true } -frunk_core = { version = "0.4.0", optional = true } +frunk = { version = "0.4.3", optional = true } +frunk_derives = { version = "0.4.3", optional = true } +frunk_core = { version = "0.4.3", optional = true } frunk-enum-derive = { version = "0.3.0", optional = true } frunk-enum-core = { version = "0.3.0", optional = true } # Bearer authentication -jsonwebtoken = { version = "9.3.0", optional = false } +jsonwebtoken = { version = "9.3.1", optional = false } [dev-dependencies] -clap = "2.25" +always_send = "0.1.1" +clap = "4.5" env_logger = "0.11" -tokio = { version = "1.14", features = ["full"] } +tokio = { version = "1.45", features = ["full"] } native-tls = "0.2" +pin-project = "1.1.10" [target.'cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))'.dev-dependencies] tokio-openssl = "0.6" diff --git a/samples/server/petstore/rust-server/output/rust-server-test/bin/cli.rs b/samples/server/petstore/rust-server/output/rust-server-test/bin/cli.rs index e582c479c363..01cbbf1f003a 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/bin/cli.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/bin/cli.rs @@ -1,5 +1,6 @@ //! CLI tool driving the API client use anyhow::{anyhow, Context, Result}; +use clap::Parser; use log::{debug, info}; // models may be unused if all inputs are primitive types #[allow(unused_imports)] @@ -16,7 +17,6 @@ use rust_server_test::{ SoloObjectPostResponse, }; use simple_logger::SimpleLogger; -use structopt::StructOpt; use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString}; type ClientContext = swagger::make_context_ty!( @@ -26,44 +26,44 @@ type ClientContext = swagger::make_context_ty!( XSpanIdString ); -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "rust-server-test", version = "2.3.4", about = "CLI access to rust-server-test" )] struct Cli { - #[structopt(subcommand)] + #[clap(subcommand)] operation: Operation, /// Address or hostname of the server hosting this API, including optional port - #[structopt(short = "a", long, default_value = "http://localhost")] + #[clap(short = 'a', long, default_value = "http://localhost")] server_address: String, /// Path to the client private key if using client-side TLS authentication #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-certificate", "server-certificate"]))] + #[clap(long, requires_all(&["client_certificate", "server_certificate"]))] client_key: Option, /// Path to the client's public certificate associated with the private key #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long, requires_all(&["client-key", "server-certificate"]))] + #[clap(long, requires_all(&["client_key", "server_certificate"]))] client_certificate: Option, /// Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] - #[structopt(long)] + #[clap(long)] server_certificate: Option, /// If set, write output to file instead of stdout - #[structopt(short, long)] + #[clap(short, long)] output_file: Option, - #[structopt(flatten)] + #[command(flatten)] verbosity: clap_verbosity_flag::Verbosity, } -#[derive(StructOpt, Debug)] +#[derive(Parser, Debug)] enum Operation { AllOfGet { }, @@ -71,7 +71,7 @@ enum Operation { DummyGet { }, DummyPut { - #[structopt(parse(try_from_str = parse_json))] + #[clap(value_parser = parse_json::)] nested_response: models::DummyPutRequest, }, /// Get a file @@ -131,7 +131,7 @@ fn create_client(args: &Cli, context: ClientContext) -> Result Result<()> { - let args = Cli::from_args(); + let args = Cli::parse(); if let Some(log_level) = args.verbosity.log_level() { SimpleLogger::new().with_level(log_level.to_level_filter()).init()?; } @@ -307,6 +307,6 @@ async fn main() -> Result<()> { // May be unused if all inputs are primitive types #[allow(dead_code)] -fn parse_json<'a, T: serde::de::Deserialize<'a>>(json_string: &'a str) -> Result { +fn parse_json(json_string: &str) -> Result { serde_json::from_str(json_string).map_err(|err| anyhow!("Error parsing input: {}", err)) } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs index 99939f148aff..63ebeec10bff 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/client/main.rs @@ -15,7 +15,7 @@ use rust_server_test::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, mod RawJsonGetResponse, SoloObjectPostResponse, }; -use clap::{App, Arg}; +use clap::{Command, Arg}; // NOTE: Set environment variable RUST_LOG to the name of the executable (or "cargo run") to activate console logging for all loglevels. // See https://docs.rs/env_logger/latest/env_logger/ for more details @@ -38,31 +38,31 @@ use client_auth::build_token; fn main() { env_logger::init(); - let matches = App::new("client") - .arg(Arg::with_name("operation") + let matches = Command::new("client") + .arg(Arg::new("operation") .help("Sets the operation to run") - .possible_values(&[ + .value_parser([ "AllOfGet", "DummyGet", + "DummyPut", "FileResponseGet", "GetStructuredYaml", "HtmlPost", "PostYaml", "RawJsonGet", + "SoloObjectPost", ]) .required(true) .index(1)) - .arg(Arg::with_name("https") + .arg(Arg::new("https") .long("https") .help("Whether to use HTTPS or not")) - .arg(Arg::with_name("host") + .arg(Arg::new("host") .long("host") - .takes_value(true) .default_value("localhost") .help("Hostname to contact")) - .arg(Arg::with_name("port") + .arg(Arg::new("port") .long("port") - .takes_value(true) .default_value("8080") .help("Port to contact")) .get_matches(); @@ -86,22 +86,22 @@ fn main() { b"secret").unwrap(); let auth_data = if !auth_token.is_empty() { - Some(AuthData::Bearer(swagger::auth::Bearer { token: auth_token})) + Some(AuthData::Bearer(auth_token)) } else { // No Bearer-token available, so return None None }; - let is_https = matches.is_present("https"); + let is_https = matches.contains_id("https"); let base_url = format!("{}://{}:{}", if is_https { "https" } else { "http" }, - matches.value_of("host").unwrap(), - matches.value_of("port").unwrap()); + matches.get_one::("host").unwrap(), + matches.get_one::("port").unwrap()); let context: ClientContext = swagger::make_context!(ContextBuilder, EmptyContext, auth_data, XSpanIdString::default()); - let mut client : Box> = if matches.is_present("https") { + let mut client : Box> = if is_https { // Using Simple HTTPS let client = Box::new(Client::try_new_https(&base_url) .expect("Failed to create HTTPS client")); @@ -116,7 +116,7 @@ fn main() { let mut rt = tokio::runtime::Runtime::new().unwrap(); - match matches.value_of("operation") { + match matches.get_one::("operation").map(String::as_str) { Some("AllOfGet") => { let result = rt.block_on(client.all_of_get( )); diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs index 7492252060e2..4ebb86603915 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/main.rs @@ -3,26 +3,26 @@ #![allow(missing_docs)] - -use clap::{App, Arg}; +use clap::{Arg, Command}; mod server; mod server_auth; - /// Create custom server, wire it to the autogenerated router, /// and pass it to the web server. #[tokio::main] async fn main() { env_logger::init(); - let matches = App::new("server") - .arg(Arg::with_name("https") - .long("https") - .help("Whether to use HTTPS or not")) + let matches = Command::new("server") + .arg( + Arg::new("https") + .long("https") + .help("Whether to use HTTPS or not"), + ) .get_matches(); let addr = "127.0.0.1:8080"; - server::create(addr, matches.is_present("https")).await; + server::create(addr, matches.contains_id("https")).await; } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs index 00240b2ecdce..2670ed062857 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server.rs @@ -4,8 +4,9 @@ use async_trait::async_trait; use futures::{future, Stream, StreamExt, TryFutureExt, TryStreamExt}; -use hyper::server::conn::Http; -use hyper::service::Service; +use hyper::server::conn::http1; +use hyper_util::rt::TokioIo; +use hyper::service::{service_fn, Service}; use log::info; use std::future::Future; use std::marker::PhantomData; @@ -24,12 +25,12 @@ use rust_server_test::models; /// Builds an SSL implementation for Simple HTTPS from some hard-coded file names pub async fn create(addr: &str, https: bool) { - let addr = addr.parse().expect("Failed to parse bind address"); + let addr: SocketAddr = addr.parse().expect("Failed to parse bind address"); + let listener = TcpListener::bind(&addr).await.unwrap(); let server = Server::new(); let service = MakeService::new(server); - let service = MakeAllowAllAuthenticator::new(service, "cosmo"); #[allow(unused_mut)] @@ -54,21 +55,19 @@ pub async fn create(addr: &str, https: bool) { ssl.check_private_key().expect("Failed to check private key"); let tls_acceptor = ssl.build(); - let tcp_listener = TcpListener::bind(&addr).await.unwrap(); info!("Starting a server (with https)"); loop { - if let Ok((tcp, _)) = tcp_listener.accept().await { + if let Ok((tcp, addr)) = listener.accept().await { let ssl = Ssl::new(tls_acceptor.context()).unwrap(); - let addr = tcp.peer_addr().expect("Unable to get remote address"); let service = service.call(addr); tokio::spawn(async move { let tls = tokio_openssl::SslStream::new(ssl, tcp).map_err(|_| ())?; let service = service.await.map_err(|_| ())?; - Http::new() - .serve_connection(tls, service) + http1::Builder::new() + .serve_connection(TokioIo::new(tls), service) .await .map_err(|_| ()) }); @@ -78,11 +77,41 @@ pub async fn create(addr: &str, https: bool) { } else { info!("Starting a server (over http, so no TLS)"); // Using HTTP - hyper::server::Server::bind(&addr).serve(service).await.unwrap() + let listener = TcpListener::bind(&addr).await.unwrap(); + println!("Listening on http://{}", addr); + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (tcp_stream, addr) = listener.accept().await.expect("Failed to accept connection"); + + let service = service.call(addr).await.unwrap(); + let io = TokioIo::new(tcp_stream); + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP1 connection we just received + // to finish + tokio::task::spawn(async move { + // Handle the connection from the client using HTTP1 and pass any + // HTTP requests received on that connection to the `hello` function + let result = http1::Builder::new() + .serve_connection(io, service) + .await; + if let Err(err) = result + { + println!("Error serving connection: {err:?}"); + } + }); + } } } -#[derive(Copy, Clone)] +#[derive(Copy)] pub struct Server { marker: PhantomData, } @@ -93,6 +122,14 @@ impl Server { } } +impl Clone for Server { + fn clone(&self) -> Self { + Self { + marker: PhantomData, + } + } +} + use jsonwebtoken::{decode, encode, errors::Error as JwtError, Algorithm, DecodingKey, EncodingKey, Header, TokenData, Validation}; use serde::{Deserialize, Serialize}; diff --git a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server_auth.rs b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server_auth.rs index 3191e2f7dcb9..91e4570add86 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/examples/server/server_auth.rs @@ -1,8 +1,8 @@ use swagger::{ ApiError, - auth::{Basic, Bearer}, Has, XSpanIdString}; +use headers::authorization::{Basic, Bearer}; use rust_server_test::{AuthenticationApi, Claims}; use crate::server::Server; use jsonwebtoken::{decode, errors as JwtError, decode_header, DecodingKey, TokenData, Validation}; @@ -87,7 +87,7 @@ impl AuthenticationApi for Server where C: Has + Send + Syn fn bearer_authorization(&self, bearer: &Bearer) -> Result { debug!("\tAuthorizationApi: Received Bearer-token, {bearer:#?}"); - match extract_token_data(&bearer.token, b"secret") { + match extract_token_data(&bearer.token(), b"secret") { Ok(auth_data) => { debug!("\tUnpack auth_data as: {auth_data:#?}"); let authorization = build_authorization(auth_data.claims); @@ -124,4 +124,3 @@ impl AuthenticationApi for Server where C: Has + Send + Syn } } - diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/auth.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/auth.rs index d2b1481eeb81..f363db66d495 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/auth.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/auth.rs @@ -1,8 +1,8 @@ use std::collections::BTreeSet; use crate::server::Authorization; use serde::{Deserialize, Serialize}; -use swagger::{ApiError, auth::{Basic, Bearer}}; - +use swagger::ApiError; +use headers::authorization::{Basic, Bearer}; #[derive(Debug, Serialize, Deserialize)] pub struct Claims { pub sub: String, @@ -24,7 +24,7 @@ pub trait AuthenticationApi { /// Method should be implemented (see example-code) to map Basic (Username:password) to an Authorization fn basic_authorization(&self, basic: &Basic) -> Result; -} +} // Implement it for AllowAllAuthenticator (dummy is needed, but should not used as we have Bearer authorization) use swagger::auth::{AllowAllAuthenticator, RcBound, Scopes}; diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs index a88ea9dea0ae..42f7f75ed4b4 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/client/mod.rs @@ -1,10 +1,12 @@ use async_trait::async_trait; +use bytes::Bytes; use futures::{Stream, future, future::BoxFuture, stream, future::TryFutureExt, future::FutureExt, stream::StreamExt}; +use http_body_util::{combinators::BoxBody, Full}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; -use hyper::{Body, Request, Response, service::Service, Uri}; +use hyper::{body::{Body, Incoming}, Request, Response, service::Service, Uri}; use percent_encoding::{utf8_percent_encode, AsciiSet}; use std::borrow::Cow; -use std::convert::TryInto; +use std::convert::{TryInto, Infallible}; use std::io::{ErrorKind, Read}; use std::error::Error; use std::future::Future; @@ -18,6 +20,7 @@ use std::string::ToString; use std::task::{Context, Poll}; use swagger::{ApiError, AuthData, BodyExt, Connector, DropContextService, Has, XSpanIdString}; use url::form_urlencoded; +use tower_service::Service as _; use crate::models; @@ -62,15 +65,14 @@ fn into_base_path(input: impl TryInto, } let host = uri.host().ok_or(ClientInitError::MissingHost)?; - let port = uri.port_u16().map(|x| format!(":{}", x)).unwrap_or_default(); - Ok(format!("{}://{}{}{}", scheme, host, port, uri.path().trim_end_matches('/'))) + let port = uri.port_u16().map(|x| format!(":{x}")).unwrap_or_default(); + Ok(format!("{scheme}://{host}{port}{}", uri.path().trim_end_matches('/'))) } /// A client that implements the API by making HTTP calls out to a server. pub struct Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -87,8 +89,7 @@ pub struct Client where impl fmt::Debug for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -100,8 +101,7 @@ impl fmt::Debug for Client where impl Clone for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -115,8 +115,19 @@ impl Clone for Client where } } -impl Client, C>, C> where - Connector: hyper::client::connect::Connect + Clone + Send + Sync + 'static, +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + Connector, + BoxBody + > + >, + C + >, + C +> where + Connector: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static, C: Clone + Send + Sync + 'static, { /// Create a client with a custom implementation of hyper::client::Connect. @@ -130,7 +141,7 @@ impl Client" /// * `protocol` - Which protocol to use when constructing the request url, e.g. `Some("http")` /// * `connector` - Implementation of `hyper::client::Connect` to use for the client pub fn try_new_with_connector( @@ -139,8 +150,8 @@ impl Client Result { - let client_service = hyper::client::Client::builder().build(connector); - let client_service = DropContextService::new(client_service); + let client_service = hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector); + let client_service = DropContextService::new(hyper_util::service::TowerToHyperService::new(client_service)); Ok(Self { client_service, @@ -152,26 +163,19 @@ impl Client), - Https(hyper::client::Client), + Http(hyper_util::client::legacy::Client>), + Https(hyper_util::client::legacy::Client>), } -impl Service> for HyperClient { - type Response = Response; - type Error = hyper::Error; - type Future = hyper::client::ResponseFuture; - - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - match self { - HyperClient::Http(client) => client.poll_ready(cx), - HyperClient::Https(client) => client.poll_ready(cx), - } - } +impl Service>> for HyperClient { + type Response = Response; + type Error = hyper_util::client::legacy::Error; + type Future = hyper_util::client::legacy::ResponseFuture; - fn call(&mut self, req: Request) -> Self::Future { + fn call(&self, req: Request>) -> Self::Future { match self { - HyperClient::Http(client) => client.call(req), - HyperClient::Https(client) => client.call(req) + HyperClient::Http(client) => client.request(req), + HyperClient::Https(client) => client.request(req) } } } @@ -182,7 +186,7 @@ impl Client, C> where /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new( base_path: &str, ) -> Result { @@ -195,13 +199,13 @@ impl Client, C> where let client_service = match scheme.as_str() { "http" => { - HyperClient::Http(hyper::client::Client::builder().build(connector.build())) + HyperClient::Http(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector.build())) }, "https" => { let connector = connector.https() .build() .map_err(ClientInitError::SslError)?; - HyperClient::Https(hyper::client::Client::builder().build(connector)) + HyperClient::Https(hyper_util::client::legacy::Client::builder(hyper_util::rt::TokioExecutor::new()).build(connector)) }, _ => { return Err(ClientInitError::InvalidScheme); @@ -218,13 +222,24 @@ impl Client, C> where } } -impl Client, C>, C> where +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + hyper_util::client::legacy::connect::HttpConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create an HTTP client. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "http://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_http( base_path: &str, ) -> Result { @@ -235,18 +250,29 @@ impl Client; +type HttpsConnector = hyper_tls::HttpsConnector; #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] -type HttpsConnector = hyper_openssl::HttpsConnector; - -impl Client, C>, C> where +type HttpsConnector = hyper_openssl::client::legacy::HttpsConnector; + +impl Client< + DropContextService< + hyper_util::service::TowerToHyperService< + hyper_util::client::legacy::Client< + HttpsConnector, + BoxBody + > + >, + C + >, + C +> where C: Clone + Send + Sync + 'static { /// Create a client with a TLS connection to the server /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" pub fn try_new_https(base_path: &str) -> Result { let https_connector = Connector::builder() @@ -259,7 +285,7 @@ impl Client, C /// Create a client with a TLS connection to the server using a pinned certificate /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "ios")))] pub fn try_new_https_pinned( @@ -280,7 +306,7 @@ impl Client, C /// Create a client with a mutually authenticated TLS connection to the server. /// /// # Arguments - /// * `base_path` - base path of the client API, i.e. "https://www.my-api-implementation.com" + /// * `base_path` - base path of the client API, i.e. "" /// * `ca_certificate` - Path to CA certificate used to authenticate the server /// * `client_key` - Path to the client private key /// * `client_certificate` - Path to the client's public certificate associated with the private key @@ -308,8 +334,7 @@ impl Client, C impl Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C)> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Clone + Send + Sync + 'static @@ -371,28 +396,31 @@ impl Error for ClientInitError { } } +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + #[async_trait] -impl Api for Client where +impl Api for Client where S: Service< - (Request, C), - Response=Response> + Clone + Sync + Send + 'static, + (Request>, C), + Response=Response> + Clone + Sync + Send + 'static, S::Future: Send + 'static, S::Error: Into + fmt::Display, C: Has + Clone + Send + Sync + 'static, + B: hyper::body::Body + Send + 'static + Unpin, + B::Data: Send, + B::Error: Into>, { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - match self.client_service.clone().poll_ready(cx) { - Poll::Ready(Err(e)) => Poll::Ready(Err(e.into())), - Poll::Ready(Ok(o)) => Poll::Ready(Ok(o)), - Poll::Pending => Poll::Pending, - } - } + #[allow(clippy::vec_init_then_push)] async fn all_of_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/allOf", self.base_path @@ -410,37 +438,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(AllOfGetResponse::OK @@ -449,29 +478,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn dummy_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/dummy", self.base_path @@ -489,25 +518,25 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -517,30 +546,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn dummy_put( &self, param_nested_response: models::DummyPutRequest, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/dummy", self.base_path @@ -558,36 +587,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("PUT") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_nested_response).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { @@ -597,29 +626,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn file_response_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/file_response", self.base_path @@ -637,37 +666,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(FileResponseGetResponse::Success @@ -676,29 +706,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn get_structured_yaml( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/get-structured-yaml", self.base_path @@ -716,35 +746,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = body.to_string(); @@ -754,30 +785,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn html_post( &self, param_body: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/html", self.base_path @@ -795,46 +826,47 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = param_body; - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "text/html"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = body.to_string(); @@ -844,30 +876,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn post_yaml( &self, param_value: String, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/post-yaml", self.base_path @@ -885,36 +917,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = param_value; - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/yaml"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -924,29 +956,29 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn raw_json_get( &self, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/raw_json", self.base_path @@ -964,37 +996,38 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("GET") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 200 => { let body = response.into_body(); - let body = body - .into_raw() - .map_err(|e| ApiError(format!("Failed to read response: {}", e))).await?; + let body = http_body_util::BodyExt::collect(body) + .await + .map(|f| f.to_bytes().to_vec()) + .map_err(|e| ApiError(format!("Failed to read response: {}", e.into())))?; let body = str::from_utf8(&body) - .map_err(|e| ApiError(format!("Response was not valid UTF8: {}", e)))?; + .map_err(|e| ApiError(format!("Response was not valid UTF8: {e}")))?; let body = serde_json::from_str::(body) - .map_err(|e| ApiError(format!("Response body did not match the schema: {}", e)))?; + .map_err(|e| ApiError(format!("Response body did not match the schema: {e}")))?; Ok(RawJsonGetResponse::Success @@ -1003,30 +1036,30 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } } } + #[allow(clippy::vec_init_then_push)] async fn solo_object_post( &self, param_value: serde_json::Value, context: &C) -> Result { let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] let mut uri = format!( "{}/solo-object", self.base_path @@ -1044,36 +1077,36 @@ impl Api for Client where let uri = match Uri::from_str(&uri) { Ok(uri) => uri, - Err(err) => return Err(ApiError(format!("Unable to build URI: {}", err))), + Err(err) => return Err(ApiError(format!("Unable to build URI: {err}"))), }; let mut request = match Request::builder() .method("POST") .uri(uri) - .body(Body::empty()) { + .body(BoxBody::new(http_body_util::Empty::new())) { Ok(req) => req, - Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) }; // Consumes basic body // Body parameter let body = serde_json::to_string(¶m_value).expect("impossible to fail to serialize"); - *request.body_mut() = Body::from(body); + *request.body_mut() = body_from_string(body); let header = "application/json"; request.headers_mut().insert(CONTENT_TYPE, match HeaderValue::from_str(header) { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create header: {} - {}", header, e))) + Err(e) => return Err(ApiError(format!("Unable to create header: {header} - {e}"))) }); let header = HeaderValue::from_str(Has::::get(context).0.as_str()); request.headers_mut().insert(HeaderName::from_static("x-span-id"), match header { Ok(h) => h, - Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {}", e))) + Err(e) => return Err(ApiError(format!("Unable to create X-Span ID header value: {e}"))) }); let response = client_service.call((request, context.clone())) - .map_err(|e| ApiError(format!("No response received: {}", e))).await?; + .map_err(|e| ApiError(format!("No response received: {e}"))).await?; match response.status().as_u16() { 204 => { @@ -1083,18 +1116,16 @@ impl Api for Client where } code => { let headers = response.headers().clone(); - let body = response.into_body() - .take(100) - .into_raw().await; - Err(ApiError(format!("Unexpected response code {}:\n{:?}\n\n{}", - code, - headers, + let body = http_body_util::BodyExt::collect(response.into_body()) + .await + .map(|f| f.to_bytes().to_vec()); + Err(ApiError(format!("Unexpected response code {code}:\n{headers:?}\n\n{}", match body { Ok(body) => match String::from_utf8(body) { Ok(body) => body, - Err(e) => format!("", e), + Err(e) => format!(""), }, - Err(e) => format!("", e), + Err(e) => format!("", Into::::into(e)), } ))) } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs index ee8e118587bb..45180a543112 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/context.rs @@ -6,9 +6,9 @@ use std::default::Default; use std::io; use std::marker::PhantomData; use std::task::{Poll, Context}; -use swagger::auth::{AuthData, Authorization, Bearer, Scopes}; +use swagger::auth::{AuthData, Authorization, Scopes}; use swagger::{EmptyContext, Has, Pop, Push, XSpanIdString}; -use crate::{Api, AuthenticationApi}; +use crate::Api; use log::error; pub struct MakeAddContext { @@ -16,11 +16,11 @@ pub struct MakeAddContext { marker: PhantomData, } -impl MakeAddContext +impl MakeAddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, + C: Send + 'static, { pub fn new(inner: T) -> MakeAddContext { MakeAddContext { @@ -30,27 +30,34 @@ where } } +impl Clone for MakeAddContext +where + T: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + marker: PhantomData, + } + } +} + // Make a service that adds context. -impl Service for +impl Service for MakeAddContext where Target: Send, A: Default + Push + Send, B: Push, Result = C>, - C: Push, Result = D>, - D: Send + 'static, + C: Send + 'static, T: Service + Send, T::Future: Send + 'static { type Error = T::Error; - type Response = AddContext; + type Response = AddContext; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = self.inner.call(target); Box::pin(async move { @@ -60,21 +67,17 @@ where } /// Middleware to add context data from the request -pub struct AddContext -where - A: Default + Push, - B: Push, Result = C>, - C: Push, Result = D> +#[derive(Debug, Clone)] +pub struct AddContext { inner: T, marker: PhantomData, } -impl AddContext +impl AddContext where A: Default + Push, B: Push, Result = C>, - C: Push, Result = D>, { pub fn new(inner: T) -> Self { AddContext { @@ -84,30 +87,23 @@ where } } -impl Service> for AddContext +impl Service> for AddContext where A: Default + Push, B: Push, Result=C>, - C: Push, Result=D>, - D: Send + 'static, - T: Service<(Request, D)> + AuthenticationApi + C: Send + 'static, + T: Service<(Request, C)> { type Error = T::Error; type Future = T::Future; type Response = T::Response; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - self.inner.poll_ready(cx) - } - - - fn call(&mut self, request: Request) -> Self::Future { + fn call(&self, request: Request) -> Self::Future { let context = A::default().push(XSpanIdString::get_or_generate(&request)); let headers = request.headers(); let context = context.push(None::); - let context = context.push(None::); self.inner.call((request, context)) } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/header.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/header.rs index 5bc6ebe929b9..823d2779b31f 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/header.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/header.rs @@ -31,11 +31,9 @@ macro_rules! ihv_generate { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse::<$t>() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse {} as a string: {}", - stringify!($t), e)), + Err(e) => Err(format!("Unable to parse {} as a string: {e}", stringify!($t))), }, - Err(e) => Err(format!("Unable to parse header {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header {hdr_value:?} as a string - {e}")), } } } @@ -76,8 +74,7 @@ impl TryFrom for IntoHeaderValue> { y => Some(y.to_string()), }) .collect())), - Err(e) => Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse header: {hdr_value:?} as a string - {e}")), } } } @@ -88,8 +85,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(&hdr_value.0.join(", ")) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} into a header - {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} into a header - {e}")) } } } @@ -102,8 +98,7 @@ impl TryFrom for IntoHeaderValue { fn try_from(hdr_value: HeaderValue) -> Result { match hdr_value.to_str() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value.to_string())), - Err(e) => Err(format!("Unable to convert header {:?} to {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to {e}")), } } } @@ -114,8 +109,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")) } } } @@ -128,11 +122,9 @@ impl TryFrom for IntoHeaderValue { match hdr_value.to_str() { Ok(hdr_value) => match hdr_value.parse() { Ok(hdr_value) => Ok(IntoHeaderValue(hdr_value)), - Err(e) => Err(format!("Unable to parse bool from {} - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse bool from {hdr_value} - {e}")), }, - Err(e) => Err(format!("Unable to convert {:?} from a header {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} from a header {e}")), } } } @@ -143,8 +135,7 @@ impl TryFrom> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue) -> Result { match HeaderValue::from_str(&hdr_value.0.to_string()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert: {:?} into a header: {}", - hdr_value, e)) + Err(e) => Err(format!("Unable to convert: {hdr_value:?} into a header: {e}")) } } } @@ -158,11 +149,9 @@ impl TryFrom for IntoHeaderValue> { match hdr_value.to_str() { Ok(hdr_value) => match DateTime::parse_from_rfc3339(hdr_value) { Ok(date) => Ok(IntoHeaderValue(date.with_timezone(&Utc))), - Err(e) => Err(format!("Unable to parse: {} as date - {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to parse: {hdr_value} as date - {e}")), }, - Err(e) => Err(format!("Unable to convert header {:?} to string {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert header {hdr_value:?} to string {e}")), } } } @@ -173,8 +162,7 @@ impl TryFrom>> for HeaderValue { fn try_from(hdr_value: IntoHeaderValue>) -> Result { match HeaderValue::from_str(hdr_value.0.to_rfc3339().as_str()) { Ok(hdr_value) => Ok(hdr_value), - Err(e) => Err(format!("Unable to convert {:?} to a header: {}", - hdr_value, e)), + Err(e) => Err(format!("Unable to convert {hdr_value:?} to a header: {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs index 3adabd148d80..9183faf7d34f 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/lib.rs @@ -83,10 +83,6 @@ pub enum SoloObjectPostResponse { #[async_trait] #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait Api { - fn poll_ready(&self, _cx: &mut Context) -> Poll>> { - Poll::Ready(Ok(())) - } - async fn all_of_get( &self, context: &C) -> Result; @@ -139,8 +135,6 @@ pub trait Api { #[allow(clippy::too_many_arguments, clippy::ptr_arg)] pub trait ApiNoContext { - fn poll_ready(&self, _cx: &mut Context) -> Poll>>; - fn context(&self) -> &C; async fn all_of_get( @@ -205,10 +199,6 @@ impl + Send + Sync, C: Clone + Send + Sync> ContextWrapperExt for T #[async_trait] impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for ContextWrapper { - fn poll_ready(&self, cx: &mut Context) -> Poll> { - self.api().poll_ready(cx) - } - fn context(&self) -> &C { ContextWrapper::context(self) } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs index 0e86f9a1267d..089147490dc9 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/models.rs @@ -32,10 +32,10 @@ impl ANullableContainer { } /// Converts the ANullableContainer value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ANullableContainer { - fn to_string(&self) -> String { +impl std::fmt::Display for ANullableContainer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.nullable_thing.as_ref().map(|nullable_thing| { [ @@ -47,12 +47,12 @@ impl std::string::ToString for ANullableContainer { Some(self.required_nullable_thing.as_ref().map_or("null".to_string(), |x| x.to_string())), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ANullableContainer value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ANullableContainer { type Err = String; @@ -110,8 +110,7 @@ impl std::convert::TryFrom> for hype match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ANullableContainer - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ANullableContainer - value: {hdr_value} is invalid {e}")) } } } @@ -126,13 +125,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ANullableContainer - {}", - value, err)) + format!("Unable to convert header value '{value}' into ANullableContainer - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -148,8 +145,7 @@ impl std::convert::TryFrom>> for match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -169,16 +165,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ANullableContainer - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ANullableContainer - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -214,17 +208,17 @@ impl std::ops::DerefMut for AdditionalPropertiesObject { } /// Converts the AdditionalPropertiesObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl ::std::string::ToString for AdditionalPropertiesObject { - fn to_string(&self) -> String { - // ToString for this model is not supported - "".to_string() +impl std::fmt::Display for AdditionalPropertiesObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Display for this model is not supported + write!(f, "") } } /// Converts Query Parameters representation (style=form, explode=false) to a AdditionalPropertiesObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl ::std::str::FromStr for AdditionalPropertiesObject { type Err = &'static str; @@ -245,8 +239,7 @@ impl std::convert::TryFrom> match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AdditionalPropertiesObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AdditionalPropertiesObject - value: {hdr_value} is invalid {e}")) } } } @@ -261,13 +254,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AdditionalPropertiesObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -283,8 +274,7 @@ impl std::convert::TryFrom std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -304,16 +294,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AdditionalPropertiesObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AdditionalPropertiesObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -343,10 +331,10 @@ impl AllOfObject { } /// Converts the AllOfObject value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for AllOfObject { - fn to_string(&self) -> String { +impl std::fmt::Display for AllOfObject { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.sample_property.as_ref().map(|sample_property| { [ @@ -362,12 +350,12 @@ impl std::string::ToString for AllOfObject { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a AllOfObject value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for AllOfObject { type Err = String; @@ -427,8 +415,7 @@ impl std::convert::TryFrom> for hyper::head match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for AllOfObject - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for AllOfObject - value: {hdr_value} is invalid {e}")) } } } @@ -443,13 +430,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AllOfObject - {}", - value, err)) + format!("Unable to convert header value '{value}' into AllOfObject - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -465,8 +450,7 @@ impl std::convert::TryFrom>> for hyper: match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -486,16 +470,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into AllOfObject - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into AllOfObject - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -520,10 +502,10 @@ impl BaseAllOf { } /// Converts the BaseAllOf value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for BaseAllOf { - fn to_string(&self) -> String { +impl std::fmt::Display for BaseAllOf { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.sample_base_property.as_ref().map(|sample_base_property| { [ @@ -533,12 +515,12 @@ impl std::string::ToString for BaseAllOf { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a BaseAllOf value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for BaseAllOf { type Err = String; @@ -594,8 +576,7 @@ impl std::convert::TryFrom> for hyper::header match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for BaseAllOf - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for BaseAllOf - value: {hdr_value} is invalid {e}")) } } } @@ -610,13 +591,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into BaseAllOf - {}", - value, err)) + format!("Unable to convert header value '{value}' into BaseAllOf - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -632,8 +611,7 @@ impl std::convert::TryFrom>> for hyper::h match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -653,16 +631,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into BaseAllOf - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into BaseAllOf - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -691,10 +667,10 @@ impl DummyPutRequest { } /// Converts the DummyPutRequest value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for DummyPutRequest { - fn to_string(&self) -> String { +impl std::fmt::Display for DummyPutRequest { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("id".to_string()), Some(self.id.to_string()), @@ -706,12 +682,12 @@ impl std::string::ToString for DummyPutRequest { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a DummyPutRequest value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for DummyPutRequest { type Err = String; @@ -771,8 +747,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for DummyPutRequest - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for DummyPutRequest - value: {hdr_value} is invalid {e}")) } } } @@ -787,13 +762,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DummyPutRequest - {}", - value, err)) + format!("Unable to convert header value '{value}' into DummyPutRequest - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -809,8 +782,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -830,16 +802,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into DummyPutRequest - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into DummyPutRequest - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -866,10 +836,10 @@ impl GetYamlResponse { } /// Converts the GetYamlResponse value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for GetYamlResponse { - fn to_string(&self) -> String { +impl std::fmt::Display for GetYamlResponse { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ self.value.as_ref().map(|value| { [ @@ -879,12 +849,12 @@ impl std::string::ToString for GetYamlResponse { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a GetYamlResponse value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for GetYamlResponse { type Err = String; @@ -940,8 +910,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for GetYamlResponse - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for GetYamlResponse - value: {hdr_value} is invalid {e}")) } } } @@ -956,13 +925,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into GetYamlResponse - {}", - value, err)) + format!("Unable to convert header value '{value}' into GetYamlResponse - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -978,8 +945,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -999,16 +965,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into GetYamlResponse - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into GetYamlResponse - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1034,20 +998,20 @@ impl ObjectOfObjects { } /// Converts the ObjectOfObjects value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectOfObjects { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectOfObjects { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ // Skipping non-primitive type inner in query parameter serialization ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectOfObjects value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectOfObjects { type Err = String; @@ -1103,8 +1067,7 @@ impl std::convert::TryFrom> for hyper:: match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectOfObjects - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectOfObjects - value: {hdr_value} is invalid {e}")) } } } @@ -1119,13 +1082,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectOfObjects - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectOfObjects - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1141,8 +1102,7 @@ impl std::convert::TryFrom>> for hy match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1162,16 +1122,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectOfObjects - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectOfObjects - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } @@ -1200,10 +1158,10 @@ impl ObjectOfObjectsInner { } /// Converts the ObjectOfObjectsInner value to the Query Parameters representation (style=form, explode=false) -/// specified in https://swagger.io/docs/specification/serialization/ +/// specified in /// Should be implemented in a serde serializer -impl std::string::ToString for ObjectOfObjectsInner { - fn to_string(&self) -> String { +impl std::fmt::Display for ObjectOfObjectsInner { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let params: Vec> = vec![ Some("required_thing".to_string()), Some(self.required_thing.to_string()), @@ -1215,12 +1173,12 @@ impl std::string::ToString for ObjectOfObjectsInner { }), ]; - params.into_iter().flatten().collect::>().join(",") + write!(f, "{}", params.into_iter().flatten().collect::>().join(",")) } } /// Converts Query Parameters representation (style=form, explode=false) to a ObjectOfObjectsInner value -/// as specified in https://swagger.io/docs/specification/serialization/ +/// as specified in /// Should be implemented in a serde deserializer impl std::str::FromStr for ObjectOfObjectsInner { type Err = String; @@ -1280,8 +1238,7 @@ impl std::convert::TryFrom> for hy match hyper::header::HeaderValue::from_str(&hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(e) => std::result::Result::Err( - format!("Invalid header value for ObjectOfObjectsInner - value: {} is invalid {}", - hdr_value, e)) + format!("Invalid header value for ObjectOfObjectsInner - value: {hdr_value} is invalid {e}")) } } } @@ -1296,13 +1253,11 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(value) { std::result::Result::Ok(value) => std::result::Result::Ok(header::IntoHeaderValue(value)), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectOfObjectsInner - {}", - value, err)) + format!("Unable to convert header value '{value}' into ObjectOfObjectsInner - {err}")) } }, std::result::Result::Err(e) => std::result::Result::Err( - format!("Unable to convert header: {:?} to string: {}", - hdr_value, e)) + format!("Unable to convert header: {hdr_value:?} to string: {e}")) } } } @@ -1318,8 +1273,7 @@ impl std::convert::TryFrom>> f match hyper::header::HeaderValue::from_str(&hdr_values.join(", ")) { std::result::Result::Ok(hdr_value) => std::result::Result::Ok(hdr_value), - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {:?} into a header - {}", - hdr_values, e)) + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to convert {hdr_values:?} into a header - {e}",)) } } } @@ -1339,16 +1293,14 @@ impl std::convert::TryFrom for header::IntoHeaderVal match ::from_str(hdr_value) { std::result::Result::Ok(value) => std::result::Result::Ok(value), std::result::Result::Err(err) => std::result::Result::Err( - format!("Unable to convert header value '{}' into ObjectOfObjectsInner - {}", - hdr_value, err)) + format!("Unable to convert header value '{hdr_value}' into ObjectOfObjectsInner - {err}")) } }) }).collect::, String>>()?; std::result::Result::Ok(header::IntoHeaderValue(hdr_values)) }, - std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {:?} as a string - {}", - hdr_values, e)), + std::result::Result::Err(e) => std::result::Result::Err(format!("Unable to parse header: {hdr_values:?} as a string - {e}")), } } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs index d2e153e4ac52..c68c0a73f3fc 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/server/mod.rs @@ -1,10 +1,12 @@ +use bytes::Bytes; use futures::{future, future::BoxFuture, Stream, stream, future::FutureExt, stream::TryStreamExt}; -use hyper::{Request, Response, StatusCode, Body, HeaderMap}; +use http_body_util::{combinators::BoxBody, Full}; +use hyper::{body::{Body, Incoming}, HeaderMap, Request, Response, StatusCode}; use hyper::header::{HeaderName, HeaderValue, CONTENT_TYPE}; use log::warn; #[allow(unused_imports)] use std::convert::{TryFrom, TryInto}; -use std::error::Error; +use std::{convert::Infallible, error::Error}; use std::future::Future; use std::marker::PhantomData; use std::task::{Context, Poll}; @@ -18,7 +20,7 @@ use crate::{models, header, AuthenticationApi}; pub use crate::context; -type ServiceFuture = BoxFuture<'static, Result, crate::ServiceError>>; +type ServiceFuture = BoxFuture<'static, Result>, crate::ServiceError>>; use crate::{Api, AllOfGetResponse, @@ -61,7 +63,8 @@ mod paths { } -pub struct MakeService where +pub struct MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -69,7 +72,8 @@ pub struct MakeService where marker: PhantomData, } -impl MakeService where +impl MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -81,7 +85,21 @@ impl MakeService where } } -impl hyper::service::Service for MakeService where +impl Clone for MakeService +where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static +{ + fn clone(&self) -> Self { + Self { + api_impl: self.api_impl.clone(), + marker: PhantomData, + } + } +} + +impl hyper::service::Service for MakeService +where T: Api + Clone + Send + 'static, C: Has + Send + Sync + 'static { @@ -89,21 +107,17 @@ impl hyper::service::Service for MakeService where type Error = crate::ServiceError; type Future = future::Ready>; - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn call(&mut self, target: Target) -> Self::Future { + fn call(&self, target: Target) -> Self::Future { let service = Service::new(self.api_impl.clone()); future::ok(service) } } -fn method_not_allowed() -> Result, crate::ServiceError> { +fn method_not_allowed() -> Result>, crate::ServiceError> { Ok( Response::builder().status(StatusCode::METHOD_NOT_ALLOWED) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Method Not Allowed response") ) } @@ -140,25 +154,37 @@ impl Clone for Service where } } -impl hyper::service::Service<(Request, C)> for Service where +#[allow(dead_code)] +fn body_from_string(s: String) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(s))) +} + +fn body_from_str(s: &str) -> BoxBody { + BoxBody::new(Full::new(Bytes::copy_from_slice(s.as_bytes()))) +} + +impl hyper::service::Service<(Request, C)> for Service where T: Api + Clone + Send + Sync + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { - type Response = Response; + type Response = Response>; type Error = crate::ServiceError; type Future = ServiceFuture; - fn poll_ready(&mut self, cx: &mut Context) -> Poll> { - self.api_impl.poll_ready(cx) - } - - fn call(&mut self, req: (Request, C)) -> Self::Future { - async fn run( + fn call(&self, req: (Request, C)) -> Self::Future { + async fn run( mut api_impl: T, - req: (Request, C), - ) -> Result, crate::ServiceError> where + req: (Request, C), + ) -> Result>, crate::ServiceError> + where T: Api + Clone + Send + 'static, - C: Has + Send + Sync + 'static + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, { let (request, context) = req; let (parts, body) = request.into_parts(); @@ -172,7 +198,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.all_of_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -190,7 +216,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -198,7 +224,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -210,7 +236,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.dummy_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -228,7 +254,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -240,22 +266,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_nested_response: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_nested_response) => param_nested_response, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter nested_response - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter nested_response - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter nested_response due to schema")), } + } else { None }; @@ -263,7 +290,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_nested_response) => param_nested_response, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter nested_response")) + .body(BoxBody::new("Missing required body parameter nested_response".to_string())) .expect("Unable to create Bad Request response for missing body parameter nested_response")), }; @@ -272,7 +299,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_nested_response, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -281,7 +308,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -296,7 +323,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -304,7 +331,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -314,7 +341,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.file_response_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -332,7 +359,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for application/json")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -340,7 +367,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -352,7 +379,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.get_structured_yaml( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -369,8 +396,7 @@ impl hyper::service::Service<(Request, C)> for Service where HeaderValue::from_str("application/yaml") .expect("Unable to create Content-Type header for application/yaml")); // Plain text Body - let body = body; - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -378,7 +404,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -390,7 +416,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let param_body: Option = if !body.is_empty() { @@ -398,7 +424,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_body) => Some(param_body), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter body - not valid UTF-8: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter body - not valid UTF-8: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter body due to UTF-8")), } } else { @@ -408,7 +434,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_body) => param_body, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter body")) + .body(BoxBody::new("Missing required body parameter body".to_string())) .expect("Unable to create Bad Request response for missing body parameter body")), }; @@ -417,7 +443,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_body, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -434,8 +460,7 @@ impl hyper::service::Service<(Request, C)> for Service where HeaderValue::from_str("text/html") .expect("Unable to create Content-Type header for text/html")); // Plain text Body - let body = body; - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -443,7 +468,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -451,7 +476,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -461,7 +486,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let param_value: Option = if !body.is_empty() { @@ -469,7 +494,7 @@ impl hyper::service::Service<(Request, C)> for Service where Ok(param_value) => Some(param_value), Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter value - not valid UTF-8: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter value - not valid UTF-8: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter value due to UTF-8")), } } else { @@ -479,7 +504,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_value) => param_value, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter value")) + .body(BoxBody::new("Missing required body parameter value".to_string())) .expect("Unable to create Bad Request response for missing body parameter value")), }; @@ -488,7 +513,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_value, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -506,7 +531,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -514,7 +539,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -524,7 +549,7 @@ impl hyper::service::Service<(Request, C)> for Service where let result = api_impl.raw_json_get( &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -542,7 +567,7 @@ impl hyper::service::Service<(Request, C)> for Service where .expect("Unable to create Content-Type header for */*")); // JSON Body let body = serde_json::to_string(&body).expect("impossible to fail to serialize"); - *response.body_mut() = Body::from(body); + *response.body_mut() = body_from_string(body); }, }, @@ -550,7 +575,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -562,22 +587,23 @@ impl hyper::service::Service<(Request, C)> for Service where // Handle body parameters (note that non-required body parameters will ignore garbage // values, rather than causing a 400 response). Produce warning header and logs for // any unused fields. - let result = body.into_raw().await; + let result = http_body_util::BodyExt::collect(body).await.map(|f| f.to_bytes().to_vec()); match result { Ok(body) => { let mut unused_elements : Vec = vec![]; let param_value: Option = if !body.is_empty() { - let deserializer = &mut serde_json::Deserializer::from_slice(&*body); + let deserializer = &mut serde_json::Deserializer::from_slice(&body); match serde_ignored::deserialize(deserializer, |path| { - warn!("Ignoring unknown field in body: {}", path); + warn!("Ignoring unknown field in body: {path}"); unused_elements.push(path.to_string()); }) { Ok(param_value) => param_value, Err(e) => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Couldn't parse body parameter value - doesn't match schema: {}", e))) + .body(BoxBody::new(format!("Couldn't parse body parameter value - doesn't match schema: {e}"))) .expect("Unable to create Bad Request response for invalid body parameter value due to schema")), } + } else { None }; @@ -585,7 +611,7 @@ impl hyper::service::Service<(Request, C)> for Service where Some(param_value) => param_value, None => return Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from("Missing required body parameter value")) + .body(BoxBody::new("Missing required body parameter value".to_string())) .expect("Unable to create Bad Request response for missing body parameter value")), }; @@ -594,7 +620,7 @@ impl hyper::service::Service<(Request, C)> for Service where param_value, &context ).await; - let mut response = Response::new(Body::empty()); + let mut response = Response::new(BoxBody::new(http_body_util::Empty::new())); response.headers_mut().insert( HeaderName::from_static("x-span-id"), HeaderValue::from_str((&context as &dyn Has).get().0.clone().as_str()) @@ -603,7 +629,7 @@ impl hyper::service::Service<(Request, C)> for Service where if !unused_elements.is_empty() { response.headers_mut().insert( HeaderName::from_static("warning"), - HeaderValue::from_str(format!("Ignoring unknown fields in body: {:?}", unused_elements).as_str()) + HeaderValue::from_str(format!("Ignoring unknown fields in body: {unused_elements:?}").as_str()) .expect("Unable to create Warning header value")); } match result { @@ -618,7 +644,7 @@ impl hyper::service::Service<(Request, C)> for Service where // Application code returned an error. This should not happen, as the implementation should // return a valid response. *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - *response.body_mut() = Body::from("An internal error occurred"); + *response.body_mut() = body_from_str("An internal error occurred"); }, } @@ -626,7 +652,7 @@ impl hyper::service::Service<(Request, C)> for Service where }, Err(e) => Ok(Response::builder() .status(StatusCode::BAD_REQUEST) - .body(Body::from(format!("Unable to read body: {}", e))) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) .expect("Unable to create Bad Request response due to unable to read body")), } }, @@ -640,7 +666,7 @@ impl hyper::service::Service<(Request, C)> for Service where _ if path.matched(paths::ID_RAW_JSON) => method_not_allowed(), _ if path.matched(paths::ID_SOLO_OBJECT) => method_not_allowed(), _ => Ok(Response::builder().status(StatusCode::NOT_FOUND) - .body(Body::empty()) + .body(BoxBody::new(http_body_util::Empty::new())) .expect("Unable to create Not Found response")) } } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/src/server/server_auth.rs b/samples/server/petstore/rust-server/output/rust-server-test/src/server/server_auth.rs index ba78eb2f3f5d..21b1d7babd03 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/src/server/server_auth.rs +++ b/samples/server/petstore/rust-server/output/rust-server-test/src/server/server_auth.rs @@ -1,11 +1,12 @@ use super::Service; use crate::{Api, AuthenticationApi}; +use headers::authorization::{Basic, Bearer}; use swagger::{ ApiError, - Authorization, - auth::{Basic, Bearer}, - Has, - XSpanIdString}; + Authorization, + Has, + XSpanIdString +}; impl AuthenticationApi for Service where T: Api + Clone + Send + 'static + AuthenticationApi, diff --git a/website/i18n/en.json b/website/i18n/en.json index 1599045b79f9..e6eaca7b372e 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -450,6 +450,10 @@ "title": "Config Options for rust-server", "sidebar_label": "rust-server" }, + "generators/rust-server-deprecated": { + "title": "Config Options for rust-server-deprecated", + "sidebar_label": "rust-server-deprecated" + }, "generators/rust": { "title": "Config Options for rust", "sidebar_label": "rust"