Skip to content

Commit b79d66f

Browse files
committed
fix: address more PR feedback, add and fix tests
1 parent ff9f164 commit b79d66f

File tree

5 files changed

+69
-46
lines changed

5 files changed

+69
-46
lines changed

src/Microsoft.OpenApi/Extensions/OpenApiTypeMapper.cs

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ public static class OpenApiTypeMapper
2020
/// </summary>
2121
/// <param name="schemaType"></param>
2222
/// <returns></returns>
23-
public static string[]? ToIdentifier(this JsonSchemaType? schemaType)
23+
public static string[]? ToIdentifiers(this JsonSchemaType? schemaType)
2424
{
2525
if (schemaType is null)
2626
{
2727
return null;
2828
}
29-
return schemaType.Value.ToIdentifier();
29+
return schemaType.Value.ToIdentifiers();
3030
}
3131

3232
/// <summary>
@@ -56,10 +56,24 @@ public static string[] ToIdentifiers(this JsonSchemaType schemaType)
5656
/// <returns></returns>
5757
internal static string ToFirstIdentifier(this JsonSchemaType schemaType)
5858
{
59-
var identifier = schemaType.ToIdentifier();
59+
var identifier = schemaType.ToIdentifiers();
6060
return identifier[0];
6161
}
6262

63+
/// <summary>
64+
/// Returns a single identifier from an array with only one item.
65+
/// </summary>
66+
/// <param name="schemaType"></param>
67+
/// <returns></returns>
68+
public static string ToSingleIdentifier(this JsonSchemaType schemaType)
69+
{
70+
if (schemaType.ToIdentifiers().Length != 1)
71+
{
72+
throw new OpenApiException($"Schema type {schemaType} must have exactly one identifier.");
73+
}
74+
return schemaType.ToFirstIdentifier();
75+
}
76+
6377
#nullable restore
6478

