Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -44,6 +44,7 @@
import org.slf4j.LoggerFactory;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.file.Path;
import java.util.*;
Expand Down Expand Up @@ -1024,6 +1025,63 @@ public CodegenParameter fromRequestBody(RequestBody body, Set<String> imports, S
return codegenParameter;
}

private String getIntegerDataType(String format,
BigInteger minimum,
boolean exclusiveMinimum,
BigInteger maximum,
boolean exclusiveMaximum,
boolean explicitUnsigned) {
boolean unsigned = explicitUnsigned || canFitIntoUnsigned(minimum, exclusiveMinimum);
Comment thread
LSX-s-Software marked this conversation as resolved.
Outdated

if (StringUtils.isEmpty(format)) {
return bestFittingIntegerType(
minimum,
exclusiveMinimum,
maximum,
exclusiveMaximum,
true);
Comment thread
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
}

switch (format) {
// custom integer formats (legacy)
case "uint32":
return "u32";
case "uint64":
return "u64";
case "int32":
return unsigned ? "u32" : "i32";
case "int64":
return unsigned ? "u64" : "i64";
default:
LOGGER.warn("The integer format '{}' is not recognized and will be ignored.", format);
return bestFittingIntegerType(
minimum,
exclusiveMinimum,
maximum,
exclusiveMaximum,
true);
}
}

@Override
public String getSchemaType(Schema p) {
if (Objects.equals(p.getType(), "integer")) {
BigInteger minimum = Optional.ofNullable(p.getMinimum()).map(BigDecimal::toBigInteger).orElse(null);
Comment thread
LSX-s-Software marked this conversation as resolved.
Outdated
BigInteger maximum = Optional.ofNullable(p.getMaximum()).map(BigDecimal::toBigInteger).orElse(null);
Comment thread
LSX-s-Software marked this conversation as resolved.
Outdated
boolean explicitUnsigned = ModelUtils.isUnsignedIntegerSchema(p) || ModelUtils.isUnsignedLongSchema(p);

return getIntegerDataType(
p.getFormat(),
minimum,
Optional.ofNullable(p.getExclusiveMinimum()).orElse(false),
maximum,
Optional.ofNullable(p.getExclusiveMaximum()).orElse(false),
explicitUnsigned);
}

return super.getSchemaType(p);
}

@Override
public String toInstantiationType(final Schema p) {
if (ModelUtils.isArraySchema(p)) {
Expand Down Expand Up @@ -1113,13 +1171,17 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
}

// Integer type fitting
if (Objects.equals(property.baseType, "integer")) {
if (Boolean.TRUE.equals(property.isInteger) || Boolean.TRUE.equals(property.isLong) || Objects.equals(property.baseType, "UnsignedInteger") || Objects.equals(property.baseType, "UnsignedLong")) {
BigInteger minimum = Optional.ofNullable(property.getMinimum()).map(BigInteger::new).orElse(null);
BigInteger maximum = Optional.ofNullable(property.getMaximum()).map(BigInteger::new).orElse(null);
property.dataType = bestFittingIntegerType(
minimum, property.getExclusiveMinimum(),
maximum, property.getExclusiveMaximum(),
true);
boolean explicitUnsigned = Objects.equals(property.baseType, "UnsignedInteger") || Objects.equals(property.baseType, "UnsignedLong");
property.dataType = getIntegerDataType(
property.dataFormat,
minimum,
property.getExclusiveMinimum(),
maximum,
property.getExclusiveMaximum(),
explicitUnsigned);
}

property.name = underscore(property.name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package org.openapitools.codegen.rust;

import io.swagger.v3.oas.models.media.IntegerSchema;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.RustAxumServerCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;

import static org.openapitools.codegen.TestUtils.linearize;
Expand Down Expand Up @@ -49,4 +54,53 @@ public void testPreventDuplicateOperationDeclaration() throws IOException {
TestUtils.assertFileExists(outputPath);
TestUtils.assertFileContains(outputPath, routerSpec);
}
}

@Test
public void testIntegerSchemaTypeMapping() {
RustAxumServerCodegen codegen = new RustAxumServerCodegen();
IntegerSchema schema = new IntegerSchema();

schema.setFormat("uint32");
Assert.assertEquals(codegen.getSchemaType(schema), "u32");

schema.setFormat("uint64");
Assert.assertEquals(codegen.getSchemaType(schema), "u64");

schema.setFormat("int32");
schema.setMinimum(BigDecimal.ZERO);
Assert.assertEquals(codegen.getSchemaType(schema), "u32");

schema.setFormat("int64");
Assert.assertEquals(codegen.getSchemaType(schema), "u64");

schema.setFormat(null);
schema.setMaximum(BigDecimal.valueOf(255));
Assert.assertEquals(codegen.getSchemaType(schema), "u8");

schema.setExtensions(new HashMap<>());
schema.getExtensions().put("x-unsigned", true);
schema.setMaximum(null);
Assert.assertEquals(codegen.getSchemaType(schema), "u32");
}

@Test
public void testGeneratedIntegerTypes() throws IOException {
Path target = Files.createTempDirectory("test");
final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("rust-axum")
.setInputSpec("src/test/resources/3_0/rust-axum/integer-types.yaml")
.setSkipOverwrite(false)
.setOutputDir(target.toAbsolutePath().toString().replace("\\", "/"));
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
files.forEach(File::deleteOnExit);

Path modelsPath = Path.of(target.toString(), "/src/models.rs");
TestUtils.assertFileExists(modelsPath);
TestUtils.assertFileContains(modelsPath, "pub legacy_uint32: u32");
TestUtils.assertFileContains(modelsPath, "pub legacy_uint64: u64");
TestUtils.assertFileContains(modelsPath, "pub positive_int32: u32");
TestUtils.assertFileContains(modelsPath, "pub positive_int64: u64");
TestUtils.assertFileContains(modelsPath, "pub small_positive: u8");
TestUtils.assertFileContains(modelsPath, "pub struct GetIntegersQueryParams");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
openapi: 3.0.3
info:
title: Rust Axum Integer Type Mapping Test
version: 1.0.0
paths:
/integers:
get:
operationId: getIntegers
parameters:
- name: legacy_uint32
in: query
required: true
schema:
type: integer
format: uint32
- name: legacy_uint64
in: query
required: true
schema:
type: integer
format: uint64
- name: positive_int32
in: query
required: true
schema:
type: integer
format: int32
minimum: 0
- name: positive_int64
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: small_positive
in: query
required: true
schema:
type: integer
minimum: 0
maximum: 255
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/IntegerTypes'
components:
schemas:
IntegerTypes:
type: object
required:
- legacy_uint32
- legacy_uint64
- positive_int32
- positive_int64
- small_positive
properties:
legacy_uint32:
type: integer
format: uint32
legacy_uint64:
type: integer
format: uint64
positive_int32:
type: integer
format: int32
minimum: 0
positive_int64:
type: integer
format: int64
minimum: 0
small_positive:
type: integer
minimum: 0
maximum: 255