Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,16 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
param.isPrimitiveType = true;
param.isString = true;
}

// Free-form objects are typed `serde_json::Value`, which does not live in the
// generated `models` module. Mark them as primitive so the templates do not
// qualify the type with a `models::` prefix, mirroring what
// `DefaultCodegen.updateRequestBodyForObject` already does for free-form body
// parameters. Free-form schemas with `additionalProperties` map to a container
// type (`HashMap`) and must keep their existing handling.
if (param.isFreeFormObject && !param.isContainer) {
param.isPrimitiveType = true;
}
}

if (operation.pathParams != null && operation.pathParams.size() > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,30 @@ public void testIntegerPropertyEnum() throws IOException {
TestUtils.assertFileNotContains(outputPath, linearize("#[serde(rename = \"0\")]"));
}

@Test
public void testFreeFormObjectQueryParam() throws IOException {
Path target = Files.createTempDirectory("test");
target.toFile().deleteOnExit();
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("rust")
.setInputSpec("src/test/resources/3_0/rust/free-form-object-query-param.yaml")
.setSkipOverwrite(false)
.setOutputDir(target.toAbsolutePath().toString().replace("\\", "/"));
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);
Path outputPath = Path.of(target.toString(), "/src/apis/default_api.rs");
TestUtils.assertFileExists(outputPath);
// A free-form object query parameter maps to `serde_json::Value`, which lives
// outside of the `models` module.
TestUtils.assertFileContains(outputPath, "filter: Option<serde_json::Value>");
TestUtils.assertFileNotContains(outputPath, "models::serde_json");
// A free-form object with additionalProperties stays a map.
TestUtils.assertFileContains(outputPath, "tags: Option<std::collections::HashMap<String, String>>");
TestUtils.assertFileContains(outputPath, "meta: Option<std::collections::HashMap<String, serde_json::Value>>");
// Maps keep their JSON serialization (`HashMap` does not implement `Display`).
TestUtils.assertFileContains(outputPath, "req_builder.query(&[(\"meta\", &serde_json::to_string(param_value)?)])");
}

@Test
public void testArrayWithObjectEnumValues() throws IOException {
Path target = Files.createTempDirectory("test");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
openapi: 3.0.0
info:
title: Free-form object query parameter
version: 1.0.0
paths:
/things:
get:
operationId: listThings
parameters:
- name: filter
in: query
description: A free-form object query parameter.
schema:
type: object
- name: tags
in: query
description: A free-form object with typed additionalProperties (a map).
schema:
type: object
additionalProperties:
type: string
- name: meta
in: query
description: A free-form object with additionalProperties true (also a map).
schema:
type: object
additionalProperties: true
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
type: string