6579
/// <summary>
@@ -185,40 +199,37 @@ public static Type MapOpenApiPrimitiveTypeToSimpleType(this OpenApiSchema schema
185199
{
186200
throw new ArgumentNullException(nameof(schema));
187201
}
188-
var isNullable = (schema.Type & JsonSchemaType.Null) == JsonSchemaType.Null;
189-
var nonNullable = (schema.Type & ~JsonSchemaType.Null)?.FirstIdentifier();
190202

191-
var type = (nonNullable, schema.Format?.ToLowerInvariant(), isNullable) switch
203+
var type = (schema.Type, schema.Format?.ToLowerInvariant()) switch
192204
{
193-
("integer" or "number", "int32", true) => typeof(int?),
194-
("integer" or "number", "int64", true) => typeof(long?),
195-
("integer", null, true) => typeof(long?),
196-
("number", "float", true) => typeof(float?),
197-
("number", "double", true) => typeof(double?),
198-
("number", null, true) => typeof(double?),
199-
("number", "decimal", true) => typeof(decimal?),
200-
("string", "byte", true) => typeof(byte?),
201-
("string", "date-time", true) => typeof(DateTimeOffset?),
202-
("string", "uuid", true) => typeof(Guid?),
203-
("string", "char", true) => typeof(char?),
204-
("boolean", null, true) => typeof(bool?),
205-
("boolean", null, _) => typeof(bool),
205+
(JsonSchemaType.Integer | JsonSchemaType.Null or JsonSchemaType.Number | JsonSchemaType.Null, "int32") => typeof(int?),
206+
(JsonSchemaType.Integer | JsonSchemaType.Null or JsonSchemaType.Number | JsonSchemaType.Null, "int64") => typeof(long?),
207+
(JsonSchemaType.Integer | JsonSchemaType.Null, null) => typeof(long?),
208+
(JsonSchemaType.Number | JsonSchemaType.Null, "float") => typeof(float?),
209+
(JsonSchemaType.Number | JsonSchemaType.Null, "double") => typeof(double?),
210+
(JsonSchemaType.Number | JsonSchemaType.Null, null) => typeof(double?),
211+
(JsonSchemaType.Number | JsonSchemaType.Null, "decimal") => typeof(decimal?),
212+
(JsonSchemaType.String | JsonSchemaType.Null, "byte") => typeof(byte?),
213+
(JsonSchemaType.String | JsonSchemaType.Null, "date-time") => typeof(DateTimeOffset?),
214+
(JsonSchemaType.String | JsonSchemaType.Null, "uuid") => typeof(Guid?),
215+
(JsonSchemaType.String | JsonSchemaType.Null, "char") => typeof(char?),
216+
(JsonSchemaType.Boolean | JsonSchemaType.Null, null) => typeof(bool?),
217+
(JsonSchemaType.Boolean, null) => typeof(bool),
206218
// integer is technically not valid with format, but we must provide some compatibility
207-
("integer" or "number", "int32", _) => typeof(int),
208-
("integer" or "number", "int64", _) => typeof(long),
209-
("integer", null, _) => typeof(long),
210-
("number", "float", _) => typeof(float),
211-
("number", "double", _) => typeof(double),
212-
("number", "decimal", _) => typeof(decimal),
213-
("number", null, _) => typeof(double),
214-
("string", "byte", _) => typeof(byte),
215-
("string", "date-time", _) => typeof(DateTimeOffset),
216-
("string", "uuid", _) => typeof(Guid),
217-
("string", "duration", _) => typeof(TimeSpan),
218-
("string", "char", _) => typeof(char),
219-
("string", null, _) => typeof(string),
220-
("object", null, _) => typeof(object),
221-
("string", "uri", _) => typeof(Uri),
219+
(JsonSchemaType.Integer or JsonSchemaType.Number, "int32") => typeof(int),
220+
(JsonSchemaType.Integer or JsonSchemaType.Number, "int64") => typeof(long),
221+
(JsonSchemaType.Integer, null) => typeof(long),
222+
(JsonSchemaType.Number, "float") => typeof(float),
223+
(JsonSchemaType.Number, "double") => typeof(double),
224+
(JsonSchemaType.Number, "decimal") => typeof(decimal),
225+
(JsonSchemaType.Number, null) => typeof(double),
226+
(JsonSchemaType.String, "byte") => typeof(byte),
227+
(JsonSchemaType.String, "date-time") => typeof(DateTimeOffset),
228+
(JsonSchemaType.String, "uuid") => typeof(Guid),
229+
(JsonSchemaType.String, "char") => typeof(char),
230+
(JsonSchemaType.String, null) => typeof(string),
231+
(JsonSchemaType.Object, null) => typeof(object),
232+
(JsonSchemaType.String, "uri") => typeof(Uri),
222233
_ => typeof(string),
223234
};
224235

src/Microsoft.OpenApi/Models/OpenApiSchema.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ internal void WriteJsonSchemaKeywords(IOpenApiWriter writer)
413413
internal void WriteAsItemsProperties(IOpenApiWriter writer)
414414
{
415415
// type
416-
writer.WriteProperty(OpenApiConstants.Type, (Type & ~JsonSchemaType.Null)?.FirstIdentifier());
416+
writer.WriteProperty(OpenApiConstants.Type, (Type & ~JsonSchemaType.Null)?.ToFirstIdentifier());
417417

418418
// format
419419
WriteFormatProperty(writer);
@@ -651,14 +651,14 @@ Extensions is not null &&
651651
break;
652652
case OpenApiSpecVersion.OpenApi3_0 when isNullable && type.Value == JsonSchemaType.Null:
653653
writer.WriteProperty(OpenApiConstants.Nullable, true);
654-
writer.WriteProperty(OpenApiConstants.Type, JsonSchemaType.Object.FirstIdentifier());
654+
writer.WriteProperty(OpenApiConstants.Type, JsonSchemaType.Object.ToFirstIdentifier());
655655
break;
656656
case OpenApiSpecVersion.OpenApi3_0 when isNullable && type.Value != JsonSchemaType.Null:
657657
writer.WriteProperty(OpenApiConstants.Nullable, true);
658-
writer.WriteProperty(OpenApiConstants.Type, type.Value.FirstIdentifier());
658+
writer.WriteProperty(OpenApiConstants.Type, type.Value.ToFirstIdentifier());
659659
break;
660660
default:
661-
writer.WriteProperty(OpenApiConstants.Type, type.Value.FirstIdentifier());
661+
writer.WriteProperty(OpenApiConstants.Type, type.Value.ToFirstIdentifier());
662662
break;
663663
}
664664
}
@@ -676,7 +676,7 @@ where type.Value.HasFlag(flag)
676676
select flag).ToList();
677677
writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) =>
678678
{
679-
foreach(var item in s.ToIdentifier())
679+
foreach(var item in s.ToIdentifiers())
680680
{
681681
w.WriteValue(item);
682682
}
@@ -703,7 +703,7 @@ private static void UpCastSchemaTypeToV31(JsonSchemaType type, IOpenApiWriter wr
703703
var temporaryType = type | JsonSchemaType.Null;
704704
var list = (from JsonSchemaType flag in jsonSchemaTypeValues// Check if the flag is set in 'type' using a bitwise AND operation
705705
where temporaryType.HasFlag(flag)
706-
select flag.FirstIdentifier()).ToList();
706+
select flag.ToFirstIdentifier()).ToList();
707707
if (list.Count > 1)
708708
{
709709
writer.WriteOptionalCollection(OpenApiConstants.Type, list, (w, s) => w.WriteValue(s));
@@ -740,7 +740,7 @@ private void DowncastTypeArrayToV2OrV3(JsonSchemaType schemaType, IOpenApiWriter
740740
if (schemaType.HasFlag(flag) && flag != JsonSchemaType.Null)
741741
{
742742
// Write the non-null flag value to the writer
743-
writer.WriteProperty(OpenApiConstants.Type, flag.FirstIdentifier());
743+
writer.WriteProperty(OpenApiConstants.Type, flag.ToFirstIdentifier());
744744
}
745745
}
746746
writer.WriteProperty(nullableProp, true);
@@ -753,7 +753,7 @@ private void DowncastTypeArrayToV2OrV3(JsonSchemaType schemaType, IOpenApiWriter
753753
}
754754
else
755755
{
756-
writer.WriteProperty(OpenApiConstants.Type, schemaType.FirstIdentifier());
756+
writer.WriteProperty(OpenApiConstants.Type, schemaType.ToFirstIdentifier());
757757
}
758758
}
759759
}

