13
13
//===----------------------------------------------------------------------===//
14
14
import OpenAPIKit30
15
15
16
+ /// A result of checking whether a schema is supported.
17
+ enum IsSchemaSupportedResult : Equatable {
18
+
19
+ /// The schema is supported and can be generated.
20
+ case supported
21
+
22
+ /// The reason a schema is unsupported.
23
+ enum UnsupportedReason : Equatable , CustomStringConvertible {
24
+
25
+ /// Describes when no subschemas are found in an allOf, oneOf, or anyOf.
26
+ case noSubschemas
27
+
28
+ /// Describes when the schema is not object-ish, in other words isn't
29
+ /// an object, a ref, or an allOf.
30
+ case notObjectish
31
+
32
+ /// Describes when the schema is not a reference.
33
+ case notRef
34
+
35
+ /// Describes when the schema is of an unsupported schema type.
36
+ case schemaType
37
+
38
+ var description : String {
39
+ switch self {
40
+ case . noSubschemas:
41
+ return " no subschemas "
42
+ case . notObjectish:
43
+ return " not an object-ish schema (object, ref, allOf) "
44
+ case . notRef:
45
+ return " not a reference "
46
+ case . schemaType:
47
+ return " schema type "
48
+ }
49
+ }
50
+ }
51
+
52
+ /// The schema is unsupported for the provided reason.
53
+ case unsupported( reason: UnsupportedReason , schema: JSONSchema )
54
+ }
55
+
16
56
extension FileTranslator {
17
57
18
58
/// Validates that the schema is supported by the generator.
@@ -26,11 +66,17 @@ extension FileTranslator {
26
66
_ schema: JSONSchema ,
27
67
foundIn: String
28
68
) throws -> Bool {
29
- guard try isSchemaSupported ( schema) else {
30
- diagnostics. emitUnsupported ( " Schema " , foundIn: foundIn)
69
+ switch try isSchemaSupported ( schema) {
70
+ case . supported:
71
+ return true
72
+ case . unsupported( reason: let reason, schema: let schema) :
73
+ diagnostics. emitUnsupportedSchema (
74
+ reason: reason. description,
75
+ schema: schema,
76
+ foundIn: foundIn
77
+ )
31
78
return false
32
79
}
33
- return true
34
80
}
35
81
36
82
/// Validates that the schema is supported by the generator.
@@ -44,22 +90,27 @@ extension FileTranslator {
44
90
_ schema: UnresolvedSchema ? ,
45
91
foundIn: String
46
92
) throws -> Bool {
47
- guard try isSchemaSupported ( schema) else {
48
- diagnostics. emitUnsupported ( " Schema " , foundIn: foundIn)
93
+ switch try isSchemaSupported ( schema) {
94
+ case . supported:
95
+ return true
96
+ case . unsupported( reason: let reason, schema: let schema) :
97
+ diagnostics. emitUnsupportedSchema (
98
+ reason: reason. description,
99
+ schema: schema,
100
+ foundIn: foundIn
101
+ )
49
102
return false
50
103
}
51
- return true
52
104
}
53
105
54
- /// Returns a Boolean value that indicates whether the schema is supported.
106
+ /// Returns whether the schema is supported.
55
107
///
56
108
/// If a schema is not supported, no references to it should be emitted.
57
109
/// - Parameters:
58
110
/// - schema: The schema to validate.
59
- /// - Returns: `true` if the schema is supported; `false` otherwise.
60
111
func isSchemaSupported(
61
112
_ schema: JSONSchema
62
- ) throws -> Bool {
113
+ ) throws -> IsSchemaSupportedResult {
63
114
switch schema. value {
64
115
case . string,
65
116
. integer,
@@ -71,31 +122,40 @@ extension FileTranslator {
71
122
// responsible for picking only supported properties.
72
123
. object,
73
124
. fragment:
74
- return true
125
+ return . supported
75
126
case . reference( let ref, _) :
76
127
// reference is supported iff the existing type is supported
77
128
let existingSchema = try components. lookup ( ref)
78
129
return try isSchemaSupported ( existingSchema)
79
130
case . array( _, let array) :
80
131
guard let items = array. items else {
81
132
// an array of fragments is supported
82
- return true
133
+ return . supported
83
134
}
84
135
// an array is supported iff its element schema is supported
85
136
return try isSchemaSupported ( items)
86
137
case . all( of: let schemas, _) :
87
138
guard !schemas. isEmpty else {
88
- return false
139
+ return . unsupported(
140
+ reason: . noSubschemas,
141
+ schema: schema
142
+ )
89
143
}
90
144
return try areObjectishSchemasAndSupported ( schemas)
91
145
case . any( of: let schemas, _) :
92
146
guard !schemas. isEmpty else {
93
- return false
147
+ return . unsupported(
148
+ reason: . noSubschemas,
149
+ schema: schema
150
+ )
94
151
}
95
152
return try areObjectishSchemasAndSupported ( schemas)
96
153
case . one( of: let schemas, let context) :
97
154
guard !schemas. isEmpty else {
98
- return false
155
+ return . unsupported(
156
+ reason: . noSubschemas,
157
+ schema: schema
158
+ )
99
159
}
100
160
// If a discriminator is provided, only refs to object/allOf of
101
161
// object schemas are allowed.
@@ -105,81 +165,104 @@ extension FileTranslator {
105
165
}
106
166
return try areRefsToObjectishSchemaAndSupported ( schemas)
107
167
case . not:
108
- return false
168
+ return . unsupported(
169
+ reason: . schemaType,
170
+ schema: schema
171
+ )
109
172
}
110
173
}
111
174
112
- /// Returns a Boolean value that indicates whether the schema is supported.
175
+ /// Returns a result indicating whether the schema is supported.
113
176
///
114
177
/// If a schema is not supported, no references to it should be emitted.
115
178
/// - Parameters:
116
179
/// - schema: The schema to validate.
117
- /// - Returns: `true` if the schema is supported; `false` otherwise.
118
180
func isSchemaSupported(
119
181
_ schema: UnresolvedSchema ?
120
- ) throws -> Bool {
182
+ ) throws -> IsSchemaSupportedResult {
121
183
guard let schema else {
122
184
// fragment type is supported
123
- return true
185
+ return . supported
124
186
}
125
187
switch schema {
126
188
case . a:
127
189
// references are supported
128
- return true
190
+ return . supported
129
191
case let . b( schema) :
130
192
return try isSchemaSupported ( schema)
131
193
}
132
194
}
133
195
134
- /// Returns a Boolean value that indicates whether the provided schemas
196
+ /// Returns a result indicating whether the provided schemas
135
197
/// are supported.
136
198
/// - Parameter schemas: Schemas to check.
137
- /// - Returns: `true` if all schemas are supported; `false` otherwise.
138
- func areSchemasSupported( _ schemas: [ JSONSchema ] ) throws -> Bool {
139
- try schemas. allSatisfy ( isSchemaSupported)
199
+ func areSchemasSupported( _ schemas: [ JSONSchema ] ) throws -> IsSchemaSupportedResult {
200
+ for schema in schemas {
201
+ let result = try isSchemaSupported ( schema)
202
+ guard result == . supported else {
203
+ return result
204
+ }
205
+ }
206
+ return . supported
140
207
}
141
208
142
- /// Returns a Boolean value that indicates whether the provided schemas
209
+ /// Returns a result indicating whether the provided schemas
143
210
/// are reference, object, or allOf schemas and supported.
144
211
/// - Parameter schemas: Schemas to check.
145
- /// - Returns: `true` if all schemas match; `false` otherwise.
146
- func areObjectishSchemasAndSupported( _ schemas: [ JSONSchema ] ) throws -> Bool {
147
- try schemas. allSatisfy ( isObjectishSchemaAndSupported)
212
+ /// - Returns: `.supported` if all schemas match; `.unsupported` otherwise.
213
+ func areObjectishSchemasAndSupported( _ schemas: [ JSONSchema ] ) throws -> IsSchemaSupportedResult {
214
+ for schema in schemas {
215
+ let result = try isObjectishSchemaAndSupported ( schema)
216
+ guard result == . supported else {
217
+ return result
218
+ }
219
+ }
220
+ return . supported
148
221
}
149
222
150
- /// Returns a Boolean value that indicates whether the provided schema
223
+ /// Returns a result indicating whether the provided schema
151
224
/// is an reference, object, or allOf (object-ish) schema and is supported.
152
225
/// - Parameter schema: A schemas to check.
153
- /// - Returns: `true` if the schema matches; `false` otherwise.
154
- func isObjectishSchemaAndSupported( _ schema: JSONSchema ) throws -> Bool {
226
+ func isObjectishSchemaAndSupported( _ schema: JSONSchema ) throws -> IsSchemaSupportedResult {
155
227
switch schema. value {
156
228
case . object, . reference:
157
229
return try isSchemaSupported ( schema)
158
230
case . all( of: let schemas, _) :
159
231
return try areObjectishSchemasAndSupported ( schemas)
160
232
default :
161
- return false
233
+ return . unsupported(
234
+ reason: . notObjectish,
235
+ schema: schema
236
+ )
162
237
}
163
238
}
164
239
165
- /// Returns a Boolean value that indicates whether the provided schemas
240
+ /// Returns a result indicating whether the provided schemas
166
241
/// are reference schemas that point to object-ish schemas and supported.
167
242
/// - Parameter schemas: Schemas to check.
168
- /// - Returns: `true` if all schemas match; `false` otherwise.
169
- func areRefsToObjectishSchemaAndSupported( _ schemas: [ JSONSchema ] ) throws -> Bool {
170
- try schemas. allSatisfy ( isRefToObjectishSchemaAndSupported)
243
+ /// - Returns: `.supported` if all schemas match; `.unsupported` otherwise.
244
+ func areRefsToObjectishSchemaAndSupported( _ schemas: [ JSONSchema ] ) throws -> IsSchemaSupportedResult {
245
+ for schema in schemas {
246
+ let result = try isRefToObjectishSchemaAndSupported ( schema)
247
+ guard result == . supported else {
248
+ return result
249
+ }
250
+ }
251
+ return . supported
171
252
}
172
253
173
- /// Returns a Boolean value that indicates whether the provided schema
254
+ /// Returns a result indicating whether the provided schema
174
255
/// is a reference schema that points to an object-ish schema and is supported.
175
256
/// - Parameter schema: A schema to check.
176
- /// - Returns: `true` if the schema matches; `false` otherwise.
177
- func isRefToObjectishSchemaAndSupported( _ schema: JSONSchema ) throws -> Bool {
257
+ func isRefToObjectishSchemaAndSupported( _ schema: JSONSchema ) throws -> IsSchemaSupportedResult {
178
258
switch schema. value {
179
259
case . reference:
180
260
return try isObjectishSchemaAndSupported ( schema)
181
261
default :
182
- return false
262
+ return . unsupported(
263
+ reason: . notRef,
264
+ schema: schema
265
+ )
183
266
}
184
267
}
185
268
}
0 commit comments