mirror of
https://github.com/jlengrand/openapi-generator.git
synced 2026-03-10 08:31:23 +00:00
[csharp-netcore] Add unsigned integer/long support (#14885)
* add unsigned integer/long support to c# netcore client * undo change in test spec, samples * new test spec * update doc
This commit is contained in:
@@ -105,6 +105,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
<li>long</li>
|
||||
<li>long?</li>
|
||||
<li>string</li>
|
||||
<li>uint</li>
|
||||
<li>uint?</li>
|
||||
<li>ulong</li>
|
||||
<li>ulong?</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
@@ -98,6 +98,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
<li>long</li>
|
||||
<li>long?</li>
|
||||
<li>string</li>
|
||||
<li>uint</li>
|
||||
<li>uint?</li>
|
||||
<li>ulong</li>
|
||||
<li>ulong?</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
@@ -99,6 +99,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
<li>long</li>
|
||||
<li>long?</li>
|
||||
<li>string</li>
|
||||
<li>uint</li>
|
||||
<li>uint?</li>
|
||||
<li>ulong</li>
|
||||
<li>ulong?</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
@@ -93,6 +93,10 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|
||||
<li>long</li>
|
||||
<li>long?</li>
|
||||
<li>string</li>
|
||||
<li>uint</li>
|
||||
<li>uint?</li>
|
||||
<li>ulong</li>
|
||||
<li>ulong?</li>
|
||||
</ul>
|
||||
|
||||
## RESERVED WORDS
|
||||
|
||||
@@ -1728,9 +1728,11 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
typeMapping.put("DateTime", "Date");
|
||||
typeMapping.put("long", "Long");
|
||||
typeMapping.put("short", "Short");
|
||||
typeMapping.put("integer", "Integer");
|
||||
typeMapping.put("UnsignedInteger", "Integer");
|
||||
typeMapping.put("UnsignedLong", "Long");
|
||||
typeMapping.put("char", "String");
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("integer", "Integer");
|
||||
// FIXME: java specific type should be in Java Based Abstract Impl's
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
typeMapping.put("binary", "File");
|
||||
@@ -2394,8 +2396,14 @@ public class DefaultCodegen implements CodegenConfig {
|
||||
return "number";
|
||||
}
|
||||
} else if (ModelUtils.isIntegerSchema(schema)) {
|
||||
if (ModelUtils.isLongSchema(schema)) {
|
||||
if (ModelUtils.isUnsignedLongSchema(schema)) {
|
||||
return "UnsignedLong";
|
||||
} else if (ModelUtils.isUnsignedIntegerSchema(schema)) {
|
||||
return "UnsignedInteger";
|
||||
} else if (ModelUtils.isLongSchema(schema)) {
|
||||
return "long";
|
||||
} else if (ModelUtils.isShortSchema(schema)) {// int32
|
||||
return "integer";
|
||||
} else {
|
||||
return schema.getType(); // integer
|
||||
}
|
||||
|
||||
@@ -160,8 +160,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
"decimal",
|
||||
"int?",
|
||||
"int",
|
||||
"uint",
|
||||
"uint?",
|
||||
"long?",
|
||||
"long",
|
||||
"ulong",
|
||||
"ulong?",
|
||||
"float?",
|
||||
"float",
|
||||
"byte[]",
|
||||
@@ -197,8 +201,10 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
typeMapping.put("boolean", "bool?");
|
||||
typeMapping.put("integer", "int?");
|
||||
typeMapping.put("float", "float?");
|
||||
typeMapping.put("UnsignedInteger", "uint?");
|
||||
typeMapping.put("UnsignedLong", "ulong?");
|
||||
typeMapping.put("long", "long?");
|
||||
typeMapping.put("float", "float?");
|
||||
typeMapping.put("double", "double?");
|
||||
typeMapping.put("number", "decimal?");
|
||||
typeMapping.put("BigDecimal", "decimal?");
|
||||
@@ -215,11 +221,12 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
|
||||
// nullable type
|
||||
nullableType = new HashSet<>(
|
||||
Arrays.asList("decimal", "bool", "int", "float", "long", "double", "DateTime", "DateTimeOffset", "Guid")
|
||||
Arrays.asList("decimal", "bool", "int", "uint", "long", "ulong", "float", "double",
|
||||
"DateTime", "DateTimeOffset", "Guid")
|
||||
);
|
||||
// value Types
|
||||
valueTypes = new HashSet<>(
|
||||
Arrays.asList("decimal", "bool", "int", "float", "long", "double")
|
||||
Arrays.asList("decimal", "bool", "int", "uint", "long", "ulong", "float", "double")
|
||||
);
|
||||
|
||||
this.setSortParamsByRequiredFlag(true);
|
||||
@@ -1334,7 +1341,9 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
|
||||
// Per: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum
|
||||
// The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.
|
||||
// but we're not supporting unsigned integral types or shorts.
|
||||
if (datatype.startsWith("int") || datatype.startsWith("long") || datatype.startsWith("byte")) {
|
||||
if (datatype.startsWith("int") || datatype.startsWith("uint") ||
|
||||
datatype.startsWith("long") || datatype.startsWith("ulong") ||
|
||||
datatype.startsWith("byte")) {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,8 +123,10 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
|
||||
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("long", "long");
|
||||
typeMapping.put("UnsignedInteger", "uint");
|
||||
typeMapping.put("UnsignedLong", "ulong");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("double", "double");
|
||||
typeMapping.put("number", "decimal");
|
||||
typeMapping.put("decimal", "decimal");
|
||||
@@ -789,7 +791,8 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
|
||||
}
|
||||
|
||||
// number
|
||||
if (datatype.startsWith("int") || datatype.startsWith("long") ||
|
||||
if (datatype.startsWith("int") || datatype.startsWith("uint") ||
|
||||
datatype.startsWith("ulong") || datatype.startsWith("long") ||
|
||||
datatype.startsWith("double") || datatype.startsWith("float")) {
|
||||
String varName = "NUMBER_" + value;
|
||||
varName = varName.replaceAll("-", "MINUS_");
|
||||
|
||||
@@ -153,8 +153,10 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
|
||||
typeMapping.put("ByteArray", "byte[]");
|
||||
typeMapping.put("boolean", "bool");
|
||||
typeMapping.put("integer", "int");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("long", "long");
|
||||
typeMapping.put("UnsignedInteger", "uint");
|
||||
typeMapping.put("UnsignedLong", "ulong");
|
||||
typeMapping.put("float", "float");
|
||||
typeMapping.put("double", "double");
|
||||
typeMapping.put("number", "decimal");
|
||||
typeMapping.put("decimal", "decimal");
|
||||
@@ -1176,7 +1178,8 @@ public class CSharpNetCoreClientCodegen extends AbstractCSharpCodegen {
|
||||
}
|
||||
|
||||
// number
|
||||
if (datatype.startsWith("int") || datatype.startsWith("long") ||
|
||||
if (datatype.startsWith("int") || datatype.startsWith("uint") ||
|
||||
datatype.startsWith("long") || datatype.startsWith("ulong") ||
|
||||
datatype.startsWith("double") || datatype.startsWith("float")) {
|
||||
String varName = "NUMBER_" + value;
|
||||
varName = varName.replaceAll("-", "MINUS_");
|
||||
|
||||
@@ -606,6 +606,15 @@ public class ModelUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUnsignedIntegerSchema(Schema schema) {
|
||||
if (SchemaTypeUtil.INTEGER_TYPE.equals(schema.getType()) && // type: integer
|
||||
("int32".equals(schema.getFormat()) || schema.getFormat() == null) && // format: int32
|
||||
(schema.getExtensions() != null && (Boolean) schema.getExtensions().getOrDefault("x-unsigned", Boolean.FALSE))) { // x-unsigned: true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isLongSchema(Schema schema) {
|
||||
if (SchemaTypeUtil.INTEGER_TYPE.equals(schema.getType()) // type: integer
|
||||
&& SchemaTypeUtil.INTEGER64_FORMAT.equals(schema.getFormat())) { // format: long (int64)
|
||||
@@ -614,6 +623,15 @@ public class ModelUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUnsignedLongSchema(Schema schema) {
|
||||
if (SchemaTypeUtil.INTEGER_TYPE.equals(schema.getType()) && // type: integer
|
||||
"int64".equals(schema.getFormat()) && // format: int64
|
||||
(schema.getExtensions() != null && (Boolean) schema.getExtensions().getOrDefault("x-unsigned", Boolean.FALSE))) { // x-unsigned: true
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isBooleanSchema(Schema schema) {
|
||||
if (schema instanceof BooleanSchema) {
|
||||
return true;
|
||||
|
||||
@@ -16,7 +16,13 @@
|
||||
|
||||
package org.openapitools.codegen.csharpnetcore;
|
||||
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.openapitools.codegen.CodegenModel;
|
||||
import org.openapitools.codegen.CodegenProperty;
|
||||
import org.openapitools.codegen.TestUtils;
|
||||
import org.openapitools.codegen.languages.CSharpNetCoreClientCodegen;
|
||||
import org.openapitools.codegen.languages.JavaClientCodegen;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@@ -37,4 +43,36 @@ public class CSharpNetCoreClientCodegenTest {
|
||||
// Assert.assertEquals(codegen.toEnumVarName("FOO-BAR", "string"), "FooBar");
|
||||
// Assert.assertEquals(codegen.toEnumVarName("FOO_BAR", "string"), "FooBar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnsigned() {
|
||||
// test unsigned integer/long
|
||||
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/unsigned-test.yaml");
|
||||
CSharpNetCoreClientCodegen codegen = new CSharpNetCoreClientCodegen();
|
||||
|
||||
Schema test1 = openAPI.getComponents().getSchemas().get("format_test");
|
||||
codegen.setOpenAPI(openAPI);
|
||||
CodegenModel cm1 = codegen.fromModel("format_test", test1);
|
||||
Assert.assertEquals(cm1.getClassname(), "FormatTest");
|
||||
|
||||
final CodegenProperty property1 = cm1.allVars.get(2);
|
||||
Assert.assertEquals(property1.baseName, "unsigned_integer");
|
||||
Assert.assertEquals(property1.dataType, "uint");
|
||||
Assert.assertEquals(property1.vendorExtensions.get("x-unsigned"), Boolean.TRUE);
|
||||
Assert.assertTrue(property1.isPrimitiveType);
|
||||
Assert.assertTrue(property1.isInteger);
|
||||
Assert.assertFalse(property1.isContainer);
|
||||
Assert.assertFalse(property1.isFreeFormObject);
|
||||
Assert.assertFalse(property1.isAnyType);
|
||||
|
||||
final CodegenProperty property2 = cm1.allVars.get(4);
|
||||
Assert.assertEquals(property2.baseName, "unsigned_long");
|
||||
Assert.assertEquals(property2.dataType, "ulong");
|
||||
Assert.assertEquals(property2.vendorExtensions.get("x-unsigned"), Boolean.TRUE);
|
||||
Assert.assertTrue(property2.isPrimitiveType);
|
||||
Assert.assertTrue(property2.isLong);
|
||||
Assert.assertFalse(property2.isContainer);
|
||||
Assert.assertFalse(property2.isFreeFormObject);
|
||||
Assert.assertFalse(property2.isAnyType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
description: >-
|
||||
This spec is mainly for testing Petstore server and contains fake endpoints,
|
||||
models. Please do not use this for any other purpose. Special characters: "
|
||||
\
|
||||
version: 1.0.0
|
||||
title: OpenAPI Petstore
|
||||
license:
|
||||
name: Apache-2.0
|
||||
url: 'https://www.apache.org/licenses/LICENSE-2.0.html'
|
||||
tags:
|
||||
- name: pet
|
||||
description: Everything about your Pets
|
||||
- name: store
|
||||
description: Access to Petstore orders
|
||||
- name: user
|
||||
description: Operations about user
|
||||
paths:
|
||||
/foo:
|
||||
get:
|
||||
responses:
|
||||
default:
|
||||
description: response
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
string:
|
||||
$ref: '#/components/schemas/Foo'
|
||||
servers:
|
||||
- url: 'http://{server}.swagger.io:{port}/v2'
|
||||
description: petstore server
|
||||
variables:
|
||||
server:
|
||||
enum:
|
||||
- 'petstore'
|
||||
- 'qa-petstore'
|
||||
- 'dev-petstore'
|
||||
default: 'petstore'
|
||||
port:
|
||||
enum:
|
||||
- 80
|
||||
- 8080
|
||||
default: 80
|
||||
- url: https://localhost:8080/{version}
|
||||
description: The local server
|
||||
variables:
|
||||
version:
|
||||
enum:
|
||||
- 'v1'
|
||||
- 'v2'
|
||||
default: 'v2'
|
||||
- url: https://127.0.0.1/no_variable
|
||||
description: The local server without variables
|
||||
components:
|
||||
securitySchemes:
|
||||
petstore_auth:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
|
||||
scopes:
|
||||
'write:pets': modify pets in your account
|
||||
'read:pets': read your pets
|
||||
api_key:
|
||||
type: apiKey
|
||||
name: api_key
|
||||
in: header
|
||||
api_key_query:
|
||||
type: apiKey
|
||||
name: api_key_query
|
||||
in: query
|
||||
http_basic_test:
|
||||
type: http
|
||||
scheme: basic
|
||||
bearer_test:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
http_signature_test:
|
||||
# Test the 'HTTP signature' security scheme.
|
||||
# Each HTTP request is cryptographically signed as specified
|
||||
# in https://datatracker.ietf.org/doc/draft-cavage-http-signatures/
|
||||
type: http
|
||||
scheme: signature
|
||||
schemas:
|
||||
Foo:
|
||||
type: object
|
||||
properties:
|
||||
bar:
|
||||
$ref: '#/components/schemas/Bar'
|
||||
format_test:
|
||||
type: object
|
||||
required:
|
||||
- number
|
||||
- byte
|
||||
- date
|
||||
- password
|
||||
properties:
|
||||
integer:
|
||||
type: integer
|
||||
maximum: 100
|
||||
minimum: 10
|
||||
multipleOf: 2
|
||||
int32:
|
||||
type: integer
|
||||
format: int32
|
||||
maximum: 200
|
||||
minimum: 20
|
||||
unsigned_integer:
|
||||
type: integer
|
||||
format: int32
|
||||
maximum: 200
|
||||
minimum: 20
|
||||
x-unsigned: true
|
||||
int64:
|
||||
type: integer
|
||||
format: int64
|
||||
unsigned_long:
|
||||
type: integer
|
||||
format: int64
|
||||
x-unsigned: true
|
||||
number:
|
||||
maximum: 543.2
|
||||
minimum: 32.1
|
||||
type: number
|
||||
multipleOf: 32.5
|
||||
float:
|
||||
type: number
|
||||
format: float
|
||||
maximum: 987.6
|
||||
minimum: 54.3
|
||||
double:
|
||||
type: number
|
||||
format: double
|
||||
maximum: 123.4
|
||||
minimum: 67.8
|
||||
decimal:
|
||||
type: string
|
||||
format: number
|
||||
string:
|
||||
type: string
|
||||
pattern: '/[a-z]/i'
|
||||
byte:
|
||||
type: string
|
||||
format: byte
|
||||
binary:
|
||||
type: string
|
||||
format: binary
|
||||
date:
|
||||
type: string
|
||||
format: date
|
||||
example: '2020-02-02'
|
||||
dateTime:
|
||||
type: string
|
||||
format: date-time
|
||||
example: '2007-12-03T10:15:30+01:00'
|
||||
uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
example: 72f98069-206d-4f12-9f12-3d1e525a8e84
|
||||
password:
|
||||
type: string
|
||||
format: password
|
||||
maxLength: 64
|
||||
minLength: 10
|
||||
pattern_with_digits:
|
||||
description: A string that is a 10 digit number. Can have leading zeros.
|
||||
type: string
|
||||
pattern: '^\d{10}$'
|
||||
pattern_with_digits_and_delimiter:
|
||||
description: A string starting with 'image_' (case insensitive) and one to three digits following i.e. Image_01.
|
||||
type: string
|
||||
pattern: '/^image_\d{1,3}$/i'
|
||||
Reference in New Issue
Block a user