Skip to content

Commit 4ba16b4

Browse files
devin-ai-integration[bot]iamnamananand996claude
authored
feat(rust): preserve parameter order in dynamic snippets and fix wire tests (#10829)
* fix(rust): use getStructNameByDeclaration for request struct naming in dynamic snippets The dynamic snippets generator was using getStructName() which doesn't account for name deduplication in the registry. This caused incorrect struct names to be generated for request types, particularly for query-only requests. Now using getStructNameByDeclaration() to ensure the generated snippet uses the same deduplicated struct names as the SDK generator. Co-Authored-By: [email protected] <[email protected]> * fix(rust): use getStructNameByDeclaration for request struct naming in dynamic snippets The dynamic snippets generator was using getStructName() which doesn't account for name deduplication in the registry. This caused incorrect struct names to be generated for request types, particularly for query-only requests. Now using getStructNameByDeclaration() to ensure the generated snippet uses the same deduplicated struct names as the SDK generator. Co-Authored-By: [email protected] <[email protected]> * chore(rust): enhance Rust snippet generator for default struct values Improves the Rust dynamic snippet generator to handle struct construction with ..Default::default() only when all fields are optional, matching the model generator's logic. Adds logic to fill in missing required fields with sensible defaults when Default cannot be used, and ensures query request struct names are deduplicated and consistent with the SDK generator. Also updates query parameter datetime formatting for consistency. * chore: seed update * chore(rust): bump version * chore(rust): bump version to 0.13.6 for dynamic snippets fix Co-Authored-By: [email protected] <[email protected]> * chore: dynamic snippets fix * fix(rust): avoid Default::default() in wire tests for non-Default types - Always explicitly provide all fields in generated wire tests instead of using ..Default::default() - Fix generateDefaultValueForType() to construct named types properly instead of using Default::default() - Use HashMap::new() and HashSet::new() instead of Default::default() for collections - This ensures wire tests compile correctly when request structs don't derive Default Co-Authored-By: [email protected] <[email protected]> * fix(rust): use getTypeNameById for named types in generateDefaultValueForType Co-Authored-By: [email protected] <[email protected]> * fix(rust): handle integer-based named types in generateDefaultValueForType - Look up named types from IR to determine underlying type - For alias types, recursively generate inner value and wrap with constructor - Fixes issue where Orgtype(pub i64) was incorrectly generated as Orgtype("value".to_string()) - Now correctly generates Orgtype(0) for integer newtypes, Orgname("value".to_string()) for string newtypes - Also handles enum types by using first variant Co-Authored-By: [email protected] <[email protected]> * fix(rust): use IR declaration names for request types in dynamic snippets Fix wire test request type naming to use IR declaration names instead of synthetic endpoint-based names. For inlined requests with properties body, use the actual type name from the IR (e.g., ResponseChargeBack) instead of generating synthetic names (e.g., AddResponseRequest). This ensures generated wire tests reference types that actually exist in the SDK, fixing E0422 compilation errors. Co-Authored-By: [email protected] <[email protected]> * chore: revert IR-sdk and ir-generator changes to focus on Rust-only fixes Co-Authored-By: [email protected] <[email protected]> * feat: preserve parameter order in dynamic snippets generation - Modified AbstractDynamicSnippetsGeneratorContext to iterate over parameters in schema order instead of Object.entries(values) - This ensures generated snippets maintain the parameter order defined in the API schema - Updated TypeScript and Python dynamic snippets test snapshots to reflect new behavior - Validation now skips parameters not provided in values instead of throwing errors for unrecognized keys Co-Authored-By: [email protected] <[email protected]> * chore: update dynamic snippets test snapshots for all generators - Updated C# dynamic snippets snapshots (10 snapshots) - Updated Go dynamic snippets snapshots (27 snapshots) - Updated Java dynamic snippets snapshots (8 snapshots) - Updated PHP dynamic snippets snapshots (10 snapshots) - Updated Ruby dynamic snippets snapshots (4 snapshots) These snapshot updates are required due to the parameter iteration order change in AbstractDynamicSnippetsGeneratorContext.ts which affects all dynamic snippets generators. Co-Authored-By: [email protected] <[email protected]> * update sdk ete * update sdk ete * chore(rust): update wiretests mechanism and fixes * fix: update snippets-core test snapshot for extends field Co-Authored-By: [email protected] <[email protected]> * chore: update snapshot * fix: preserve order * chore: snapshot update * revert: undo parameter order changes to AbstractDynamicSnippetsGeneratorContext Reverts changes that broke Java and other generators by adding stricter parameter validation. The Rust generator handles parameter order independently through its own DynamicTypeLiteralMapper. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * feat(rust): preserve parameter order in dynamic snippets Override associateByWireValue in Rust DynamicSnippetsGeneratorContext to iterate over schema parameters instead of Object.entries(values). This ensures generated Rust code has struct fields in the same order as defined in the API schema. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * chore: update ETE test snapshots for dynamic IR extends field The dynamic IR now includes an 'extends' field on ObjectType for handling inheritance patterns. This updates the ETE test snapshots to include this new field in IR and dynamic snippet outputs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * chore: bump CLI to 3.31.3 and Rust SDK to 0.13.9 - CLI 3.31.3: Add `extends` field to dynamic IR ObjectType for inheritance patterns - Rust SDK 0.13.9: Preserve parameter order in dynamic snippets 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(cli): bump version to 3.32.0 for feature addition (semantic versioning) Co-Authored-By: [email protected] <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: [email protected] <[email protected]> Co-authored-by: Claude Opus 4.5 <[email protected]>
1 parent 358e187 commit 4ba16b4

File tree

193 files changed

+2128
-568
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

193 files changed

+2128
-568
lines changed

generators/rust/base/src/asIs/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838

3939
- name: Set up Rust
4040
uses: actions-rust-lang/setup-rust-toolchain@v1
41-
41+
{{WIREMOCK_SETUP}}
4242
- name: Test
43-
run: cargo test
44-
{{PUBLISH_WORKFLOW}}
43+
run: {{TEST_COMMAND}}
44+
{{WIREMOCK_TEARDOWN}}{{PUBLISH_WORKFLOW}}

generators/rust/base/src/asIs/query_parameter_builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ impl QueryBuilder {
117117
/// Add a datetime parameter
118118
pub fn datetime(mut self, key: &str, value: impl Into<Option<DateTime<Utc>>>) -> Self {
119119
if let Some(v) = value.into() {
120-
self.params.push((key.to_string(), v.to_rfc3339()));
120+
self.params.push((key.to_string(), v.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)));
121121
}
122122
self
123123
}
@@ -135,7 +135,7 @@ impl QueryBuilder {
135135
if let Some(v) = value.into() {
136136
// Convert NaiveDate to DateTime<Utc> at start of day
137137
let datetime = v.and_hms_opt(0, 0, 0).unwrap().and_utc();
138-
self.params.push((key.to_string(), datetime.to_rfc3339()));
138+
self.params.push((key.to_string(), datetime.to_rfc3339_opts(chrono::SecondsFormat::Secs, true)));
139139
}
140140
self
141141
}

generators/rust/base/src/project/RustProject.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ export class RustProject extends AbstractProject<AbstractRustGeneratorContext<Ba
105105

106106
content = content.replace(/\{\{PUBLISH_WORKFLOW\}\}/g, this.generatePublishWorkflow());
107107

108+
// Conditionally include wiremock setup/teardown and test command for wire tests
109+
content = content.replace(/\{\{WIREMOCK_SETUP\}\}/g, this.generateWiremockSetup());
110+
content = content.replace(/\{\{WIREMOCK_TEARDOWN\}\}/g, this.generateWiremockTeardown());
111+
content = content.replace(/\{\{TEST_COMMAND\}\}/g, this.generateTestCommand());
112+
108113
// Conditionally include chrono exports in prelude
109114
if (this.context.usesDateTime()) {
110115
content = content.replace(
@@ -179,6 +184,55 @@ export class RustProject extends AbstractProject<AbstractRustGeneratorContext<Ba
179184
run: cargo publish`;
180185
}
181186

187+
/**
188+
* Generates the WireMock setup step for CI workflow when wire tests are enabled.
189+
* This starts the WireMock container before running tests.
190+
*/
191+
private generateWiremockSetup(): string {
192+
if (!this.context.customConfig.enableWireTests) {
193+
return "";
194+
}
195+
196+
return `
197+
- name: Setup WireMock server
198+
run: |
199+
if [ -f wiremock/docker-compose.test.yml ]; then
200+
docker compose -f wiremock/docker-compose.test.yml down 2>/dev/null || true
201+
docker compose -f wiremock/docker-compose.test.yml up -d --wait
202+
fi
203+
`;
204+
}
205+
206+
/**
207+
* Generates the WireMock teardown step for CI workflow when wire tests are enabled.
208+
* This stops the WireMock container after running tests.
209+
*/
210+
private generateWiremockTeardown(): string {
211+
if (!this.context.customConfig.enableWireTests) {
212+
return "";
213+
}
214+
215+
return `
216+
- name: Teardown WireMock server
217+
if: always()
218+
run: |
219+
if [ -f wiremock/docker-compose.test.yml ]; then
220+
docker compose -f wiremock/docker-compose.test.yml down
221+
fi
222+
`;
223+
}
224+
225+
/**
226+
* Generates the appropriate test command based on whether wire tests are enabled.
227+
* When wire tests are enabled, uses RUN_WIRE_TESTS=true and --test-threads=1.
228+
*/
229+
private generateTestCommand(): string {
230+
if (this.context.customConfig.enableWireTests) {
231+
return "RUN_WIRE_TESTS=true cargo test -- --test-threads=1";
232+
}
233+
return "cargo test";
234+
}
235+
182236
private objectToToml(obj: unknown): string {
183237
if (typeof obj === "string") {
184238
return `"${obj}"`;

0 commit comments

Comments
 (0)