Skip to content

Commit

Permalink
Adds support for Int128 and UInt128 and unify STJ and Newtonsoft Prim…
Browse files Browse the repository at this point in the history
…itive types and formats lookup dictionary to reduce code duplication. Fixes domaindrivendev#2611 for #3
  • Loading branch information
Havunen committed Feb 24, 2024
1 parent 9956c87 commit b39f252
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public DataContract GetDataContractForType(Type type)

if (jsonContract is JsonPrimitiveContract && !jsonContract.UnderlyingType.IsEnum)
{
var primitiveTypeAndFormat = PrimitiveTypesAndFormats.TryGetValue(jsonContract.UnderlyingType, out var format)
var primitiveTypeAndFormat = CommonFormats.PrimitiveTypesAndFormats.TryGetValue(jsonContract.UnderlyingType, out var format)
? format
: Tuple.Create(DataType.String, (string)null);

Expand All @@ -53,8 +53,8 @@ public DataContract GetDataContractForType(Type type)
&& JsonConverterFunc(enumValues.GetValue(0)).StartsWith("\"");

var primitiveTypeAndFormat = serializeAsString
? PrimitiveTypesAndFormats[typeof(string)]
: PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()];
? CommonFormats.PrimitiveTypesAndFormats[typeof(string)]
: CommonFormats.PrimitiveTypesAndFormats[jsonContract.UnderlyingType.GetEnumUnderlyingType()];

return DataContract.ForPrimitive(
underlyingType: jsonContract.UnderlyingType,
Expand Down Expand Up @@ -183,50 +183,5 @@ private IEnumerable<DataProperty> GetDataPropertiesFor(JsonObjectContract jsonOb

return dataProperties;
}

private static readonly Dictionary<Type, Tuple<DataType, string>> PrimitiveTypesAndFormats = new Dictionary<Type, Tuple<DataType, string>>
{
[typeof(bool)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(bool?)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(byte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(byte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(long)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(long?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(float)] = Tuple.Create(DataType.Number, "float"),
[typeof(float?)] = Tuple.Create(DataType.Number, "float"),
[typeof(double)] = Tuple.Create(DataType.Number, "double"),
[typeof(double?)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal?)] = Tuple.Create(DataType.Number, "double"),
[typeof(byte[])] = Tuple.Create(DataType.String, "byte"),
[typeof(string)] = Tuple.Create(DataType.String, (string)null),
[typeof(char)] = Tuple.Create(DataType.String, (string)null),
[typeof(char?)] = Tuple.Create(DataType.String, (string)null),
[typeof(DateTime)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTime?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(Guid)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Guid?)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Uri)] = Tuple.Create(DataType.String, "uri"),
[typeof(TimeSpan)] = Tuple.Create(DataType.String, "date-span"),
[typeof(TimeSpan?)] = Tuple.Create(DataType.String, "date-span"),
[typeof(DateOnly)] = Tuple.Create(DataType.String, "date"),
[typeof(DateOnly?)] = Tuple.Create(DataType.String, "date"),
[typeof(TimeOnly)] = Tuple.Create(DataType.String, "time"),
[typeof(TimeOnly?)] = Tuple.Create(DataType.String, "time")
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public DataContract GetDataContractForType(Type type)
jsonConverter: JsonConverterFunc);
}

