From 344276eae0eac90fa67e83f145f983ad940f2696 Mon Sep 17 00:00:00 2001 From: bigmomma Date: Sat, 13 Jun 2026 15:19:33 -0400 Subject: [PATCH 1/2] fix(rust-server): include regex deps in client feature --- .../main/resources/rust-server/Cargo.mustache | 5 ++- .../codegen/rust/RustServerCodegenTest.java | 33 +++++++++++++++++++ .../3_0/rust-server/pattern-validation.yaml | 25 ++++++++++++++ .../output/no-example-v3/Cargo.toml | 1 + .../rust-server/output/openapi-v3/Cargo.toml | 2 +- .../rust-server/output/ops-v3/Cargo.toml | 1 + .../output/ping-bearer-auth/Cargo.toml | 1 + .../output/rust-server-test/Cargo.toml | 1 + 8 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml diff --git a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache index 3d145ccb6c50..28267a14a55d 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache @@ -43,8 +43,11 @@ client = [ {{#usesUrlEncodedForm}} "serde_urlencoded", {{/usesUrlEncodedForm}} +{{^apiUsesByteArray}} + "lazy_static", "regex", +{{/apiUsesByteArray}} {{#hasCallbacks}} - "serde_ignored", "percent-encoding", {{^apiUsesByteArray}}"lazy_static", "regex",{{/apiUsesByteArray}} + "serde_ignored", "percent-encoding", {{/hasCallbacks}} {{! Anything added to the list below, should probably be added to the callbacks list below }} "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" 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..c796a3c6f9e6 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 @@ -3,6 +3,7 @@ import org.openapitools.codegen.DefaultGenerator; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.config.CodegenConfigurator; +import org.testng.Assert; import org.testng.annotations.Test; import java.io.File; @@ -112,4 +113,36 @@ public void testRequiredQueryParamWithoutExampleDisablesClientExample() throws I // Clean up target.toFile().deleteOnExit(); } + + @Test + public void testPatternValidationModelsEnableClientRegexDependencies() throws IOException { + Path target = Files.createTempDirectory("test"); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("rust-server") + .setInputSpec("src/test/resources/3_0/rust-server/pattern-validation.yaml") + .setSkipOverwrite(false) + .setOutputDir(target.toAbsolutePath().toString().replace("\\", "/")); + List files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + Path cargoPath = Path.of(target.toString(), "/Cargo.toml"); + Path modelsPath = Path.of(target.toString(), "/src/models.rs"); + TestUtils.assertFileExists(cargoPath); + TestUtils.assertFileExists(modelsPath); + TestUtils.assertFileContains(modelsPath, "lazy_static::lazy_static!", "regex::Regex"); + + String cargoToml = Files.readString(cargoPath); + int clientStart = cargoToml.indexOf("client = ["); + int clientEnd = cargoToml.indexOf("]\n# TLS support", clientStart); + Assert.assertTrue(clientStart >= 0, "Generated Cargo.toml should contain a client feature"); + Assert.assertTrue(clientEnd > clientStart, "Generated Cargo.toml should close the client feature before TLS support"); + String clientFeature = cargoToml.substring(clientStart, clientEnd); + Assert.assertTrue(clientFeature.contains("\"lazy_static\""), + "Client-only builds need lazy_static when shared models emit pattern validation statics"); + Assert.assertTrue(clientFeature.contains("\"regex\""), + "Client-only builds need regex when shared models emit pattern validation statics"); + + // Clean up + target.toFile().deleteOnExit(); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml new file mode 100644 index 000000000000..b786fdaffbfa --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml @@ -0,0 +1,25 @@ +openapi: 3.0.3 +info: + title: Pattern validation test + version: 1.0.0 +paths: + /phone: + get: + operationId: getPhone + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/PhoneNumber' +components: + schemas: + PhoneNumber: + type: object + required: + - value + properties: + value: + type: string + pattern: '^[+][1-9]\d{1,14}$' diff --git a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml index 9e73002e56fe..6b0bbff39758 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" [features] default = ["client", "server", "client-tls"] client = [ + "lazy_static", "regex", "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" ] # TLS support - automatically selects backend based on target OS: diff --git a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml index 3fdf5173ea2e..d3da1f6e2c64 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" default = ["client", "server", "client-tls"] client = [ "serde_urlencoded", - "serde_ignored", "percent-encoding", + "serde_ignored", "percent-encoding", "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" ] # TLS support - automatically selects backend based on target OS: diff --git a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml index 12c55c614ae5..ee8b4b6f8acf 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" [features] default = ["client", "server", "client-tls"] client = [ + "lazy_static", "regex", "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" ] # TLS support - automatically selects backend based on target OS: diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml index 92666ec67329..fd38225badbc 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" [features] default = ["client", "server", "client-tls"] client = [ + "lazy_static", "regex", "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" ] # TLS support - automatically selects backend based on target OS: diff --git a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml index 8a9ac600d58a..28b90b171ac8 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml +++ b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml @@ -10,6 +10,7 @@ edition = "2018" [features] default = ["client", "server", "client-tls"] client = [ + "lazy_static", "regex", "hyper", "percent-encoding", "hyper-util/http1", "hyper-util/http2", "url" ] # TLS support - automatically selects backend based on target OS: From 88db979e52cd073c255ecd20c70f71c7f511f806 Mon Sep 17 00:00:00 2001 From: bigmomma Date: Tue, 16 Jun 2026 02:17:26 -0400 Subject: [PATCH 2/2] Fix rust-server client deps for pattern validation Pattern validation emits shared model code that uses lazy_static and regex, so client-only builds need those crates outside the callback-only feature block. Also bound serde_valid below 2.0.2 for rust-server output because swagger 7.0.0 still uses the older enum validation API and fails against serde_valid 2.0.2. Verification: - ./mvnw -pl modules/openapi-generator -am -Dtest=RustServerCodegenTest -Dsurefire.failIfNoSpecifiedTests=false test - cargo build --all-targets --all-features - cargo build --all-targets --no-default-features - client-only rust-server sample package sweep --- .../src/main/resources/rust-server/Cargo.mustache | 2 +- .../codegen/rust/RustServerCodegenTest.java | 12 +++++++++--- ...n.yaml => pattern-validation-client-feature.yaml} | 8 ++++---- .../rust-server/output/multipart-v3/Cargo.toml | 2 +- .../rust-server/output/no-example-v3/Cargo.toml | 2 +- .../rust-server/output/openapi-v3/Cargo.toml | 2 +- .../petstore/rust-server/output/ops-v3/Cargo.toml | 2 +- .../Cargo.toml | 2 +- .../rust-server/output/ping-bearer-auth/Cargo.toml | 2 +- .../rust-server/output/rust-server-test/Cargo.toml | 2 +- 10 files changed, 21 insertions(+), 15 deletions(-) rename modules/openapi-generator/src/test/resources/3_0/rust-server/{pattern-validation.yaml => pattern-validation-client-feature.yaml} (67%) diff --git a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache index 28267a14a55d..1367e580b1de 100644 --- a/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache +++ b/modules/openapi-generator/src/main/resources/rust-server/Cargo.mustache @@ -111,7 +111,7 @@ serde_json = "1.0" {{#apiUsesIntegerEnums}} serde_repr = "0.1" {{/apiUsesIntegerEnums}} -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } 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 c796a3c6f9e6..edb878f960f4 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 @@ -114,12 +114,15 @@ public void testRequiredQueryParamWithoutExampleDisablesClientExample() throws I target.toFile().deleteOnExit(); } + /** + * Test that model pattern validation dependencies are enabled for client-only builds. + */ @Test - public void testPatternValidationModelsEnableClientRegexDependencies() throws IOException { + public void testClientFeatureIncludesPatternValidationDependencies() throws IOException { Path target = Files.createTempDirectory("test"); final CodegenConfigurator configurator = new CodegenConfigurator() .setGeneratorName("rust-server") - .setInputSpec("src/test/resources/3_0/rust-server/pattern-validation.yaml") + .setInputSpec("src/test/resources/3_0/rust-server/pattern-validation-client-feature.yaml") .setSkipOverwrite(false) .setOutputDir(target.toAbsolutePath().toString().replace("\\", "/")); List files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate(); @@ -129,7 +132,9 @@ public void testPatternValidationModelsEnableClientRegexDependencies() throws IO Path modelsPath = Path.of(target.toString(), "/src/models.rs"); TestUtils.assertFileExists(cargoPath); TestUtils.assertFileExists(modelsPath); - TestUtils.assertFileContains(modelsPath, "lazy_static::lazy_static!", "regex::Regex"); + + TestUtils.assertFileContains(modelsPath, "lazy_static::lazy_static!"); + TestUtils.assertFileContains(modelsPath, "regex::Regex"); String cargoToml = Files.readString(cargoPath); int clientStart = cargoToml.indexOf("client = ["); @@ -141,6 +146,7 @@ public void testPatternValidationModelsEnableClientRegexDependencies() throws IO "Client-only builds need lazy_static when shared models emit pattern validation statics"); Assert.assertTrue(clientFeature.contains("\"regex\""), "Client-only builds need regex when shared models emit pattern validation statics"); + TestUtils.assertFileContains(cargoPath, "serde_valid = { version = \">=2.0, <2.0.2\", optional = true }"); // Clean up target.toFile().deleteOnExit(); diff --git a/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml b/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation-client-feature.yaml similarity index 67% rename from modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml rename to modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation-client-feature.yaml index b786fdaffbfa..252e5cae4a58 100644 --- a/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/rust-server/pattern-validation-client-feature.yaml @@ -1,18 +1,18 @@ openapi: 3.0.3 info: - title: Pattern validation test + title: Rust server pattern validation client feature test version: 1.0.0 paths: /phone: get: operationId: getPhone responses: - '200': + "200": description: OK content: application/json: schema: - $ref: '#/components/schemas/PhoneNumber' + $ref: "#/components/schemas/PhoneNumber" components: schemas: PhoneNumber: @@ -22,4 +22,4 @@ components: properties: value: type: string - pattern: '^[+][1-9]\d{1,14}$' + pattern: '^\\+[1-9]\\d{1,14}$' diff --git a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml index 9712bd2a7c2c..c9a2e1fe3386 100644 --- a/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/multipart-v3/Cargo.toml @@ -57,7 +57,7 @@ regex = "1.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml index 6b0bbff39758..f6248374399d 100644 --- a/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/no-example-v3/Cargo.toml @@ -52,7 +52,7 @@ mockall = { version = "0.14", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml index d3da1f6e2c64..49f8a1fc53a1 100644 --- a/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/openapi-v3/Cargo.toml @@ -56,7 +56,7 @@ regex = "1.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml index ee8b4b6f8acf..3c5471e007f2 100644 --- a/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ops-v3/Cargo.toml @@ -52,7 +52,7 @@ mockall = { version = "0.14", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml index 3835cb94a4b1..db9339f6279d 100644 --- a/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml +++ b/samples/server/petstore/rust-server/output/petstore-with-fake-endpoints-models-for-testing/Cargo.toml @@ -58,7 +58,7 @@ regex = "1.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_repr = "0.1" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml index fd38225badbc..31d148944872 100644 --- a/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml +++ b/samples/server/petstore/rust-server/output/ping-bearer-auth/Cargo.toml @@ -52,7 +52,7 @@ mockall = { version = "0.14", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] } diff --git a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml index 28b90b171ac8..df8f404e92d4 100644 --- a/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml +++ b/samples/server/petstore/rust-server/output/rust-server-test/Cargo.toml @@ -52,7 +52,7 @@ mockall = { version = "0.14", optional = true } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -serde_valid = { version = "2.0", optional = true } +serde_valid = { version = ">=2.0, <2.0.2", optional = true } validator = { version = "0.20", features = ["derive"] }