Skip to content

Commit

Permalink
[Rust-Axum] Fix uuid in header params causing compilation errors (#18563
Browse files Browse the repository at this point in the history
)

* fix: Fix uuid in header params causing errors

Routes with header parameters with a `format` of `uuid` in the openAPI
specification used to cause a compilation error in the resulting
Rust Axum code.
This commit fixes the issue by including the correct conversion trait
implementation on the condition that at least one header parameter of
`format` `uuid` is included in the specification.

* refactor: Add final to boolean

* fix: Bring str::FromStr optionally into scope

The trait needs to be in scope for the TryFrom implementation:
`TryFrom<HeaderValue> for IntoHeaderValue<uuid::Uuid> `
It will only be brought into scope when the implementation is rendered.

* test: Add integration test and its specification

This commit adds an integration test that tests the bug fix for #18554.
A header parameter of `format: uuid` is included in one route.
This makes the example create a route handler that tries to extract a
Rust `uuid::Uuid` type from the header. The integration test will check
that the generated code compiles.

* test: Update examples and run integration test

The generated samples are updated with:
`./bin/generate-samples.sh ./bin/configs/manual/*.yaml`
Most example projects have their version numbers bumped. Some changes
show, that there are some other unrelated changes to the files, which
indicates that some prior commit did not update the samples accordingly.
The relevant integration test
`mvn integration-test -f samples/server/petstore/rust-axum/pom.xml`
passes.
  • Loading branch information
myz-dev committed May 7, 2024
1 parent 9929d35 commit 2d967cc
Show file tree
Hide file tree
Showing 35 changed files with 2,760 additions and 39 deletions.
9 changes: 9 additions & 0 deletions bin/configs/manual/rust-axum-header-uuid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
generatorName: rust-axum
outputDir: samples/server/petstore/rust-axum/output/rust-axum-header-uuid
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-axum/rust-axum-header-uuid.yaml
templateDir: modules/openapi-generator/src/main/resources/rust-axum
generateAliasAsModel: true
additionalProperties:
hideGenerationTimestamp: "true"
packageName: rust-axum-header-uui
enablePostProcessFile: true
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputFilter.Config;
import java.math.BigInteger;
import java.nio.file.Path;
import java.util.*;
Expand Down Expand Up @@ -552,6 +553,12 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
}
}

// Include renderUuidConversionImpl exactly once in the vendorExtensions map when
// at least one `uuid::Uuid` converted from a header value in the resulting Rust code.
final Boolean renderUuidConversionImpl = op.headerParams.stream().anyMatch(h -> h.getDataType().equals(uuidType));
if (renderUuidConversionImpl) {
additionalProperties.put("renderUuidConversionImpl", "true");
}
return op;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{convert::TryFrom, fmt, ops::Deref};
use std::{convert::TryFrom, fmt, ops::Deref{{#renderUuidConversionImpl}}, str::FromStr{{/renderUuidConversionImpl}}};

use chrono::{DateTime, Utc};
use http::HeaderValue;
Expand Down Expand Up @@ -178,3 +178,39 @@ impl TryFrom<IntoHeaderValue<DateTime<Utc>>> for HeaderValue {
}
}
}

{{#renderUuidConversionImpl}}
// uuid::Uuid

impl TryFrom<HeaderValue> for IntoHeaderValue<uuid::Uuid> {
type Error = String;
fn try_from(hdr_value: HeaderValue) -> Result<Self, Self::Error> {
match hdr_value.to_str() {
Ok(hdr_value) => match uuid::Uuid::from_str(hdr_value) {
Ok(uuid) => Ok(IntoHeaderValue(uuid)),
Err(e) => Err(format!("Unable to parse: {} as uuid - {}", hdr_value, e)),
},
Err(e) => Err(format!(
"Unable to convert header {:?} to string {}",
hdr_value, e
)),
}
}
}

impl TryFrom<IntoHeaderValue<uuid::Uuid>> for HeaderValue {
type Error = String;
fn try_from(hdr_value: IntoHeaderValue<uuid::Uuid>) -> Result<Self, Self::Error> {
match HeaderValue::from_bytes(hdr_value.0.as_bytes()) {
Ok(hdr_value) => Ok(hdr_value),
Err(e) => Err(format!(
"Unable to convert {:?} to a header: {}",
hdr_value, e
)),
}
}
}

{{/renderUuidConversionImpl}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Test deserialization of uuid objects in headers
openapi: 3.0.0
info:
title: Sample API
version: 0.1.9
paths:
/users:
post:
description: Adds a user to the users database table.
parameters:
- $ref: "#/components/parameters/UuidHeaderParam"
responses:
"201": # status code
description: Added row to table!
content:
application/json:
schema:
type: string
components:
schemas:
HeaderUuid:
type: string
format: uuid
example: a9f5a638-728c-479d-af9b-016eb8049ab6
parameters:
UuidHeaderParam:
name: some_uid
in: header
required: true
description: A uuid transmitted in the header.
schema:
$ref: "#/components/schemas/HeaderUuid"
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.5.0-SNAPSHOT
7.6.0-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ 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.5.0-SNAPSHOT
- Generator version: 7.6.0-SNAPSHOT



Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.5.0-SNAPSHOT
7.6.0-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ 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.5.0-SNAPSHOT
- Generator version: 7.6.0-SNAPSHOT



Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.5.0-SNAPSHOT
7.6.0-SNAPSHOT
2 changes: 1 addition & 1 deletion samples/server/petstore/rust-axum/output/ops-v3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech))

- API version: 0.0.1
- Generator version: 7.5.0-SNAPSHOT
- Generator version: 7.6.0-SNAPSHOT



Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.5.0-SNAPSHOT
7.6.0-SNAPSHOT
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ server, you can easily generate a server stub.
To see how to make this your own, look here: [README]((https://openapi-generator.tech))

- API version: 1.0.0
- Generator version: 7.5.0-SNAPSHOT
- Generator version: 7.6.0-SNAPSHOT



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ pub trait Api {
method: Method,
host: Host,
cookies: CookieJar,
body: models::TestEndpointParametersRequest,
) -> Result<TestEndpointParametersResponse, String>;

/// To test enum parameters.
Expand All @@ -457,6 +458,7 @@ pub trait Api {
cookies: CookieJar,
header_params: models::TestEnumParametersHeaderParams,
query_params: models::TestEnumParametersQueryParams,
body: Option<models::TestEnumParametersRequest>,
) -> Result<TestEnumParametersResponse, String>;

/// test inline additionalProperties.
Expand All @@ -478,6 +480,7 @@ pub trait Api {
method: Method,
host: Host,
cookies: CookieJar,
body: models::TestJsonFormDataRequest,
) -> Result<TestJsonFormDataResponse, String>;

/// To test class name in snake case.
Expand Down Expand Up @@ -567,6 +570,7 @@ pub trait Api {
host: Host,
cookies: CookieJar,
path_params: models::UpdatePetWithFormPathParams,
body: Option<models::UpdatePetWithFormRequest>,
) -> Result<UpdatePetWithFormResponse, String>;

/// uploads an image.
Expand Down
Loading

0 comments on commit 2d967cc

Please sign in to comment.