@@ -31,21 +31,37 @@ public struct StructureSwiftGen: JSONSchemaSwiftGenerator {
3131 cascadingConformances: [ String ] = [ ] ,
3232 rootConformances: [ String ] ? = nil
3333 ) throws {
34- guard case . object( _, let context) = structure else {
35- throw Error . rootNotJSONObject
34+ let typeName : String
35+ if reservedTypeNames. contains ( swiftTypeName) {
36+ typeName = " Gen " + swiftTypeName
37+ } else {
38+ typeName = swiftTypeName
3639 }
3740
38- self . swiftTypeName = swiftTypeName
41+ self . swiftTypeName = typeName
3942 self . structure = structure
4043
41- decls = [
42- try StructureSwiftGen . structure (
43- named: swiftTypeName,
44- forObject: context,
44+ switch structure {
45+ case . object( _, let context) :
46+ decls = [
47+ try StructureSwiftGen . structure (
48+ named: typeName,
49+ forObject: context,
50+ cascadingConformances: cascadingConformances,
51+ rootConformances: rootConformances
52+ )
53+ ]
54+ case . one( of: let schemas, core: _) :
55+ let poly = try StructureSwiftGen . structure (
56+ named: typeName,
57+ forOneOf: schemas,
4558 cascadingConformances: cascadingConformances,
4659 rootConformances: rootConformances
4760 )
48- ]
61+ decls = [ poly. polyDecl] + poly. dependencies
62+ default :
63+ throw Error . rootNotJSONObject
64+ }
4965 }
5066
5167 static func structure(
@@ -72,6 +88,40 @@ public struct StructureSwiftGen: JSONSchemaSwiftGenerator {
7288 )
7389 }
7490
91+ static func structure(
92+ named name: String ,
93+ forOneOf schemas: [ DereferencedJSONSchema ] ,
94+ cascadingConformances: [ String ] ,
95+ rootConformances: [ String ] ? = nil
96+ ) throws -> ( polyDecl: Decl , dependencies: [ Decl ] ) {
97+ let dependencies = try schemas
98+ . enumerated ( )
99+ . map { ( idx, schema) -> ( String , [ Decl ] ) in
100+ let name = typeCased ( " Poly \( name) \( idx) " )
101+ return (
102+ name,
103+ try declsForType (
104+ named: name,
105+ for: schema,
106+ conformances: cascadingConformances
107+ )
108+ )
109+ }
110+
111+ let poly = Typealias (
112+ alias: . def( . init( name: name) ) ,
113+ existingType: . def(
114+ . init(
115+ name: " Poly \( dependencies. count) " ,
116+ specializationReps: dependencies. map { . def( . init( name: $0. 0 ) ) } ,
117+ optional: false
118+ )
119+ )
120+ )
121+
122+ return ( polyDecl: poly, dependencies: dependencies. flatMap ( \. 1 ) )
123+ }
124+
75125 static func structure(
76126 named name: String ,
77127 forArray context: DereferencedJSONSchema . ArrayContext ,
@@ -91,6 +141,70 @@ public struct StructureSwiftGen: JSONSchemaSwiftGenerator {
91141 )
92142 }
93143
144+ /// Create the decls needed to represent the structures in use
145+ /// by a PolyX.
146+ static func declsForType(
147+ named name: String ,
148+ for schema: DereferencedJSONSchema ,
149+ conformances: [ String ]
150+ ) throws -> [ Decl ] {
151+ let type : SwiftTypeRep
152+ let structureDecl : Decl ?
153+
154+ do {
155+ type = try swiftType ( from: schema, allowPlaceholders: false )
156+ structureDecl = nil
157+ } catch {
158+ switch schema {
159+ case . object( let context, let objContext) :
160+ let newTypeName = typeCased ( name)
161+
162+ // TODO: ideally distinguish between these
163+ // but that requires generating Swift code
164+ // for custom encoding/decoding
165+ let optional = !context. required || context. nullable
166+
167+ let typeIntermediate = SwiftTypeRep . def ( . init( name: newTypeName) )
168+
169+ type = optional ? typeIntermediate. optional : typeIntermediate
170+
171+ structureDecl = try structure (
172+ named: newTypeName,
173+ forObject: objContext,
174+ cascadingConformances: conformances
175+ )
176+
177+ case . array( let context, let arrayContext) :
178+ let newTypeName = typeCased ( name)
179+
180+ // TODO: ideally distinguish between these
181+ // but that requires generating Swift code
182+ // for custom encoding/decoding
183+ let optional = !context. required || context. nullable
184+
185+ let typeIntermediate = SwiftTypeRep . def ( SwiftTypeDef ( name: newTypeName) . array)
186+
187+ type = optional ? typeIntermediate. optional : typeIntermediate
188+
189+ structureDecl = try structure (
190+ named: newTypeName,
191+ forArray: arrayContext,
192+ conformances: conformances
193+ )
194+ default :
195+ throw SwiftTypeError . typeNotFound
196+ }
197+ }
198+ return [
199+ structureDecl ?? Typealias (
200+ alias: . def( . init( name: name) ) ,
201+ existingType: type
202+ )
203+ ] . compactMap { $0 }
204+ }
205+
206+ /// Create the decls needed to represent the substructure of
207+ /// a property with the given name.
94208 static func declsForProp(
95209 named name: String ,
96210 for schema: DereferencedJSONSchema ,
0 commit comments