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 cc9569c92b78..47723dc4d95c 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 @@ -391,6 +391,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 55806f12df72..5a1c0d162fff 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 @@ -83,23 +83,27 @@ {{^isByteArray}} {{^isBinary}} let body = param_{{{paramName}}}; + *request.body_mut() = body_from_string(body); {{/isBinary}} {{/isByteArray}} {{#isByteArray}} - let body = String::from_utf8(param_{{{paramName}}}.0).expect("Body was not valid UTF8"); + // Raw binary body - pass the bytes through without coercing to UTF-8. + *request.body_mut() = body_from_bytes(param_{{{paramName}}}.0); {{/isByteArray}} {{#isBinary}} - let body = String::from_utf8(param_{{{paramName}}}.0).expect("Body was not valid UTF8"); + // Raw binary body - pass the bytes through without coercing to UTF-8. + *request.body_mut() = body_from_bytes(param_{{{paramName}}}.0); {{/isBinary}} {{/x-consumes-plain-text}} {{#x-consumes-xml}} let body = param_{{{paramName}}}.as_xml(); + *request.body_mut() = body_from_string(body); {{/x-consumes-xml}} {{#x-consumes-json}} let body = serde_json::to_string(¶m_{{{paramName}}}).expect("impossible to fail to serialize"); + *request.body_mut() = body_from_string(body); {{/x-consumes-json}} {{/exts}} - *request.body_mut() = body_from_string(body); {{^required}} } {{/required}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustServerCodegenTest.java index e6d664e26762..ab515ec7eebb 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/rust/RustServerCodegenTest.java @@ -112,4 +112,33 @@ public void testRequiredQueryParamWithoutExampleDisablesClientExample() throws I // Clean up target.toFile().deleteOnExit(); } + + /** + * Test that binary/byte request bodies are passed through as raw bytes rather than being + * coerced to UTF-8, which panics on any non-UTF-8 payload (see issue #24094). + */ + @Test + public void testBinaryRequestBodyNotCoercedToUtf8() throws IOException { + Path target = Files.createTempDirectory("test"); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("rust-server") + .setInputSpec("src/test/resources/3_0/rust-server/openapi-v3.yaml") + .setSkipOverwrite(false) + .setOutputDir(target.toAbsolutePath().toString().replace("\\", "/")); + List files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + Path clientModPath = Path.of(target.toString(), "/src/client/mod.rs"); + TestUtils.assertFileExists(clientModPath); + + // format: binary request body should pass raw bytes through. + TestUtils.assertFileContains(clientModPath, "*request.body_mut() = body_from_bytes(param_body.0);"); + // The bytes helper must be generated. + TestUtils.assertFileContains(clientModPath, "fn body_from_bytes(b: Vec) -> BoxBody {"); + // The request body must no longer be coerced to UTF-8 (would panic on non-UTF-8 payloads). + TestUtils.assertFileNotContains(clientModPath, "let body = String::from_utf8(param_body.0).expect(\"Body was not valid UTF8\");"); + + // Clean up + target.toFile().deleteOnExit(); + } } 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 69ae83c5bd64..31ddec7303bf 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 @@ -210,6 +210,18 @@ paths: responses: '200': description: 'OK' + /required_binary_stream: + put: + requestBody: + required: true + content: + application/octet-stream: + schema: + type: string + format: binary + responses: + '200': + description: 'OK' /readonly_auth_scheme: get: security: 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..9a09a5849b95 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/README.md @@ -0,0 +1,272 @@ +# 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.24.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 openapi-v3- +``` + +To pass in arguments to the examples, put them after `--`, for example: + +``` +cargo run --example openapi-v3-client -- --help +``` + +### Running the example server +To run the server, follow these simple steps: + +``` +cargo run --example openapi-v3-server +``` + +### Running the example client +To run a client, follow one of the following simple steps: + +``` +cargo run --example openapi-v3-client AnyOfGet +cargo run --example openapi-v3-client CallbackWithHeaderPost +cargo run --example openapi-v3-client ComplexQueryParamGet +cargo run --example openapi-v3-client ExamplesTest +cargo run --example openapi-v3-client FormTest +cargo run --example openapi-v3-client GetWithBooleanParameter +cargo run --example openapi-v3-client JsonComplexQueryParamGet +cargo run --example openapi-v3-client MandatoryRequestHeaderGet +cargo run --example openapi-v3-client MergePatchJsonGet +cargo run --example openapi-v3-client MultigetGet +cargo run --example openapi-v3-client MultipleAuthSchemeGet +cargo run --example openapi-v3-client OneOfGet +cargo run --example openapi-v3-client OverrideServerGet +cargo run --example openapi-v3-client ParamgetGet +cargo run --example openapi-v3-client QueryExampleGet +cargo run --example openapi-v3-client ReadonlyAuthSchemeGet +cargo run --example openapi-v3-client RegisterCallbackPost +cargo run --example openapi-v3-client RequiredBinaryStreamPut +cargo run --example openapi-v3-client RequiredOctetStreamPut +cargo run --example openapi-v3-client ResponsesWithHeadersGet +cargo run --example openapi-v3-client Rfc7807Get +cargo run --example openapi-v3-client TwoFirstLetterHeaders +cargo run --example openapi-v3-client UntypedPropertyGet +cargo run --example openapi-v3-client UuidGet +cargo run --example openapi-v3-client XmlExtraPost +cargo run --example openapi-v3-client XmlOtherPost +cargo run --example openapi-v3-client XmlOtherPut +cargo run --example openapi-v3-client XmlPost +cargo run --example openapi-v3-client XmlPut +cargo run --example openapi-v3-client EnumInPathPathParamGet +cargo run --example openapi-v3-client MultiplePathParamsWithVeryLongPathToTestFormattingPathParamAPathParamBGet +cargo run --example openapi-v3-client CreateRepo +cargo run --example openapi-v3-client GetRepoInfo +``` + +### HTTPS +The examples can be run in HTTPS mode by passing in the flag `--https`, for example: + +``` +cargo run --example openapi-v3-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. +[**queryExampleGet**](docs/default_api.md#queryExampleGet) | **GET** /query-example | Test required query params with and without examples +[****](docs/default_api.md#) | **GET** /readonly_auth_scheme | +[****](docs/default_api.md#) | **POST** /register-callback | +[****](docs/default_api.md#) | **PUT** /required_binary_stream | +[****](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) + - [FormTestRequestEnumField](docs/FormTestRequestEnumField.md) + - [Model12345AnyOfObject](docs/Model12345AnyOfObject.md) + - [Model12345AnyOfObjectAnyOf](docs/Model12345AnyOfObjectAnyOf.md) + - [MultigetGet201Response](docs/MultigetGet201Response.md) + - [MyId](docs/MyId.md) + - [MyIdList](docs/MyIdList.md) + - [NoTypeObject](docs/NoTypeObject.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..e05db02b4ad4 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/api/openapi.yaml @@ -0,0 +1,936 @@ +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. + /query-example: + get: + operationId: queryExampleGet + parameters: + - explode: true + in: query + name: required_no_example + required: true + schema: + type: string + style: form + - example: 42 + explode: true + in: query + name: required_with_example + required: true + schema: + format: int32 + type: integer + style: form + responses: + "200": + description: OK + summary: Test required query params with and without examples + /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 + /required_binary_stream: + put: + requestBody: + content: + application/octet-stream: + schema: + format: binary + 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: + required_untyped: "" + required_untyped_nullable: "" + not_required_untyped: "" + not_required_untyped_nullable: "" + 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: 100 + properties: + requiredParam: + type: boolean + optionalParam: + example: 100 + maximum: 10000000000000000000 + minimum: 1 + 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 + NoTypeObject: + description: An object with no type + title: an object with no type + NullableTest: + properties: + nullable: + nullable: true + type: string + nullableWithNullDefault: + nullable: true + type: string + default: null + 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_enum_field: + enum: + - one_enum + type: string + FormTest_request: + properties: + requiredArray: + items: + type: string + type: array + enum_field: + $ref: "#/components/schemas/FormTest_request_enum_field" + required: + - enum_field + - requiredArray + 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..0fab15ac198b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/bin/cli.rs @@ -0,0 +1,950 @@ +//! 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, + QueryExampleGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, + 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: Vec, + #[structopt(parse(try_from_str = parse_json))] + enum_field: models::FormTestRequestEnumField, + }, + 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>, + }, + /// Test required query params with and without examples + QueryExampleGet { + required_no_example: String, + required_with_example: i32, + }, + ReadonlyAuthSchemeGet { + }, + RegisterCallbackPost { + url: String, + }, + RequiredBinaryStreamPut { + #[structopt(parse(try_from_str = parse_json))] + body: swagger::ByteArray, + }, + 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, + enum_field, + } => { + info!("Performing a FormTest request"); + + let result = client.form_test( + required_array.as_ref(), + enum_field, + ).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::QueryExampleGet { + required_no_example, + required_with_example, + } => { + info!("Performing a QueryExampleGet request"); + + let result = client.query_example_get( + required_no_example, + required_with_example, + ).await?; + debug!("Result: {:?}", result); + + match result { + QueryExampleGetResponse::OK + => "OK\n".to_string() + , + } + } + 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::RequiredBinaryStreamPut { + body, + } => { + info!("Performing a RequiredBinaryStreamPut request"); + + let result = client.required_binary_stream_put( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + RequiredBinaryStreamPutResponse::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-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..ae6efb8add9e --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/docs/default_api.md @@ -0,0 +1,885 @@ +# 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. +**queryExampleGet**](default_api.md#queryExampleGet) | **GET** /query-example | Test required query params with and without examples +****](default_api.md#) | **GET** /readonly_auth_scheme | +****](default_api.md#) | **POST** /register-callback | +****](default_api.md#) | **PUT** /required_binary_stream | +****](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(required_array, enum_field) +Test a Form Post + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **required_array** | [**String**](String.md)| | + **enum_field** | [**FormTest_request_enum_field**](FormTest_request_enum_field.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) + +# **queryExampleGet** +> queryExampleGet(required_no_example, required_with_example) +Test required query params with and without examples + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **required_no_example** | **String**| | + **required_with_example** | **i32**| | + +### 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) + +# **** +> (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) + +# **** +> (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/examples/client/main.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/main.rs new file mode 100644 index 000000000000..29e8b8945ff6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/client/main.rs @@ -0,0 +1,378 @@ +#![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, + QueryExampleGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, + 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", + "QueryExampleGet", + "ReadonlyAuthSchemeGet", + "RegisterCallbackPost", + "RequiredBinaryStreamPut", + "RequiredOctetStreamPut", + "ResponsesWithHeadersGet", + "Rfc7807Get", + "TwoFirstLetterHeaders", + "UntypedPropertyGet", + "UuidGet", + "XmlExtraPost", + "XmlOtherPost", + "XmlOtherPut", + "XmlPost", + "XmlPut", + "EnumInPathPathParamGet", + "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( + &Vec::new(), + models::FormTestRequestEnumField::OneEnum + )); + 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("QueryExampleGet") => { + let result = rt.block_on(client.query_example_get( + "required_no_example_example".to_string(), + 42 + )); + 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("RequiredBinaryStreamPut") => { + let result = rt.block_on(client.required_binary_stream_put( + swagger::ByteArray(Vec::from("BINARY_DATA_HERE")) + )); + 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()); + }, + Some("EnumInPathPathParamGet") => { + let result = rt.block_on(client.enum_in_path_path_param_get( + models::StringEnum::Foo + )); + 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/server/server.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server.rs new file mode 100644 index 000000000000..49dbe7086a0b --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/examples/server/server.rs @@ -0,0 +1,413 @@ +//! 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, + QueryExampleGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, + 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: &Vec, + enum_field: models::FormTestRequestEnumField, + context: &C) -> Result + { + info!("form_test({:?}, {:?}) - X-Span-ID: {:?}", required_array, enum_field, 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())) + } + /// Test required query params with and without examples + async fn query_example_get( + &self, + required_no_example: String, + required_with_example: i32, + context: &C) -> Result + { + info!("query_example_get(\"{}\", {}) - X-Span-ID: {:?}", required_no_example, required_with_example, 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_binary_stream_put( + &self, + body: swagger::ByteArray, + context: &C) -> Result + { + info!("required_binary_stream_put({:?}) - X-Span-ID: {:?}", body, 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/src/client/mod.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/mod.rs new file mode 100644 index 000000000000..2b4f6646b551 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/client/mod.rs @@ -0,0 +1,3198 @@ +#![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, + QueryExampleGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, + 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: &Vec, + param_enum_field: models::FormTestRequestEnumField, + 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![]; + // style=form,explode=true + for param_required_array in param_required_array { + #[allow(clippy::uninlined_format_args)] + params.push(("requiredArray", + format!("{:?}", param_required_array) + )); + } + #[allow(clippy::uninlined_format_args)] + params.push(("enum_field", + format!("{:?}", param_enum_field) + )); + + 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, HeaderValue::from_static(header)); + 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 query_example_get( + &self, + param_required_no_example: String, + param_required_with_example: i32, + context: &C) -> Result + { + let mut client_service = self.client_service.clone(); + #[allow(clippy::uninlined_format_args)] + let mut uri = format!( + "{}/query-example", + self.base_path + ); + + // Query parameters + let query_string = { + let mut query_string = form_urlencoded::Serializer::new("".to_owned()); + query_string.append_pair("required_no_example", + ¶m_required_no_example); + query_string.append_pair("required_with_example", + ¶m_required_with_example.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( + QueryExampleGetResponse::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 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_binary_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_binary_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; + *request.body_mut() = Body::from(body); + + let header = "application/octet-stream"; + request.headers_mut().insert(CONTENT_TYPE, HeaderValue::from_static(header)); + 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( + RequiredBinaryStreamPutResponse::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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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, HeaderValue::from_static(header)); + 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/lib.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/lib.rs new file mode 100644 index 000000000000..60d8bf529bd7 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/lib.rs @@ -0,0 +1,1092 @@ +#![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, auth::Authorization}; +use serde::{Serialize, Deserialize}; + +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 QueryExampleGetResponse { + /// OK + OK +} +#[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 RequiredBinaryStreamPutResponse { + /// 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: &Vec, + enum_field: models::FormTestRequestEnumField, + 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; + + /// Test required query params with and without examples + async fn query_example_get( + &self, + required_no_example: String, + required_with_example: i32, + 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_binary_stream_put( + &self, + body: swagger::ByteArray, + 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: &Vec, + enum_field: models::FormTestRequestEnumField, + ) -> 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; + + /// Test required query params with and without examples + async fn query_example_get( + &self, + required_no_example: String, + required_with_example: i32, + ) -> Result; + + async fn readonly_auth_scheme_get( + &self, + ) -> Result; + + async fn register_callback_post( + &self, + url: String, + ) -> Result; + + async fn required_binary_stream_put( + &self, + body: swagger::ByteArray, + ) -> 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: &Vec, + enum_field: models::FormTestRequestEnumField, + ) -> Result + { + let context = self.context().clone(); + self.api().form_test(required_array, enum_field, &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 + } + + /// Test required query params with and without examples + async fn query_example_get( + &self, + required_no_example: String, + required_with_example: i32, + ) -> Result + { + let context = self.context().clone(); + self.api().query_example_get(required_no_example, required_with_example, &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_binary_stream_put( + &self, + body: swagger::ByteArray, + ) -> Result + { + let context = self.context().clone(); + self.api().required_binary_stream_put(body, &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/server/mod.rs b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/mod.rs new file mode 100644 index 000000000000..a7954cb838b6 --- /dev/null +++ b/samples/server/petstore/rust-server-deprecated/output/openapi-v3/src/server/mod.rs @@ -0,0 +1,2361 @@ +#![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, + QueryExampleGetResponse, + ReadonlyAuthSchemeGetResponse, + RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, + 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"^/query-example$", + r"^/readonly_auth_scheme$", + r"^/register-callback$", + r"^/repos$", + r"^/repos/(?P[^/?#]*)$", + r"^/required_binary_stream$", + 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_QUERY_EXAMPLE: usize = 17; + pub(crate) static ID_READONLY_AUTH_SCHEME: usize = 18; + pub(crate) static ID_REGISTER_CALLBACK: usize = 19; + pub(crate) static ID_REPOS: usize = 20; + pub(crate) static ID_REPOS_REPOID: usize = 21; + 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_BINARY_STREAM: usize = 22; + pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 23; + pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 24; + pub(crate) static ID_RFC7807: usize = 25; + pub(crate) static ID_UNTYPED_PROPERTY: usize = 26; + pub(crate) static ID_UUID: usize = 27; + pub(crate) static ID_XML: usize = 28; + pub(crate) static ID_XML_EXTRA: usize = 29; + pub(crate) static ID_XML_OTHER: usize = 30; +} + +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_static("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_static("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_static("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_static("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 = + Vec::new(); + let param_enum_field = + models::FormTestRequestEnumField::OneEnum; + let result = api_impl.form_test( + param_required_array.as_ref(), + param_enum_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 { + 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_static("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_static("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_static("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_static("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_static("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_static("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_static("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_static("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_static("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_static("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) + }, + // QueryExampleGet - GET /query-example + hyper::Method::GET if path.matched(paths::ID_QUERY_EXAMPLE) => { + // 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_required_no_example = query_params.iter().filter(|e| e.0 == "required_no_example").map(|e| e.1.clone()) + .next(); + let param_required_no_example = match param_required_no_example { + Some(param_required_no_example) => { + let param_required_no_example = + ::from_str + (¶m_required_no_example); + match param_required_no_example { + Ok(param_required_no_example) => Some(param_required_no_example), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter required_no_example - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter required_no_example")), + } + }, + None => None, + }; + let param_required_no_example = match param_required_no_example { + Some(param_required_no_example) => param_required_no_example, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter required_no_example")) + .expect("Unable to create Bad Request response for missing query parameter required_no_example")), + }; + let param_required_with_example = query_params.iter().filter(|e| e.0 == "required_with_example").map(|e| e.1.clone()) + .next(); + let param_required_with_example = match param_required_with_example { + Some(param_required_with_example) => { + let param_required_with_example = + ::from_str + (¶m_required_with_example); + match param_required_with_example { + Ok(param_required_with_example) => Some(param_required_with_example), + Err(e) => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("Couldn't parse query parameter required_with_example - doesn't match schema: {e}"))) + .expect("Unable to create Bad Request response for invalid query parameter required_with_example")), + } + }, + None => None, + }; + let param_required_with_example = match param_required_with_example { + Some(param_required_with_example) => param_required_with_example, + None => return Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from("Missing required query parameter required_with_example")) + .expect("Unable to create Bad Request response for missing query parameter required_with_example")), + }; + + let result = api_impl.query_example_get( + param_required_no_example, + param_required_with_example, + &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 { + QueryExampleGetResponse::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) + }, + // 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) + }, + // RequiredBinaryStreamPut - PUT /required_binary_stream + hyper::Method::PUT if path.matched(paths::ID_REQUIRED_BINARY_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() { + } 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_binary_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 { + RequiredBinaryStreamPutResponse::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")), + } + }, + // 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_static("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_static("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_static("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_static("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_static("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_static("text/xml")); + // XML Body + // An empty string is used to indicate a global namespace in xmltree. + let config = serde_xml_rs::SerdeXml::new() + .namespace("", models::AnotherXmlObject::NAMESPACE); + let body = config.to_string(&body).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_static("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_QUERY_EXAMPLE) => 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_BINARY_STREAM) => 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"), + // QueryExampleGet - GET /query-example + hyper::Method::GET if path.matched(paths::ID_QUERY_EXAMPLE) => Some("QueryExampleGet"), + // 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"), + // RequiredBinaryStreamPut - PUT /required_binary_stream + hyper::Method::PUT if path.matched(paths::ID_REQUIRED_BINARY_STREAM) => Some("RequiredBinaryStreamPut"), + // 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/output/multipart-v3/src/client/mod.rs b/samples/server/petstore/rust-server/output/multipart-v3/src/client/mod.rs index 7d7dffb7ab88..65c4b38f8434 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 @@ -433,6 +433,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 de9fcd4e3f48..34d1724b31e7 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 @@ -426,6 +426,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 397acf19868f..565a125781ea 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/README.md +++ b/samples/server/petstore/rust-server/output/openapi-v3/README.md @@ -99,6 +99,7 @@ cargo run --example openapi-v3-client OneOfGet cargo run --example openapi-v3-client OverrideServerGet cargo run --example openapi-v3-client ParamgetGet cargo run --example openapi-v3-client ReadonlyAuthSchemeGet +cargo run --example openapi-v3-client RequiredBinaryStreamPut cargo run --example openapi-v3-client RequiredOctetStreamPut cargo run --example openapi-v3-client ResponsesWithHeadersGet cargo run --example openapi-v3-client Rfc7807Get @@ -190,6 +191,7 @@ Method | HTTP request | Description [**queryExampleGet**](docs/default_api.md#queryExampleGet) | **GET** /query-example | Test required query params with and without examples [****](docs/default_api.md#) | **GET** /readonly_auth_scheme | [****](docs/default_api.md#) | **POST** /register-callback | +[****](docs/default_api.md#) | **PUT** /required_binary_stream | [****](docs/default_api.md#) | **PUT** /required_octet_stream | [****](docs/default_api.md#) | **GET** /responses_with_headers | [****](docs/default_api.md#) | **GET** /rfc7807 | 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 9e1e521879f3..e05db02b4ad4 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 @@ -198,6 +198,18 @@ paths: responses: "200": description: OK + /required_binary_stream: + put: + requestBody: + content: + application/octet-stream: + schema: + format: binary + type: string + required: true + responses: + "200": + description: OK /readonly_auth_scheme: get: responses: 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 8e7ab7a96cb6..fab73ef75def 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 @@ -23,6 +23,7 @@ use openapi_v3::{ QueryExampleGetResponse, ReadonlyAuthSchemeGetResponse, RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, RequiredOctetStreamPutResponse, ResponsesWithHeadersGetResponse, Rfc7807GetResponse, @@ -162,6 +163,10 @@ enum Operation { RegisterCallbackPost { url: String, }, + RequiredBinaryStreamPut { + #[clap(value_parser = parse_json::)] + body: swagger::ByteArray, + }, RequiredOctetStreamPut { #[clap(value_parser = parse_json::)] body: swagger::ByteArray, @@ -608,6 +613,22 @@ async fn main() -> Result<()> { , } } + Operation::RequiredBinaryStreamPut { + body, + } => { + info!("Performing a RequiredBinaryStreamPut request"); + + let result = client.required_binary_stream_put( + body, + ).await?; + debug!("Result: {:?}", result); + + match result { + RequiredBinaryStreamPutResponse::OK + => "OK\n".to_string() + , + } + } Operation::RequiredOctetStreamPut { body, } => { 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 2e0108f7f2e5..4c5b2c173a68 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 @@ -21,6 +21,7 @@ Method | HTTP request | Description **queryExampleGet**](default_api.md#queryExampleGet) | **GET** /query-example | Test required query params with and without examples ****](default_api.md#) | **GET** /readonly_auth_scheme | ****](default_api.md#) | **POST** /register-callback | +****](default_api.md#) | **PUT** /required_binary_stream | ****](default_api.md#) | **PUT** /required_octet_stream | ****](default_api.md#) | **GET** /responses_with_headers | ****](default_api.md#) | **GET** /rfc7807 | @@ -490,6 +491,31 @@ No authorization required > (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) + +# **** +> (body) + + ### Required Parameters Name | Type | Description | Notes 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 0ee7292ba787..32655c7bb120 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 @@ -23,6 +23,7 @@ use openapi_v3::{Api, ApiNoContext, Claims, Client, ContextWrapperExt, models, QueryExampleGetResponse, ReadonlyAuthSchemeGetResponse, RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, RequiredOctetStreamPutResponse, ResponsesWithHeadersGetResponse, Rfc7807GetResponse, @@ -79,6 +80,7 @@ fn main() { "OverrideServerGet", "ParamgetGet", "ReadonlyAuthSchemeGet", + "RequiredBinaryStreamPut", "RequiredOctetStreamPut", "ResponsesWithHeadersGet", "Rfc7807Get", @@ -290,6 +292,12 @@ fn main() { info!("{:?} (X-Span-ID: {:?})", result, (client.context() as &dyn Has).get().clone()); }, */ + Some("RequiredBinaryStreamPut") => { + let result = rt.block_on(client.required_binary_stream_put( + swagger::ByteArray(Vec::from("BINARY_DATA_HERE")) + )); + 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")) 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 6e4b73c6adc3..70eeb81eb3a4 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 @@ -154,6 +154,7 @@ use openapi_v3::{ QueryExampleGetResponse, ReadonlyAuthSchemeGetResponse, RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, RequiredOctetStreamPutResponse, ResponsesWithHeadersGetResponse, Rfc7807GetResponse, @@ -333,6 +334,15 @@ impl Api for Server where C: Has + Send + Sync Err(ApiError("Api-Error: Operation is NOT implemented".into())) } + async fn required_binary_stream_put( + &self, + body: swagger::ByteArray, + context: &C) -> Result + { + info!("required_binary_stream_put({:?}) - X-Span-ID: {:?}", body, context.get().0.clone()); + Err(ApiError("Api-Error: Operation is NOT implemented".into())) + } + async fn required_octet_stream_put( &self, body: swagger::ByteArray, 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 c85c3207b1f3..770ee3fb05f2 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 @@ -56,6 +56,7 @@ use crate::{Api, QueryExampleGetResponse, ReadonlyAuthSchemeGetResponse, RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, RequiredOctetStreamPutResponse, ResponsesWithHeadersGetResponse, Rfc7807GetResponse, @@ -459,6 +460,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< @@ -1959,6 +1965,83 @@ impl Api for Client where } } + #[allow(clippy::vec_init_then_push)] + async fn required_binary_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_binary_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(BoxBody::new(http_body_util::Empty::new())) { + Ok(req) => req, + Err(e) => return Err(ApiError(format!("Unable to create request: {e}"))) + }; + + // Consumes basic body + // Body parameter + // Raw binary body - pass the bytes through without coercing to UTF-8. + *request.body_mut() = body_from_bytes(param_body.0); + + let header = "application/octet-stream"; + request.headers_mut().insert(CONTENT_TYPE, HeaderValue::from_static(header)); + + 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( + RequiredBinaryStreamPutResponse::OK + ) + } + 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!(""), + }, + Err(e) => format!("", Into::::into(e)), + } + ))) + } + } + } + #[allow(clippy::vec_init_then_push)] async fn required_octet_stream_put( &self, @@ -1997,8 +2080,8 @@ impl Api for Client where // Consumes basic body // Body parameter - let body = String::from_utf8(param_body.0).expect("Body was not valid UTF8"); - *request.body_mut() = body_from_string(body); + // Raw binary body - pass the bytes through without coercing to UTF-8. + *request.body_mut() = body_from_bytes(param_body.0); let header = "application/octet-stream"; request.headers_mut().insert(CONTENT_TYPE, HeaderValue::from_static(header)); 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 1e9f566f5616..4c8e7b9d8fa1 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 @@ -163,6 +163,12 @@ pub enum RegisterCallbackPostResponse { OK } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub enum RequiredBinaryStreamPutResponse { + /// OK + OK +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] pub enum RequiredOctetStreamPutResponse { /// OK @@ -409,6 +415,11 @@ pub trait Api { url: String, context: &C) -> Result; + async fn required_binary_stream_put( + &self, + body: swagger::ByteArray, + context: &C) -> Result; + async fn required_octet_stream_put( &self, body: swagger::ByteArray, @@ -586,6 +597,11 @@ pub trait ApiNoContext { url: String, ) -> Result; + async fn required_binary_stream_put( + &self, + body: swagger::ByteArray, + ) -> Result; + async fn required_octet_stream_put( &self, body: swagger::ByteArray, @@ -838,6 +854,15 @@ impl + Send + Sync, C: Clone + Send + Sync> ApiNoContext for Contex self.api().register_callback_post(url, &context).await } + async fn required_binary_stream_put( + &self, + body: swagger::ByteArray, + ) -> Result + { + let context = self.context().clone(); + self.api().required_binary_stream_put(body, &context).await + } + async fn required_octet_stream_put( &self, body: swagger::ByteArray, 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 eed0dc8578a1..31e7bdee6ce9 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 @@ -42,6 +42,7 @@ use crate::{Api, QueryExampleGetResponse, ReadonlyAuthSchemeGetResponse, RegisterCallbackPostResponse, + RequiredBinaryStreamPutResponse, RequiredOctetStreamPutResponse, ResponsesWithHeadersGetResponse, Rfc7807GetResponse, @@ -90,6 +91,7 @@ mod paths { r"^/register-callback$", r"^/repos$", r"^/repos/(?P[^/?#]*)$", + r"^/required_binary_stream$", r"^/required_octet_stream$", r"^/responses_with_headers$", r"^/rfc7807$", @@ -141,14 +143,15 @@ mod paths { regex::Regex::new(r"^/repos/(?P[^/?#]*)$") .expect("Unable to create regex for REPOS_REPOID"); } - pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 22; - pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 23; - pub(crate) static ID_RFC7807: usize = 24; - pub(crate) static ID_UNTYPED_PROPERTY: usize = 25; - pub(crate) static ID_UUID: usize = 26; - pub(crate) static ID_XML: usize = 27; - pub(crate) static ID_XML_EXTRA: usize = 28; - pub(crate) static ID_XML_OTHER: usize = 29; + pub(crate) static ID_REQUIRED_BINARY_STREAM: usize = 22; + pub(crate) static ID_REQUIRED_OCTET_STREAM: usize = 23; + pub(crate) static ID_RESPONSES_WITH_HEADERS: usize = 24; + pub(crate) static ID_RFC7807: usize = 25; + pub(crate) static ID_UNTYPED_PROPERTY: usize = 26; + pub(crate) static ID_UUID: usize = 27; + pub(crate) static ID_XML: usize = 28; + pub(crate) static ID_XML_EXTRA: usize = 29; + pub(crate) static ID_XML_OTHER: usize = 30; } @@ -411,6 +414,11 @@ impl hyper::service::Service<(Request, C)> for Service { + handle_required_binary_stream_put(api_impl, uri, headers, body, context, validation).await + }, + // RequiredOctetStreamPut - PUT /required_octet_stream hyper::Method::PUT if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => { handle_required_octet_stream_put(api_impl, uri, headers, body, context, validation).await @@ -508,6 +516,7 @@ impl hyper::service::Service<(Request, C)> for Service 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_BINARY_STREAM) => 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(), @@ -1772,6 +1781,77 @@ where Ok(response) } +#[allow(unused_variables)] +async fn handle_required_binary_stream_put( + mut api_impl: T, + uri: hyper::Uri, + headers: HeaderMap, + body: ReqBody, + context: C, + validation: bool, +) -> Result>, crate::ServiceError> +where + T: Api + Clone + Send + 'static, + C: Has + Send + Sync + 'static, + ReqBody: Body + Send + 'static, + ReqBody::Error: Into> + Send, + ReqBody::Data: Send, +{ + // 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 = 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() { + 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(BoxBody::new("Missing required body parameter body".to_string())) + .expect("Unable to create Bad Request response for missing body parameter body")), + }; + + + let result = api_impl.required_binary_stream_put( + param_body, + &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 { + RequiredBinaryStreamPutResponse::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_str("An internal error occurred"); + }, + } + + Ok(response) + }, + Err(e) => Ok(Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(body_from_string(format!("Unable to read body: {}", e.into()))) + .expect("Unable to create Bad Request response due to unable to read body")), + } +} + #[allow(unused_variables)] async fn handle_required_octet_stream_put( mut api_impl: T, @@ -3061,6 +3141,8 @@ impl RequestParser for ApiRequestParser { 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"), + // RequiredBinaryStreamPut - PUT /required_binary_stream + hyper::Method::PUT if path.matched(paths::ID_REQUIRED_BINARY_STREAM) => Some("RequiredBinaryStreamPut"), // RequiredOctetStreamPut - PUT /required_octet_stream hyper::Method::PUT if path.matched(paths::ID_REQUIRED_OCTET_STREAM) => Some("RequiredOctetStreamPut"), // ResponsesWithHeadersGet - GET /responses_with_headers 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 b9035f6e45b0..ae007b288424 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 @@ -462,6 +462,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 8aa1102e56ff..0a9fecefd823 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 @@ -463,6 +463,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 49ead2648b88..811e54285120 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 @@ -426,6 +426,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service< 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 98b1550118b0..1a6a5e36ffb8 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 @@ -434,6 +434,11 @@ fn body_from_string(s: String) -> BoxBody { BoxBody::new(Full::new(Bytes::from(s))) } +#[allow(dead_code)] +fn body_from_bytes(b: Vec) -> BoxBody { + BoxBody::new(Full::new(Bytes::from(b))) +} + #[async_trait] impl Api for Client where S: Service<