src/Microsoft.OpenApi/Validations/Rules/RuleHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static void ValidateDataTypeMismatch(
5656
// convert value to JsonElement and access the ValueKind property to determine the type.
5757
var valueKind = value.GetValueKind();
5858

59-
var type = (schema.Type & ~JsonSchemaType.Null)?.FirstIdentifier();
59+
var type = (schema.Type & ~JsonSchemaType.Null)?.ToFirstIdentifier();
6060
var format = schema.Format;
6161

6262
// Before checking the type, check first if the schema allows null.

test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiSchemaTests.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Microsoft.OpenApi.Tests;
1616
using Microsoft.OpenApi.Writers;
1717
using Xunit;
18+
using Microsoft.OpenApi.Exceptions;
1819

1920
namespace Microsoft.OpenApi.Readers.Tests.V31Tests
2021
{
@@ -532,7 +533,7 @@ public void NormalizeFlaggableJsonSchemaTypeEnumWorks(JsonSchemaType type, strin
532533
Type = type
533534
};
534535

535-
var actual = schema.Type.ToIdentifier();
536+
var actual = schema.Type.ToIdentifiers();
536537
Assert.Equal(expected, actual);
537538
}
538539

@@ -552,5 +553,15 @@ public void StringIdentifierToEnumConversionWorks()
552553
var actual = "integer".ToJsonSchemaType();
553554
Assert.Equal(JsonSchemaType.Integer, actual);
554555
}
556+
557+
[Fact]
558+
public void ReturnSingleIdentifierWorks()
559+
{
560+
var type = JsonSchemaType.Integer;
561+
var types = JsonSchemaType.Integer | JsonSchemaType.Null;
562+
563+
Assert.Equal("integer", type.ToSingleIdentifier());
564+
Assert.Throws<OpenApiException>(() => types.ToSingleIdentifier());
565+
}
555566
}
556567
}

test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,11 @@ namespace Microsoft.OpenApi.Extensions
190190
{
191191
public static System.Type MapOpenApiPrimitiveTypeToSimpleType(this Microsoft.OpenApi.Models.OpenApiSchema schema) { }
192192
public static Microsoft.OpenApi.Models.OpenApiSchema MapTypeToOpenApiPrimitiveType(this System.Type type) { }
193-
public static string[] ToIdentifier(this Microsoft.OpenApi.Models.JsonSchemaType schemaType) { }
194-
public static string[]? ToIdentifier(this Microsoft.OpenApi.Models.JsonSchemaType? schemaType) { }
193+
public static string[] ToIdentifiers(this Microsoft.OpenApi.Models.JsonSchemaType schemaType) { }
194+
public static string[]? ToIdentifiers(this Microsoft.OpenApi.Models.JsonSchemaType? schemaType) { }
195195
public static Microsoft.OpenApi.Models.JsonSchemaType ToJsonSchemaType(this string identifier) { }
196196
public static Microsoft.OpenApi.Models.JsonSchemaType? ToJsonSchemaType(this string[] identifier) { }
197+
public static string ToSingleIdentifier(this Microsoft.OpenApi.Models.JsonSchemaType schemaType) { }
197198
}
198199
}
199200
namespace Microsoft.OpenApi.Interfaces

0 commit comments

Comments
 (0)