if (PrimitiveTypesAndFormats.TryGetValue(type, out var primitiveTypeAndFormat1))
if (CommonFormats.PrimitiveTypesAndFormats.TryGetValue(type, out var primitiveTypeAndFormat1))
{
return DataContract.ForPrimitive(
underlyingType: type,
Expand All @@ -44,8 +44,8 @@ public DataContract GetDataContractForType(Type type)
&& JsonConverterFunc(enumValues.GetValue(0)).StartsWith("\"");

var primitiveTypeAndFormat = serializeAsString
? PrimitiveTypesAndFormats[typeof(string)]
: PrimitiveTypesAndFormats[type.GetEnumUnderlyingType()];
? CommonFormats.PrimitiveTypesAndFormats[typeof(string)]
: CommonFormats.PrimitiveTypesAndFormats[type.GetEnumUnderlyingType()];

return DataContract.ForPrimitive(
underlyingType: type,
Expand Down Expand Up @@ -211,48 +211,5 @@ private IEnumerable<DataProperty> GetDataPropertiesFor(Type objectType, out Type

return dataProperties;
}

private static readonly Dictionary<Type, Tuple<DataType, string>> PrimitiveTypesAndFormats = new Dictionary<Type, Tuple<DataType, string>>
{
[typeof(bool)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(bool?)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(byte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(byte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(long)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(long?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(float)] = Tuple.Create(DataType.Number, "float"),
[typeof(float?)] = Tuple.Create(DataType.Number, "float"),
[typeof(double)] = Tuple.Create(DataType.Number, "double"),
[typeof(double?)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal?)] = Tuple.Create(DataType.Number, "double"),
[typeof(byte[])] = Tuple.Create(DataType.String, "byte"),
[typeof(string)] = Tuple.Create(DataType.String, (string)null),
[typeof(char)] = Tuple.Create(DataType.String, (string)null),
[typeof(char?)] = Tuple.Create(DataType.String, (string)null),
[typeof(DateTime)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTime?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(Guid)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Guid?)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Uri)] = Tuple.Create(DataType.String, "uri"),
[typeof(DateOnly)] = Tuple.Create(DataType.String, "date"),
[typeof(DateOnly?)] = Tuple.Create(DataType.String, "date"),
[typeof(TimeOnly)] = Tuple.Create(DataType.String, "time"),
[typeof(TimeOnly?)] = Tuple.Create(DataType.String, "time")
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;

namespace DotSwashbuckle.AspNetCore.SwaggerGen
{
public static class CommonFormats
{
public static readonly IReadOnlyDictionary<Type, Tuple<DataType, string>> PrimitiveTypesAndFormats = new Dictionary<Type, Tuple<DataType, string>>
{
[typeof(bool)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(bool?)] = Tuple.Create(DataType.Boolean, (string)null),
[typeof(byte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(byte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(sbyte?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(short?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(ushort?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(int?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(uint?)] = Tuple.Create(DataType.Integer, "int32"),
[typeof(long)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(long?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(ulong?)] = Tuple.Create(DataType.Integer, "int64"),
[typeof(Int128)] = Tuple.Create(DataType.Integer, "int128"),
[typeof(Int128?)] = Tuple.Create(DataType.Integer, "int128"),
[typeof(UInt128)] = Tuple.Create(DataType.Integer, "int128"),
[typeof(UInt128?)] = Tuple.Create(DataType.Integer, "int128"),
[typeof(Version)] = Tuple.Create(DataType.String, (string)null),
[typeof(float)] = Tuple.Create(DataType.Number, "float"),
[typeof(float?)] = Tuple.Create(DataType.Number, "float"),
[typeof(double)] = Tuple.Create(DataType.Number, "double"),
[typeof(double?)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal)] = Tuple.Create(DataType.Number, "double"),
[typeof(decimal?)] = Tuple.Create(DataType.Number, "double"),
[typeof(byte[])] = Tuple.Create(DataType.String, "byte"),
[typeof(string)] = Tuple.Create(DataType.String, (string)null),
[typeof(char)] = Tuple.Create(DataType.String, (string)null),
[typeof(char?)] = Tuple.Create(DataType.String, (string)null),
[typeof(DateTime)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTime?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset)] = Tuple.Create(DataType.String, "date-time"),
[typeof(DateTimeOffset?)] = Tuple.Create(DataType.String, "date-time"),
[typeof(Guid)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Guid?)] = Tuple.Create(DataType.String, "uuid"),
[typeof(Uri)] = Tuple.Create(DataType.String, "uri"),
[typeof(TimeSpan)] = Tuple.Create(DataType.String, "date-span"),
[typeof(TimeSpan?)] = Tuple.Create(DataType.String, "date-span"),
[typeof(DateOnly)] = Tuple.Create(DataType.String, "date"),
[typeof(DateOnly?)] = Tuple.Create(DataType.String, "date"),
[typeof(TimeOnly)] = Tuple.Create(DataType.String, "time"),
[typeof(TimeOnly?)] = Tuple.Create(DataType.String, "time")
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public void GenerateSchema_GeneratesFileSchema_IfFormFileOrFileResultType(Type t
[InlineData(typeof(float), "number", "float", false)]
[InlineData(typeof(double), "number", "double", false)]
[InlineData(typeof(decimal), "number", "double", false)]
[InlineData(typeof(Int128), "integer", "int128", false)]
[InlineData(typeof(UInt128), "integer", "int128", false)]
[InlineData(typeof(string), "string", null, false)]
[InlineData(typeof(char), "string", null, false)]
[InlineData(typeof(byte[]), "string", "byte", false)]
Expand All @@ -63,6 +65,8 @@ public void GenerateSchema_GeneratesFileSchema_IfFormFileOrFileResultType(Type t
[InlineData(typeof(Version), "string", null, false)]
[InlineData(typeof(bool?), "boolean", null, true)]
[InlineData(typeof(int?), "integer", "int32", true)]
[InlineData(typeof(Int128?), "integer", "int128", true)]
[InlineData(typeof(UInt128?), "integer", "int128", true)]
[InlineData(typeof(DateTime?), "string", "date-time", true)]
public void GenerateSchema_GeneratesPrimitiveSchema_IfPrimitiveOrNullablePrimitiveType(
Type type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,42 +44,44 @@ public void GenerateSchema_GeneratesFileSchema_IfFormFileOrFileResultType(Type t
}

[Theory]
[InlineData(typeof(bool), "boolean", null)]
[InlineData(typeof(byte), "integer", "int32")]
[InlineData(typeof(sbyte), "integer", "int32")]
[InlineData(typeof(short), "integer", "int32")]
[InlineData(typeof(ushort), "integer", "int32")]
[InlineData(typeof(int), "integer", "int32")]
[InlineData(typeof(uint), "integer", "int32")]
[InlineData(typeof(long), "integer", "int64")]
[InlineData(typeof(ulong), "integer", "int64")]
[InlineData(typeof(float), "number", "float")]
[InlineData(typeof(double), "number", "double")]
[InlineData(typeof(decimal), "number", "double")]
[InlineData(typeof(string), "string", null)]
[InlineData(typeof(char), "string", null)]
[InlineData(typeof(byte[]), "string", "byte")]
[InlineData(typeof(DateTime), "string", "date-time")]
[InlineData(typeof(DateTimeOffset), "string", "date-time")]
[InlineData(typeof(Guid), "string", "uuid")]
[InlineData(typeof(Uri), "string", "uri")]
[InlineData(typeof(DateOnly), "string", "date")]
[InlineData(typeof(TimeOnly), "string", "time")]
[InlineData(typeof(bool?), "boolean", null)]
[InlineData(typeof(int?), "integer", "int32")]
[InlineData(typeof(DateTime?), "string", "date-time")]
[InlineData(typeof(Guid?), "string", "uuid")]
[InlineData(typeof(DateOnly?), "string", "date")]
[InlineData(typeof(TimeOnly?), "string", "time")]
[InlineData(typeof(byte), "integer", "int32", false)]
[InlineData(typeof(sbyte), "integer", "int32", false)]
[InlineData(typeof(short), "integer", "int32", false)]
[InlineData(typeof(ushort), "integer", "int32", false)]
[InlineData(typeof(int), "integer", "int32", false)]
[InlineData(typeof(uint), "integer", "int32", false)]
[InlineData(typeof(long), "integer", "int64", false)]
[InlineData(typeof(ulong), "integer", "int64", false)]
[InlineData(typeof(float), "number", "float", false)]
[InlineData(typeof(double), "number", "double", false)]
[InlineData(typeof(decimal), "number", "double", false)]
[InlineData(typeof(Int128), "integer", "int128", false)]
[InlineData(typeof(UInt128), "integer", "int128", false)]
[InlineData(typeof(string), "string", null, false)]
[InlineData(typeof(char), "string", null, false)]
[InlineData(typeof(byte[]), "string", "byte", false)]
[InlineData(typeof(DateTime), "string", "date-time", false)]
[InlineData(typeof(DateTimeOffset), "string", "date-time", false)]
[InlineData(typeof(Guid), "string", "uuid", false)]
[InlineData(typeof(TimeSpan), "string", "date-span", false)]
[InlineData(typeof(Version), "string", null, false)]
[InlineData(typeof(bool?), "boolean", null, true)]
[InlineData(typeof(int?), "integer", "int32", true)]
[InlineData(typeof(Int128?), "integer", "int128", true)]
[InlineData(typeof(UInt128?), "integer", "int128", true)]
[InlineData(typeof(DateTime?), "string", "date-time", true)]
public void GenerateSchema_GeneratesPrimitiveSchema_IfPrimitiveOrNullablePrimitiveType(
Type type,
string expectedSchemaType,
string expectedFormat)
string expectedFormat,
bool expectedNullable
)
{
var schema = Subject().GenerateSchema(type, new SchemaRepository());

Assert.Equal(expectedSchemaType, schema.Type);
Assert.Equal(expectedFormat, schema.Format);
Assert.Equal(expectedNullable, schema.Nullable);
}

[Theory]
Expand Down

0 comments on commit b39f252

Please sign in to comment.