Skip to content

Commit fe0d74d

Browse files
committed
slight refactor and addition of a new type of document generator
1 parent a2b64e8 commit fe0d74d

9 files changed

Lines changed: 302 additions & 124 deletions

File tree

Sources/JSONAPISwiftGen/ResourceObjectSwiftGenCollection.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ func documents(
4747
on server: OpenAPI.Server,
4848
given params: [DereferencedParameter],
4949
testSuiteConfiguration: TestSuiteConfiguration
50-
) -> [OpenAPI.Response.StatusCode: DataDocumentSwiftGen] {
51-
var responseDocuments = [OpenAPI.Response.StatusCode: DataDocumentSwiftGen]()
50+
) -> [OpenAPI.Response.StatusCode: JSONAPIDocumentSwiftGen] {
51+
var responseDocuments = [OpenAPI.Response.StatusCode: JSONAPIDocumentSwiftGen]()
5252
for (statusCode, response) in responses {
5353

5454
guard let jsonResponse = response.content[.json] else {
@@ -115,7 +115,7 @@ func documents(
115115
}
116116

117117
do {
118-
responseDocuments[statusCode] = try DataDocumentSwiftGen(
118+
responseDocuments[statusCode] = try JSONAPIDocumentSwiftGen(
119119
swiftTypeName: responseBodyTypeName,
120120
structure: responseSchema,
121121
example: example,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// DocumentSwiftGen.swift
3+
//
4+
//
5+
// Created by Mathew Polzin on 7/11/20.
6+
//
7+
8+
public protocol DocumentSwiftGenerator: JSONSchemaSwiftGenerator {
9+
var swiftTypeName: String { get }
10+
var exampleGenerator: ExampleSwiftGen? { get }
11+
var testExampleFuncs: [TestFunctionGenerator] { get }
12+
13+
var swiftCodeDependencies: [SwiftGenerator] { get }
14+
}
15+
16+
extension DocumentSwiftGenerator {
17+
/// Generate Swift code not just for this Document's declaration but
18+
/// also for all declarations required for this Document to compile.
19+
public var swiftCodeWithDependencies: String {
20+
return (swiftCodeDependencies
21+
.map { $0.swiftCode }
22+
+ [swiftCode])
23+
.joined(separator: "\n")
24+
}
25+
}

Sources/JSONAPISwiftGen/Swift Generators/DocumentSwiftGen.swift renamed to Sources/JSONAPISwiftGen/Swift Generators/Document Generators/JSONAPIDocumentSwiftGen.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// DocumentSwiftGen.swift
2+
// JSONAPIDocumentSwiftGen.swift
33
// JSONAPISwiftGen
44
//
55
// Created by Mathew Polzin on 9/7/19.
@@ -13,21 +13,16 @@ import JSONAPI
1313
/// Eventually I would like to expand this to read through multiple OpenAPI responses
1414
/// and build a representation of a JSON:API Document that can handle both
1515
/// Data and Error cases.
16-
public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
16+
public struct JSONAPIDocumentSwiftGen: DocumentSwiftGenerator {
1717
public let structure: DereferencedJSONSchema
1818
public let decls: [Decl]
1919
public let swiftTypeName: String
2020
public let resourceObjectGenerators: Set<ResourceObjectSwiftGen>
2121
public let exampleGenerator: ExampleSwiftGen?
2222
public let testExampleFuncs: [TestFunctionGenerator]
2323

24-
/// Generate Swift code not just for this Document's declaration but
25-
/// also for all declarations required for this Document to compile.
26-
public var swiftCodeWithDependencies: String {
27-
return (resourceObjectGenerators
28-
.map { $0.swiftCode }
29-
+ [swiftCode])
30-
.joined(separator: "\n")
24+
public var swiftCodeDependencies: [SwiftGenerator] {
25+
Array(resourceObjectGenerators)
3126
}
3227

3328
public init(
@@ -42,7 +37,7 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
4237
self.exampleGenerator = example
4338
self.testExampleFuncs = testExampleFuncs
4439

45-
(decls, resourceObjectGenerators) = try DataDocumentSwiftGen.swiftDecls(
40+
(decls, resourceObjectGenerators) = try JSONAPIDocumentSwiftGen.swiftDecls(
4641
from: structure,
4742
swiftTypeName: swiftTypeName,
4843
allowPlaceholders: allowPlaceholders
@@ -120,7 +115,10 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
120115
guard let data = rootProperties["data"] else {
121116
if rootProperties["errors"] != nil {
122117
return (
123-
try swiftDeclsForErrorDocument(from: resourceObjectContextB, swiftTypeName: swiftTypeName),
118+
try swiftDeclsForErrorDocument(
119+
from: resourceObjectContextB,
120+
swiftTypeName: swiftTypeName
121+
),
124122
Set()
125123
)
126124
}
@@ -265,7 +263,7 @@ public struct DataDocumentSwiftGen: JSONSchemaSwiftGenerator {
265263
}
266264
}
267265

268-
public extension DataDocumentSwiftGen {
266+
public extension JSONAPIDocumentSwiftGen {
269267
enum Error: Swift.Error, CustomDebugStringConvertible {
270268
case rootNotJSONObject
271269
case expectedDataArrayToDefineItems
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// StructDocumentSwiftGen.swift
3+
// JSONAPISwiftGen
4+
//
5+
// Created by Mathew Polzin on 9/7/19.
6+
//
7+
8+
import Foundation
9+
import OpenAPIKit
10+
import JSONAPI
11+
12+
/// Creates a request or response document (no difference encoded in this
13+
/// representation) where the document structure is represented by a
14+
/// Codable `struct`.
15+
public struct StructDocumentSwiftGen: DocumentSwiftGenerator {
16+
/// The OpenAPI structure.
17+
public let structure: DereferencedJSONSchema
18+
public let decls: [Decl]
19+
public let swiftTypeName: String
20+
public let structGenerator: StructureSwiftGen
21+
public let exampleGenerator: ExampleSwiftGen?
22+
public let testExampleFuncs: [TestFunctionGenerator]
23+
24+
public let swiftCodeDependencies: [SwiftGenerator] = []
25+
26+
public init(
27+
swiftTypeName: String,
28+
structure: DereferencedJSONSchema,
29+
allowPlaceholders: Bool = true,
30+
example: ExampleSwiftGen? = nil,
31+
testExampleFuncs: [TestFunctionGenerator] = []
32+
) throws {
33+
self.swiftTypeName = swiftTypeName
34+
self.structure = structure
35+
self.exampleGenerator = example
36+
self.testExampleFuncs = testExampleFuncs
37+
38+
let structGenerator = try StructureSwiftGen(
39+
swiftTypeName: swiftTypeName,
40+
structure: structure,
41+
cascadingConformances: ["Codable", "Equatable"]
42+
)
43+
self.structGenerator = structGenerator
44+
45+
self.decls = structGenerator.decls
46+
}
47+
}

Sources/JSONAPISwiftGen/Swift Generators/ResourceObjectSwiftGen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public struct ResourceObjectSwiftGen: JSONSchemaSwiftGenerator, ResourceTypeSwif
5050

5151
resourceTypeName = typealiases.first.map { $0.alias.swiftCode }!
5252

53-
exportedSwiftTypeNames = Set(decls.compactMap { $0 as? Typealias }.map { $0.alias.swiftCode })
53+
exportedSwiftTypeNames = Set(typealiases.map { $0.alias.swiftCode })
5454
}
5555

5656
static func swiftDecls(

Sources/JSONAPISwiftGen/Swift Generators/Test Generators/OpenAPIExampleRequestTestSwiftGen.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ public extension OpenAPI.Parameter {
1515

1616
/// A Generator that produces Swift code defining a test function
1717
/// based on a provided OpenAPI example and some API parameters.
18+
///
19+
/// The generated test makes an API request, confirms the response code if desired,
20+
/// parses the response, and compares the response for equality to an example if
21+
/// desired.
1822
public struct OpenAPIExampleRequestTestSwiftGen: TestFunctionGenerator {
1923
public let decls: [Decl]
2024
public let testFunctionContext: TestFunctionLocalContext
@@ -142,16 +146,20 @@ public struct OpenAPIExampleRequestTestSwiftGen: TestFunctionGenerator {
142146
.map { "testDecodable(\(responseBodyType.swiftCode).self, from: \($0))" }
143147
?? "nil"
144148
)
145-
return PropDecl.let(propName: "expectedResponseBody",
146-
swiftType: responseBodyType.optional,
147-
value)
149+
return PropDecl.let(
150+
propName: "expectedResponseBody",
151+
swiftType: responseBodyType.optional,
152+
value
153+
)
148154
}
149155

150156
static func hostSnippet(from server: OpenAPI.Server) -> Decl {
151157
let hostUrl = server.url
152-
return PropDecl.let(propName: "defaultHost",
153-
swiftType: .rep(String.self),
154-
Value(value: hostUrl.absoluteString))
158+
return PropDecl.let(
159+
propName: "defaultHost",
160+
swiftType: .rep(String.self),
161+
Value(value: hostUrl.absoluteString)
162+
)
155163
}
156164

157165
static func headersSnippet(

Sources/JSONAPISwiftGen/SwiftDecls.swift

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ public struct PublicDecl: Decl {
116116
}
117117
}
118118

119+
public struct PrivateDecl: Decl {
120+
public let decl: Decl
121+
122+
public init(_ decl: Decl) {
123+
self.decl = decl
124+
}
125+
126+
public var swiftCode: String {
127+
return "private \(decl.swiftCode)"
128+
}
129+
}
130+
119131
public struct StaticDecl: Decl {
120132
public let decl: PropDecl
121133

@@ -271,13 +283,15 @@ public struct Function: Decl {
271283
public let body: [Decl]
272284
public let returnType: SwiftTypeRep?
273285

274-
public init(scoping: Scoping = .default,
275-
name: String,
276-
specializations: [SwiftTypeDef]? = nil,
277-
arguments: [(name: String, type: SwiftTypeRep)] = [],
278-
conditions: [(type: SwiftTypeDef, conformance: String)]? = nil,
279-
body: [Decl],
280-
returnType: SwiftTypeRep? = nil) {
286+
public init(
287+
scoping: Scoping = .default,
288+
name: String,
289+
specializations: [SwiftTypeDef]? = nil,
290+
arguments: [(name: String, type: SwiftTypeRep)] = [],
291+
conditions: [(type: SwiftTypeDef, conformance: String)]? = nil,
292+
body: [Decl],
293+
returnType: SwiftTypeRep? = nil
294+
) {
281295
self.scoping = scoping
282296
self.name = name
283297
self.specializations = specializations
@@ -375,6 +389,7 @@ public struct Import: Decl {
375389
public static let AnyCodable: Import = .init(module: "AnyCodable")
376390
public static let JSONAPI: Import = .init(module: "JSONAPI")
377391
public static let JSONAPITesting: Import = .init(module: "JSONAPITesting")
392+
public static let OpenAPIKit: Import = .init(module: "OpenAPIKit")
378393

379394
public static let FoundationNetworking: Decl = """
380395
#if canImport(FoundationNetworking)

0 commit comments

Comments
 (0)