12
12
//
13
13
//===----------------------------------------------------------------------===//
14
14
import OpenAPIKit
15
+ import Foundation
15
16
16
17
/// A set of functions that match Swift types onto OpenAPI types.
17
18
struct TypeMatcher {
@@ -46,7 +47,11 @@ struct TypeMatcher {
46
47
matchedArrayHandler: { elementType, nullableItems in
47
48
nullableItems ? elementType. asOptional. asArray : elementType. asArray
48
49
} ,
49
- genericArrayHandler: { TypeName . arrayContainer. asUsage }
50
+ genericArrayHandler: { TypeName . arrayContainer. asUsage } ,
51
+ substitutedTypeHandler: { substitute in
52
+ // never built-in
53
+ nil
54
+ }
50
55
)
51
56
}
52
57
@@ -75,7 +80,10 @@ struct TypeMatcher {
75
80
matchedArrayHandler: { elementType, nullableItems in
76
81
nullableItems ? elementType. asOptional. asArray : elementType. asArray
77
82
} ,
78
- genericArrayHandler: { TypeName . arrayContainer. asUsage }
83
+ genericArrayHandler: { TypeName . arrayContainer. asUsage } ,
84
+ substitutedTypeHandler: { substitute in
85
+ substitute. asUsage
86
+ }
79
87
) ?
80
88
. withOptional ( isOptional ( schema, components: components) )
81
89
}
@@ -98,7 +106,8 @@ struct TypeMatcher {
98
106
return true
99
107
} ,
100
108
matchedArrayHandler: { elementIsReferenceable, _ in elementIsReferenceable } ,
101
- genericArrayHandler: { true }
109
+ genericArrayHandler: { true } ,
110
+ substitutedTypeHandler: { _ in true }
102
111
) ?? false
103
112
}
104
113
@@ -353,8 +362,10 @@ struct TypeMatcher {
353
362
for schema: JSONSchema . Schema ,
354
363
test: ( JSONSchema . Schema ) throws -> R ? ,
355
364
matchedArrayHandler: ( R , _ nullableItems: Bool ) -> R ,
356
- genericArrayHandler: ( ) -> R
365
+ genericArrayHandler: ( ) -> R ,
366
+ substitutedTypeHandler: ( TypeName ) -> R ?
357
367
) rethrows -> R ? {
368
+ if let substitute = schema. substituteType ( ) { return substitutedTypeHandler ( substitute) }
358
369
switch schema {
359
370
case let . array( _, arrayContext) :
360
371
guard let items = arrayContext. items else { return genericArrayHandler ( ) }
@@ -363,11 +374,39 @@ struct TypeMatcher {
363
374
for: items. value,
364
375
test: test,
365
376
matchedArrayHandler: matchedArrayHandler,
366
- genericArrayHandler: genericArrayHandler
377
+ genericArrayHandler: genericArrayHandler,
378
+ substitutedTypeHandler: substitutedTypeHandler
367
379
)
368
380
else { return nil }
369
381
return matchedArrayHandler ( itemsResult, items. nullable)
370
382
default : return try test ( schema)
371
383
}
372
384
}
373
385
}
386
+
387
+ extension JSONSchema . Schema {
388
+ func substituteType( ) -> TypeName ? {
389
+ let extensions : [ String : AnyCodable ] =
390
+ switch self {
391
+ case . null( let context) : context. vendorExtensions
392
+ case . boolean( let context) : context. vendorExtensions
393
+ case . number( let context, _) : context. vendorExtensions
394
+ case . integer( let context, _) : context. vendorExtensions
395
+ case . string( let context, _) : context. vendorExtensions
396
+ case . object( let context, _) : context. vendorExtensions
397
+ case . array( let context, _) : context. vendorExtensions
398
+ case . all( of: _, core: let context) : context. vendorExtensions
399
+ case . one( of: _, core: let context) : context. vendorExtensions
400
+ case . any( of: _, core: let context) : context. vendorExtensions
401
+ case . not: [ : ]
402
+ case . reference( _, let context) : context. vendorExtensions
403
+ case . fragment( let context) : context. vendorExtensions
404
+ }
405
+ guard let substituteTypeName = extensions [ Constants . VendorExtension. replaceType] ? . value as? String else {
406
+ return nil
407
+ }
408
+ assert ( !substituteTypeName. isEmpty)
409
+
410
+ return TypeName ( swiftKeyPath: substituteTypeName. components ( separatedBy: " . " ) )
411
+ }
412
+ }
0 commit comments