From afa7890f9795d104ba88c0223bdd17265f5c3f68 Mon Sep 17 00:00:00 2001 From: Matthew Rayermann Date: Fri, 11 Sep 2026 17:17:45 -0700 Subject: [PATCH 1/2] [Chore] Handle Rust Unknown Enum Collision Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/codegen-check.yml | 4 ++++ scripts/codegen/package.json | 3 ++- scripts/codegen/rust.test.ts | 23 +++++++++++++++++++++++ scripts/codegen/rust.ts | 12 ++++++++++-- 4 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 scripts/codegen/rust.test.ts diff --git a/.github/workflows/codegen-check.yml b/.github/workflows/codegen-check.yml index 8642ee2e67..f66fa97f0d 100644 --- a/.github/workflows/codegen-check.yml +++ b/.github/workflows/codegen-check.yml @@ -64,6 +64,10 @@ jobs: working-directory: ./scripts/codegen run: npm ci + - name: Test codegen + working-directory: ./scripts/codegen + run: npm test + - name: Run codegen working-directory: ./scripts/codegen run: npm run generate diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json index 8e65352916..2f5e349c1b 100644 --- a/scripts/codegen/package.json +++ b/scripts/codegen/package.json @@ -8,7 +8,8 @@ "generate:csharp": "tsx csharp.ts", "generate:python": "tsx python.ts", "generate:go": "tsx go.ts", - "generate:rust": "tsx rust.ts" + "generate:rust": "tsx rust.ts", + "test": "tsx --test *.test.ts" }, "dependencies": { "json-schema": "^0.4.0", diff --git a/scripts/codegen/rust.test.ts b/scripts/codegen/rust.test.ts new file mode 100644 index 0000000000..32a3085d33 --- /dev/null +++ b/scripts/codegen/rust.test.ts @@ -0,0 +1,23 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import type { JSONSchema7 } from "json-schema"; + +import { generateApiTypesCode } from "./rust.js"; + +test("names an explicit unknown wire value separately from the catch-all", () => { + const schema = { + definitions: { + CatalogTrustEligibility: { + type: "string", + enum: ["default", "expanded", "hidden", "unknown"], + }, + }, + } satisfies JSONSchema7; + + const generated = generateApiTypesCode(schema); + + assert.match( + generated, + / #\[serde\(rename = "unknown"\)\]\n UnknownValue,\n \/\/\/ Unknown variant for forward compatibility\.\n #\[default\]\n #\[serde\(other\)\]\n Unknown,/, + ); +}); diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts index b3cc5d5753..9961735591 100644 --- a/scripts/codegen/rust.ts +++ b/scripts/codegen/rust.ts @@ -85,6 +85,12 @@ const STRING_NEWTYPE_OVERRIDES: Record = { requestId: "RequestId", }; +const STRING_ENUM_VARIANT_OVERRIDES: Record> = { + CatalogTrustEligibility: { + unknown: "UnknownValue", + }, +}; + // ── Naming helpers ────────────────────────────────────────────────────────── function toPascalCase(s: string): string { @@ -115,8 +121,9 @@ function uniqueRustPascalIdentifier( used: Set, fallback: string, reserved: Set = new Set(), + override?: string, ): string { - const identifier = toRustPascalIdentifier(value, fallback); + const identifier = override ?? toRustPascalIdentifier(value, fallback); if (used.has(identifier) || reserved.has(identifier)) { throw new Error( `Generated Rust enum variant identifier "${identifier}" is not unique for value "${value}". Add an explicit naming rule instead of stabilizing an arbitrary public variant name.`, @@ -1045,6 +1052,7 @@ function emitRustStringEnum( usedVariantNames, "Value", reservedVariantNames, + STRING_ENUM_VARIANT_OVERRIDES[enumName]?.[value], ); pushRustDoc(lines, enumValueDescriptions?.[value], " "); if (variantName !== value) { @@ -1449,7 +1457,7 @@ function isNullableParamsSchema( return !!resolved && !!getNullableInner(resolved); } -function generateApiTypesCode( +export function generateApiTypesCode( apiSchema: ApiSchema, nonDefaultableTypes: Iterable = [], ): string { From 4a4f3ad08eefc1aecc9b66f4375a04a74a62cbaa Mon Sep 17 00:00:00 2001 From: Matthew Rayermann Date: Fri, 11 Sep 2026 17:19:05 -0700 Subject: [PATCH 2/2] Remove standalone codegen test suite Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/codegen-check.yml | 4 ---- scripts/codegen/package.json | 3 +-- scripts/codegen/rust.test.ts | 23 ----------------------- scripts/codegen/rust.ts | 2 +- 4 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 scripts/codegen/rust.test.ts diff --git a/.github/workflows/codegen-check.yml b/.github/workflows/codegen-check.yml index f66fa97f0d..8642ee2e67 100644 --- a/.github/workflows/codegen-check.yml +++ b/.github/workflows/codegen-check.yml @@ -64,10 +64,6 @@ jobs: working-directory: ./scripts/codegen run: npm ci - - name: Test codegen - working-directory: ./scripts/codegen - run: npm test - - name: Run codegen working-directory: ./scripts/codegen run: npm run generate diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json index 2f5e349c1b..8e65352916 100644 --- a/scripts/codegen/package.json +++ b/scripts/codegen/package.json @@ -8,8 +8,7 @@ "generate:csharp": "tsx csharp.ts", "generate:python": "tsx python.ts", "generate:go": "tsx go.ts", - "generate:rust": "tsx rust.ts", - "test": "tsx --test *.test.ts" + "generate:rust": "tsx rust.ts" }, "dependencies": { "json-schema": "^0.4.0", diff --git a/scripts/codegen/rust.test.ts b/scripts/codegen/rust.test.ts deleted file mode 100644 index 32a3085d33..0000000000 --- a/scripts/codegen/rust.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import assert from "node:assert/strict"; -import test from "node:test"; -import type { JSONSchema7 } from "json-schema"; - -import { generateApiTypesCode } from "./rust.js"; - -test("names an explicit unknown wire value separately from the catch-all", () => { - const schema = { - definitions: { - CatalogTrustEligibility: { - type: "string", - enum: ["default", "expanded", "hidden", "unknown"], - }, - }, - } satisfies JSONSchema7; - - const generated = generateApiTypesCode(schema); - - assert.match( - generated, - / #\[serde\(rename = "unknown"\)\]\n UnknownValue,\n \/\/\/ Unknown variant for forward compatibility\.\n #\[default\]\n #\[serde\(other\)\]\n Unknown,/, - ); -}); diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts index 9961735591..776f468495 100644 --- a/scripts/codegen/rust.ts +++ b/scripts/codegen/rust.ts @@ -1457,7 +1457,7 @@ function isNullableParamsSchema( return !!resolved && !!getNullableInner(resolved); } -export function generateApiTypesCode( +function generateApiTypesCode( apiSchema: ApiSchema, nonDefaultableTypes: Iterable = [], ): string {