Skip to content

Commit 2d967cc

Browse files
authored
[Rust-Axum] Fix uuid in header params causing compilation errors (#18563)
* 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.
1 parent 9929d35 commit 2d967cc

File tree

35 files changed

+2760
-39
lines changed

35 files changed

+2760
-39
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
generatorName: rust-axum
2+
outputDir: samples/server/petstore/rust-axum/output/rust-axum-header-uuid
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/rust-axum/rust-axum-header-uuid.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/rust-axum
5+
generateAliasAsModel: true
6+
additionalProperties:
7+
hideGenerationTimestamp: "true"
8+
packageName: rust-axum-header-uui
9+
enablePostProcessFile: true

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/RustAxumServerCodegen.java

+7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
import java.io.File;
4747
import java.io.IOException;
48+
import java.io.ObjectInputFilter.Config;
4849
import java.math.BigInteger;
4950
import java.nio.file.Path;
5051
import java.util.*;
@@ -552,6 +553,12 @@ public CodegenOperation fromOperation(String path, String httpMethod, Operation
552553
}
553554
}
554555

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

modules/openapi-generator/src/main/resources/rust-axum/header.mustache

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{convert::TryFrom, fmt, ops::Deref};
1+
use std::{convert::TryFrom, fmt, ops::Deref{{#renderUuidConversionImpl}}, str::FromStr{{/renderUuidConversionImpl}}};
22

33
use chrono::{DateTime, Utc};
44
use http::HeaderValue;
@@ -178,3 +178,39 @@ impl TryFrom<IntoHeaderValue<DateTime<Utc>>> for HeaderValue {
178178
}
179179
}
180180
}
181+
182+
{{#renderUuidConversionImpl}}
183+
// uuid::Uuid
184+
185+
impl TryFrom<HeaderValue> for IntoHeaderValue<uuid::Uuid> {
186+
type Error = String;
187+
188+
fn try_from(hdr_value: HeaderValue) -> Result<Self, Self::Error> {
189+
match hdr_value.to_str() {
190+
Ok(hdr_value) => match uuid::Uuid::from_str(hdr_value) {
191+
Ok(uuid) => Ok(IntoHeaderValue(uuid)),
192+
Err(e) => Err(format!("Unable to parse: {} as uuid - {}", hdr_value, e)),
193+
},
194+
Err(e) => Err(format!(
195+
"Unable to convert header {:?} to string {}",
196+
hdr_value, e
197+
)),
198+
}
199+
}
200+
}
201+
202+
impl TryFrom<IntoHeaderValue<uuid::Uuid>> for HeaderValue {
203+
type Error = String;
204+
205+
fn try_from(hdr_value: IntoHeaderValue<uuid::Uuid>) -> Result<Self, Self::Error> {
206+
match HeaderValue::from_bytes(hdr_value.0.as_bytes()) {
207+
Ok(hdr_value) => Ok(hdr_value),
208+
Err(e) => Err(format!(
209+
"Unable to convert {:?} to a header: {}",
210+
hdr_value, e
211+
)),
212+
}
213+
}
214+
}
215+
216+
{{/renderUuidConversionImpl}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Test deserialization of uuid objects in headers
2+
openapi: 3.0.0
3+
info:
4+
title: Sample API
5+
version: 0.1.9
6+
paths:
7+
/users:
8+
post:
9+
description: Adds a user to the users database table.
10+
parameters:
11+
- $ref: "#/components/parameters/UuidHeaderParam"
12+
responses:
13+
"201": # status code
14+
description: Added row to table!
15+
content:
16+
application/json:
17+
schema:
18+
type: string
19+
components:
20+
schemas:
21+
HeaderUuid:
22+
type: string
23+
format: uuid
24+
example: a9f5a638-728c-479d-af9b-016eb8049ab6
25+
parameters:
26+
UuidHeaderParam:
27+
name: some_uid
28+
in: header
29+
required: true
30+
description: A uuid transmitted in the header.
31+
schema:
32+
$ref: "#/components/schemas/HeaderUuid"
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.5.0-SNAPSHOT
1+
7.6.0-SNAPSHOT

samples/server/petstore/rust-axum/output/multipart-v3/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ server, you can easily generate a server stub.
1212
To see how to make this your own, look here: [README]((https://openapi-generator.tech))
1313

1414
- API version: 1.0.7
15-
- Generator version: 7.5.0-SNAPSHOT
15+
- Generator version: 7.6.0-SNAPSHOT
1616

1717

1818

Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.5.0-SNAPSHOT
1+
7.6.0-SNAPSHOT

samples/server/petstore/rust-axum/output/openapi-v3/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ server, you can easily generate a server stub.
1212
To see how to make this your own, look here: [README]((https://openapi-generator.tech))
1313

1414
- API version: 1.0.7
15-
- Generator version: 7.5.0-SNAPSHOT
15+
- Generator version: 7.6.0-SNAPSHOT
1616

1717

1818

Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.5.0-SNAPSHOT
1+
7.6.0-SNAPSHOT

samples/server/petstore/rust-axum/output/ops-v3/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ server, you can easily generate a server stub.
1212
To see how to make this your own, look here: [README]((https://openapi-generator.tech))
1313

1414
- API version: 0.0.1
15-
- Generator version: 7.5.0-SNAPSHOT
15+
- Generator version: 7.6.0-SNAPSHOT
1616

1717

1818

Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.5.0-SNAPSHOT
1+
7.6.0-SNAPSHOT

samples/server/petstore/rust-axum/output/petstore-with-fake-endpoints-models-for-testing/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ server, you can easily generate a server stub.
1212
To see how to make this your own, look here: [README]((https://openapi-generator.tech))
1313

1414
- API version: 1.0.0
15-
- Generator version: 7.5.0-SNAPSHOT
15+
- Generator version: 7.6.0-SNAPSHOT
1616

1717

1818

samples/server/petstore/rust-axum/output/petstore-with-fake-endpoints-models-for-testing/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ pub trait Api {
445445
method: Method,
446446
host: Host,
447447
cookies: CookieJar,
448+
body: models::TestEndpointParametersRequest,
448449
) -> Result<TestEndpointParametersResponse, String>;
449450

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

462464
/// test inline additionalProperties.
@@ -478,6 +480,7 @@ pub trait Api {
478480
method: Method,
479481
host: Host,
480482
cookies: CookieJar,
483+
body: models::TestJsonFormDataRequest,
481484
) -> Result<TestJsonFormDataResponse, String>;
482485

483486
/// To test class name in snake case.
@@ -567,6 +570,7 @@ pub trait Api {
567570
host: Host,
568571
cookies: CookieJar,
569572
path_params: models::UpdatePetWithFormPathParams,
573+
body: Option<models::UpdatePetWithFormRequest>,
570574
) -> Result<UpdatePetWithFormResponse, String>;
571575

572576
/// uploads an image.

0 commit comments

Comments
 (0)