33
44using System ;
55using System . Collections . Generic ;
6+ using Microsoft . OpenApi . Exceptions ;
67using Microsoft . OpenApi . Models ;
78
89namespace Microsoft . OpenApi . Extensions
@@ -12,40 +13,81 @@ namespace Microsoft.OpenApi.Extensions
1213 /// </summary>
1314 public static class OpenApiTypeMapper
1415 {
16+ /// <summary>
17+ /// Maps a JsonSchema data type to an identifier.
18+ /// </summary>
19+ /// <param name="schemaType"></param>
20+ /// <returns></returns>
21+ public static string ToIdentifier ( this JsonSchemaType ? schemaType )
22+ {
23+ return schemaType switch
24+ {
25+ JsonSchemaType . Null => "null" ,
26+ JsonSchemaType . Boolean => "boolean" ,
27+ JsonSchemaType . Integer => "integer" ,
28+ JsonSchemaType . Number => "number" ,
29+ JsonSchemaType . String => "string" ,
30+ JsonSchemaType . Array => "array" ,
31+ JsonSchemaType . Object => "object" ,
32+ _ => null ,
33+ } ;
34+ }
35+
36+ /// <summary>
37+ /// Converts a schema type's identifier into the enum equivalent
38+ /// </summary>
39+ /// <param name="identifier"></param>
40+ /// <returns></returns>
41+ public static JsonSchemaType ToJsonSchemaType ( this string identifier )
42+ {
43+ return identifier switch
44+ {
45+ "null" => JsonSchemaType . Null ,
46+ "boolean" => JsonSchemaType . Boolean ,
47+ "integer" or "int" => JsonSchemaType . Integer ,
48+ "number" or "double" or "float" or "decimal" => JsonSchemaType . Number ,
49+ "string" => JsonSchemaType . String ,
50+ "array" => JsonSchemaType . Array ,
51+ "object" => JsonSchemaType . Object ,
52+ "file" => JsonSchemaType . String , // File is treated as string
53+ _ => throw new OpenApiException ( string . Format ( "Invalid schema type identifier: {0}" , identifier ) )
54+ } ;
55+ }
56+
1557 private static readonly Dictionary < Type , Func < OpenApiSchema > > _simpleTypeToOpenApiSchema = new ( )
1658 {
17- [ typeof ( bool ) ] = ( ) => new ( ) { Type = "boolean" } ,
18- [ typeof ( byte ) ] = ( ) => new ( ) { Type = "string" , Format = "byte" } ,
19- [ typeof ( int ) ] = ( ) => new ( ) { Type = "number" , Format = "int32" } ,
20- [ typeof ( uint ) ] = ( ) => new ( ) { Type = "number" , Format = "int32" } ,
21- [ typeof ( long ) ] = ( ) => new ( ) { Type = "number" , Format = "int64" } ,
22- [ typeof ( ulong ) ] = ( ) => new ( ) { Type = "number" , Format = "int64" } ,
23- [ typeof ( float ) ] = ( ) => new ( ) { Type = "number" , Format = "float" } ,
24- [ typeof ( double ) ] = ( ) => new ( ) { Type = "number" , Format = "double" } ,
25- [ typeof ( decimal ) ] = ( ) => new ( ) { Type = "number" , Format = "double" } ,
26- [ typeof ( DateTime ) ] = ( ) => new ( ) { Type = "string" , Format = "date-time" } ,
27- [ typeof ( DateTimeOffset ) ] = ( ) => new ( ) { Type = "string" , Format = "date-time" } ,
28- [ typeof ( Guid ) ] = ( ) => new ( ) { Type = "string" , Format = "uuid" } ,
29- [ typeof ( char ) ] = ( ) => new ( ) { Type = "string" } ,
59+ [ typeof ( bool ) ] = ( ) => new ( ) { Type = JsonSchemaType . Boolean } ,
60+ [ typeof ( byte ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "byte" } ,
61+ [ typeof ( int ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int32" } ,
62+ [ typeof ( uint ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int32" } ,
63+ [ typeof ( long ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int64" } ,
64+ [ typeof ( ulong ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int64" } ,
65+ [ typeof ( float ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "float" } ,
66+ [ typeof ( double ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "double" } ,
67+ [ typeof ( decimal ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "double" } ,
68+ [ typeof ( DateTime ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "date-time" } ,
69+ [ typeof ( DateTimeOffset ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "date-time" } ,
70+ [ typeof ( Guid ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "uuid" } ,
71+ [ typeof ( char ) ] = ( ) => new ( ) { Type = JsonSchemaType . String } ,
3072
3173 // Nullable types
32- [ typeof ( bool ? ) ] = ( ) => new ( ) { Type = "boolean" , Nullable = true } ,
33- [ typeof ( byte ? ) ] = ( ) => new ( ) { Type = "string" , Format = "byte" , Nullable = true } ,
34- [ typeof ( int ? ) ] = ( ) => new ( ) { Type = "number" , Format = "int32" , Nullable = true } ,
35- [ typeof ( uint ? ) ] = ( ) => new ( ) { Type = "number" , Format = "int32" , Nullable = true } ,
36- [ typeof ( long ? ) ] = ( ) => new ( ) { Type = "number" , Format = "int64" , Nullable = true } ,
37- [ typeof ( ulong ? ) ] = ( ) => new ( ) { Type = "number" , Format = "int64" , Nullable = true } ,
38- [ typeof ( float ? ) ] = ( ) => new ( ) { Type = "number" , Format = "float" , Nullable = true } ,
39- [ typeof ( double ? ) ] = ( ) => new ( ) { Type = "number" , Format = "double" , Nullable = true } ,
40- [ typeof ( decimal ? ) ] = ( ) => new ( ) { Type = "number" , Format = "double" , Nullable = true } ,
41- [ typeof ( DateTime ? ) ] = ( ) => new ( ) { Type = "string" , Format = "date-time" , Nullable = true } ,
42- [ typeof ( DateTimeOffset ? ) ] = ( ) => new ( ) { Type = "string" , Format = "date-time" , Nullable = true } ,
43- [ typeof ( Guid ? ) ] = ( ) => new ( ) { Type = "string" , Format = "uuid" , Nullable = true } ,
44- [ typeof ( char ? ) ] = ( ) => new ( ) { Type = "string" , Nullable = true } ,
74+ [ typeof ( bool ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Boolean , Nullable = true } ,
75+ [ typeof ( byte ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "byte" , Nullable = true } ,
76+ [ typeof ( int ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int32" , Nullable = true } ,
77+ [ typeof ( uint ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int32" , Nullable = true } ,
78+ [ typeof ( long ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int64" , Nullable = true } ,
79+ [ typeof ( ulong ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Integer , Format = "int64" , Nullable = true } ,
80+ [ typeof ( float ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "float" , Nullable = true } ,
81+ [ typeof ( double ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "double" , Nullable = true } ,
82+ [ typeof ( decimal ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . Number , Format = "double" , Nullable = true } ,
83+ [ typeof ( DateTime ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "date-time" , Nullable = true } ,
84+ [ typeof ( DateTimeOffset ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "date-time" , Nullable = true } ,
85+ [ typeof ( Guid ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "uuid" , Nullable = true } ,
86+ [ typeof ( char ? ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Nullable = true } ,
4587
46- [ typeof ( Uri ) ] = ( ) => new ( ) { Type = "string" , Format = "uri" } , // Uri is treated as simple string
47- [ typeof ( string ) ] = ( ) => new ( ) { Type = "string" } ,
48- [ typeof ( object ) ] = ( ) => new ( ) { Type = "object" }
88+ [ typeof ( Uri ) ] = ( ) => new ( ) { Type = JsonSchemaType . String , Format = "uri" } , // Uri is treated as simple string
89+ [ typeof ( string ) ] = ( ) => new ( ) { Type = JsonSchemaType . String } ,
90+ [ typeof ( object ) ] = ( ) => new ( ) { Type = JsonSchemaType . Object }
4991 } ;
5092
5193 /// <summary>
@@ -79,7 +121,7 @@ public static OpenApiSchema MapTypeToOpenApiPrimitiveType(this Type type)
79121
80122 return _simpleTypeToOpenApiSchema . TryGetValue ( type , out var result )
81123 ? result ( )
82- : new ( ) { Type = "string" } ;
124+ : new ( ) { Type = JsonSchemaType . String } ;
83125 }
84126
85127 /// <summary>
@@ -95,7 +137,7 @@ public static Type MapOpenApiPrimitiveTypeToSimpleType(this OpenApiSchema schema
95137 throw new ArgumentNullException ( nameof ( schema ) ) ;
96138 }
97139
98- var type = ( schema . Type ? . ToString ( ) . ToLowerInvariant ( ) , schema . Format ? . ToLowerInvariant ( ) , schema . Nullable ) switch
140+ var type = ( schema . Type . ToIdentifier ( ) , schema . Format ? . ToLowerInvariant ( ) , schema . Nullable ) switch
99141 {
100142 ( "boolean" , null , false ) => typeof ( bool ) ,
101143 // integer is technically not valid with format, but we must provide some compatibility
0 commit comments