Skip to content

Commit accaae5

Browse files
authored
Merge pull request #18 from mattpolzin/anyof-as-oneof
treat anyof as oneof for structure parsing type generation.
2 parents b940506 + 46ba52c commit accaae5

File tree

3 files changed

+137
-2
lines changed

3 files changed

+137
-2
lines changed

Sources/JSONAPISwiftGen/Swift Generators/ResourceObjectSwiftGen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public struct ResourceObjectSwiftGen: JSONSchemaSwiftGenerator, ResourceTypeSwif
286286
let dependencies: [Decl]
287287

288288
switch schema {
289-
case .object, .one:
289+
case .object, .one, .any:
290290
let structureGen = try StructureSwiftGen(
291291
swiftTypeName: typeCased(name),
292292
structure: schema,

Sources/JSONAPISwiftGen/Swift Generators/StructureSwiftGen.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ public struct StructureSwiftGen: JSONSchemaSwiftGenerator {
5151
rootConformances: rootConformances
5252
)
5353
]
54-
case .one(of: let schemas, core: _):
54+
// NOTE: This is not a great place to treat "anyOf" the same way as
55+
// "oneOf" but doing so might successfully parse a specific
56+
// subset of "anyOf"s: those where you can expect one of the
57+
// cases to succeed completely but just happen to have overlapping
58+
// success cases -- even then, you may end up with a Poly that
59+
// successfully parses fewer than all of an encoded resource because
60+
// of two applicable "anyOf" branches the less inclusive one came first.
61+
case .one(of: let schemas, core: _), .any(of: let schemas, core: _):
5562
let poly = try StructureSwiftGen.structure(
5663
named: typeName,
5764
forOneOf: schemas,

Tests/JSONAPISwiftGenTests/ResourceObjectSwiftGenTests.swift

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class ResourceObjectSwiftGenTests: XCTestCase {
7171
}
7272

7373
func test_polyAttribute() throws {
74+
// test oneOf in simplest case
7475
let openAPIStructure = try testDecoder.decode(
7576
JSONSchema.self,
7677
from: """
@@ -109,6 +110,133 @@ class ResourceObjectSwiftGenTests: XCTestCase {
109110

110111
print(polyAttrSwiftGen.swiftCode)
111112
}
113+
114+
func test_polyAttribute2() throws {
115+
// test oneOf with type & nullable at root
116+
let openAPIStructure = try testDecoder.decode(
117+
JSONSchema.self,
118+
from: """
119+
{
120+
"type": "object",
121+
"properties": {
122+
"type": {"type": "string", "enum": ["poly_thing"]},
123+
"id": {"type": "string"},
124+
"attributes": {
125+
"type": "object",
126+
"properties": {
127+
"poly_property": {
128+
"type": "object",
129+
"nullable": true,
130+
"oneOf": [
131+
{
132+
"type": "object",
133+
"title": "Widget",
134+
"additionalProperties": false,
135+
"nullable": true,
136+
"required": [
137+
"prop"
138+
],
139+
"properties": {
140+
"prop": {
141+
"type": "string",
142+
"enum": [
143+
"yes",
144+
"no"
145+
]
146+
},
147+
"reasoning": {
148+
"type": "string",
149+
"nullable": true
150+
}
151+
}
152+
},
153+
{
154+
"type": "object",
155+
"title": "Cog",
156+
"additionalProperties": false,
157+
"required": [
158+
"built"
159+
],
160+
"properties": {
161+
"built": {
162+
"type": "boolean"
163+
}
164+
}
165+
}
166+
]
167+
}
168+
}
169+
}
170+
}
171+
}
172+
""".data(using: .utf8)!
173+
).dereferenced()!
174+
175+
let polyAttrSwiftGen = try ResourceObjectSwiftGen(structure: openAPIStructure)
176+
177+
XCTAssertEqual(polyAttrSwiftGen.resourceTypeName, "PolyThing")
178+
179+
print(polyAttrSwiftGen.swiftCode)
180+
}
181+
182+
func test_polyAttribute3() throws {
183+
// test anyOf as Poly
184+
let openAPIStructure = try testDecoder.decode(
185+
JSONSchema.self,
186+
from: """
187+
{
188+
"type": "object",
189+
"properties": {
190+
"type": {"type": "string", "enum": ["poly_thing"]},
191+
"id": {"type": "string"},
192+
"attributes": {
193+
"type": "object",
194+
"properties": {
195+
"poly_property": {
196+
"type": "object",
197+
"nullable": true,
198+
"anyOf": [
199+
{
200+
"type": "object",
201+
"title": "Metadata 1",
202+
"additionalProperties": true,
203+
"nullable": true,
204+
"properties": {
205+
"title": {
206+
"type": "string",
207+
"description": "title"
208+
}
209+
}
210+
},
211+
{
212+
"type": "object",
213+
"title": "Metadata 2",
214+
"additionalProperties": true,
215+
"properties": {
216+
"title": {
217+
"type": "string",
218+
"description": "title"
219+
},
220+
"is_starred": {
221+
"type": "boolean"
222+
}
223+
}
224+
}
225+
]
226+
}
227+
}
228+
}
229+
}
230+
}
231+
""".data(using: .utf8)!
232+
).dereferenced()!
233+
234+
let polyAttrSwiftGen = try ResourceObjectSwiftGen(structure: openAPIStructure)
235+
236+
XCTAssertEqual(polyAttrSwiftGen.resourceTypeName, "PolyThing")
237+
238+
print(polyAttrSwiftGen.swiftCode)
239+
}
112240
}
113241

114242
enum TestPersonDescription: JSONAPI.ResourceObjectDescription {

0 commit comments

Comments
 (0)