Skip to content

Commit 61f714d

Browse files
Merge pull request #129 from NeedleInAJayStack/feature/drop-type-codable-requirement
Drops Encodable requirement on GraphQL types
2 parents 742dba5 + 0bd4dfd commit 61f714d

16 files changed

+70
-62
lines changed

Sources/Graphiti/Connection/Connection.swift

+10-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Foundation
22
import GraphQL
33
import NIO
44

5-
public struct Connection<Node: Encodable>: Encodable {
5+
public struct Connection<Node> {
66
public let edges: [Edge<Node>]
77
public let pageInfo: PageInfo
88
}
@@ -19,7 +19,7 @@ public extension Connection where Node: Identifiable, Node.ID: LosslessStringCon
1919
}
2020

2121
@available(macOS 10.15, macCatalyst 13.0, iOS 13.0, tvOS 13, watchOS 6.0, *) // For Identifiable
22-
public extension EventLoopFuture where Value: Sequence, Value.Element: Encodable & Identifiable,
22+
public extension EventLoopFuture where Value: Sequence, Value.Element: Identifiable,
2323
Value.Element.ID: LosslessStringConvertible {
2424
func connection(from arguments: Paginatable) -> EventLoopFuture<Connection<Value.Element>> {
2525
connection(from: arguments, makeCursor: Connection<Value.Element>.cursor)
@@ -36,7 +36,7 @@ Value.Element.ID: LosslessStringConvertible {
3636
}
3737
}
3838

39-
public extension EventLoopFuture where Value: Sequence, Value.Element: Encodable {
39+
public extension EventLoopFuture where Value: Sequence {
4040
func connection(
4141
from arguments: Paginatable,
4242
makeCursor: @escaping (Value.Element) throws -> String
@@ -66,7 +66,7 @@ public extension EventLoopFuture where Value: Sequence, Value.Element: Encodable
6666
}
6767

6868
@available(macOS 10.15, macCatalyst 13.0, iOS 13.0, tvOS 13, watchOS 6.0, *) // For Identifiable
69-
public extension Sequence where Element: Encodable & Identifiable,
69+
public extension Sequence where Element: Identifiable,
7070
Element.ID: LosslessStringConvertible {
7171
func connection(from arguments: Paginatable) throws -> Connection<Element> {
7272
try connection(from: arguments, makeCursor: Connection<Element>.cursor)
@@ -81,7 +81,7 @@ Element.ID: LosslessStringConvertible {
8181
}
8282
}
8383

84-
public extension Sequence where Element: Encodable {
84+
public extension Sequence {
8585
func connection(
8686
from arguments: Paginatable,
8787
makeCursor: @escaping (Element) throws -> String
@@ -120,7 +120,7 @@ func connect<Node>(
120120
to elements: [Node],
121121
arguments: PaginationArguments,
122122
makeCursor: @escaping (Node) throws -> String
123-
) throws -> Connection<Node> where Node: Encodable {
123+
) throws -> Connection<Node> {
124124
let edges = try elements.map { element in
125125
// swiftformat:disable:next hoistTry
126126
Edge<Node>(node: element, cursor: try makeCursor(element))
@@ -140,7 +140,7 @@ func connect<Node>(
140140
)
141141
}
142142

143-
func slicingCursor<Node: Encodable>(
143+
func slicingCursor<Node>(
144144
edges: [Edge<Node>],
145145
arguments: PaginationArguments
146146
) -> ArraySlice<Edge<Node>> {
@@ -166,7 +166,7 @@ func slicingCursor<Node: Encodable>(
166166
return edges
167167
}
168168

169-
func slicingCount<Node: Encodable>(
169+
func slicingCount<Node>(
170170
edges: ArraySlice<Edge<Node>>,
171171
arguments: PaginationArguments
172172
) throws -> [Edge<Node>] {
@@ -195,7 +195,7 @@ func slicingCount<Node: Encodable>(
195195
return Array(edges)
196196
}
197197

198-
func hasPreviousPage<Node: Encodable>(
198+
func hasPreviousPage<Node>(
199199
edges: ArraySlice<Edge<Node>>,
200200
arguments: PaginationArguments
201201
) -> Bool {
@@ -206,7 +206,7 @@ func hasPreviousPage<Node: Encodable>(
206206
return false
207207
}
208208

209-
func hasNextPage<Node: Encodable>(
209+
func hasNextPage<Node>(
210210
edges: ArraySlice<Edge<Node>>,
211211
arguments: PaginationArguments
212212
) -> Bool {

Sources/Graphiti/Connection/ConnectionType.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import GraphQL
33
public final class ConnectionType<
44
Resolver,
55
Context,
6-
ObjectType: Encodable
6+
ObjectType
77
>: TypeComponent<
88
Resolver,
99
Context
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
protocol Edgeable {
2-
associatedtype Node: Encodable
2+
associatedtype Node
33
var node: Node { get }
44
var cursor: String { get }
55
}
66

7-
public struct Edge<Node: Encodable>: Edgeable, Encodable {
7+
public struct Edge<Node>: Edgeable {
88
public let node: Node
99
public let cursor: String
1010
}

Sources/Graphiti/Definition/Reflection.swift

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public enum Reflection {
44
return description.hasSuffix("Protocol")
55
}
66

7+
@available(*, deprecated, message: "No longer used")
78
public static func isEncodable(type: Any.Type) -> Bool {
89
if isProtocol(type: type) {
910
return true

Sources/Graphiti/Definition/TypeProvider.swift

-10
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,6 @@ extension TypeProvider {
8686
}
8787

8888
func getOutputType(from type: Any.Type, field: String) throws -> GraphQLOutputType {
89-
// TODO: Remove this when Reflection error is fixed
90-
guard Reflection.isEncodable(type: type) else {
91-
throw GraphQLError(
92-
message:
93-
// TODO: Add field type and use "type.field" format.
94-
"Cannot use type \"\(type)\" for field \"\(field)\". " +
95-
"Type does not conform to \"Encodable\"."
96-
)
97-
}
98-
9989
let graphQLType: GraphQLType
10090

10191
do {

Sources/Graphiti/Field/Field/Field.swift

+11-4
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public class Field<ObjectType, Context, FieldType, Arguments: Decodable>: FieldC
112112

113113
// MARK: AsyncResolve Initializers
114114

115-
public extension Field where FieldType: Encodable {
115+
public extension Field {
116116
convenience init(
117117
_ name: String,
118118
at function: @escaping AsyncResolve<ObjectType, Context, Arguments, FieldType>,
@@ -154,7 +154,7 @@ public extension Field {
154154

155155
// MARK: SimpleAsyncResolve Initializers
156156

157-
public extension Field where FieldType: Encodable {
157+
public extension Field {
158158
convenience init(
159159
_ name: String,
160160
at function: @escaping SimpleAsyncResolve<ObjectType, Context, Arguments, FieldType>,
@@ -196,7 +196,11 @@ public extension Field {
196196

197197
// MARK: SyncResolve Initializers
198198

199-
public extension Field where FieldType: Encodable {
199+
// '@_disfavoredOverload' is included below because otherwise `SimpleAsyncResolve` initializers also match this signature, causing the
200+
// calls to be ambiguous. We prefer that if an EventLoopFuture is returned from the resolve, that `SimpleAsyncResolve` is matched.
201+
202+
public extension Field {
203+
@_disfavoredOverload
200204
convenience init(
201205
_ name: String,
202206
at function: @escaping SyncResolve<ObjectType, Context, Arguments, FieldType>,
@@ -205,6 +209,7 @@ public extension Field where FieldType: Encodable {
205209
self.init(name: name, arguments: [argument()], syncResolve: function)
206210
}
207211

212+
@_disfavoredOverload
208213
convenience init(
209214
_ name: String,
210215
at function: @escaping SyncResolve<ObjectType, Context, Arguments, FieldType>,
@@ -216,6 +221,7 @@ public extension Field where FieldType: Encodable {
216221
}
217222

218223
public extension Field {
224+
@_disfavoredOverload
219225
convenience init<ResolveType>(
220226
_ name: String,
221227
at function: @escaping SyncResolve<ObjectType, Context, Arguments, ResolveType>,
@@ -225,6 +231,7 @@ public extension Field {
225231
self.init(name: name, arguments: [argument()], syncResolve: function)
226232
}
227233

234+
@_disfavoredOverload
228235
convenience init<ResolveType>(
229236
_ name: String,
230237
at function: @escaping SyncResolve<ObjectType, Context, Arguments, ResolveType>,
@@ -298,7 +305,7 @@ public extension Field where Arguments == NoArguments {
298305

299306
// MARK: ConcurrentResolve Initializers
300307

301-
public extension Field where FieldType: Encodable {
308+
public extension Field {
302309
@available(macOS 10.15, iOS 15, watchOS 8, tvOS 15, *)
303310
convenience init(
304311
_ name: String,

Sources/Graphiti/Input/Input.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import GraphQL
33
public final class Input<
44
Resolver,
55
Context,
6-
InputObjectType: Decodable
6+
InputObjectType
77
>: TypeComponent<
88
Resolver,
99
Context

Sources/Graphiti/Subscription/SubscribeField.swift

+13-4
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public class SubscriptionField<
263263

264264
// MARK: AsyncResolve Initializers
265265

266-
public extension SubscriptionField where FieldType: Encodable {
266+
public extension SubscriptionField {
267267
convenience init(
268268
_ name: String,
269269
at function: @escaping AsyncResolve<SourceEventType, Context, Arguments, FieldType>,
@@ -376,7 +376,7 @@ public extension SubscriptionField {
376376

377377
// MARK: SimpleAsyncResolve Initializers
378378

379-
public extension SubscriptionField where FieldType: Encodable {
379+
public extension SubscriptionField {
380380
convenience init(
381381
_ name: String,
382382
at function: @escaping SimpleAsyncResolve<SourceEventType, Context, Arguments, FieldType>,
@@ -491,7 +491,11 @@ public extension SubscriptionField {
491491

492492
// MARK: SyncResolve Initializers
493493

494-
public extension SubscriptionField where FieldType: Encodable {
494+
// '@_disfavoredOverload' is included below because otherwise `SimpleAsyncResolve` initializers also match this signature, causing the
495+
// calls to be ambiguous. We prefer that if an EventLoopFuture is returned from the resolve, that `SimpleAsyncResolve` is matched.
496+
497+
public extension SubscriptionField {
498+
@_disfavoredOverload
495499
convenience init(
496500
_ name: String,
497501
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, FieldType>,
@@ -511,6 +515,7 @@ public extension SubscriptionField where FieldType: Encodable {
511515
)
512516
}
513517

518+
@_disfavoredOverload
514519
convenience init(
515520
_ name: String,
516521
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, FieldType>,
@@ -528,6 +533,7 @@ public extension SubscriptionField where FieldType: Encodable {
528533
}
529534

530535
public extension SubscriptionField {
536+
@_disfavoredOverload
531537
convenience init(
532538
_ name: String,
533539
as: FieldType.Type,
@@ -542,6 +548,7 @@ public extension SubscriptionField {
542548
self.init(name: name, arguments: [argument()], as: `as`, syncSubscribe: subFunc)
543549
}
544550

551+
@_disfavoredOverload
545552
convenience init(
546553
_ name: String,
547554
as: FieldType.Type,
@@ -557,6 +564,7 @@ public extension SubscriptionField {
557564
self.init(name: name, arguments: arguments(), as: `as`, syncSubscribe: subFunc)
558565
}
559566

567+
@_disfavoredOverload
560568
convenience init<ResolveType>(
561569
_ name: String,
562570
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, ResolveType>,
@@ -577,6 +585,7 @@ public extension SubscriptionField {
577585
)
578586
}
579587

588+
@_disfavoredOverload
580589
convenience init<ResolveType>(
581590
_ name: String,
582591
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, ResolveType>,
@@ -680,7 +689,7 @@ public extension SubscriptionField {
680689

681690
// MARK: ConcurrentResolve Initializers
682691

683-
public extension SubscriptionField where FieldType: Encodable {
692+
public extension SubscriptionField {
684693
@available(macOS 10.15, iOS 15, watchOS 8, tvOS 15, *)
685694
convenience init(
686695
_ name: String,

Sources/Graphiti/Type/Type.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import GraphQL
22

3-
public final class Type<Resolver, Context, ObjectType: Encodable>: TypeComponent<
3+
public final class Type<Resolver, Context, ObjectType>: TypeComponent<
44
Resolver,
55
Context
66
> {

Tests/GraphitiTests/ConnectionTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import NIO
44
import XCTest
55

66
class ConnectionTests: XCTestCase {
7-
struct Comment: Codable, Identifiable {
7+
struct Comment: Identifiable {
88
let id: Int
99
let message: String
1010
}

Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct ID: Codable {
2121
}
2222
}
2323

24-
struct User: Codable {
24+
struct User {
2525
let id: String
2626
let name: String?
2727
let friends: [User]?
@@ -53,7 +53,7 @@ struct UserInput: Codable {
5353
let friends: [UserInput]?
5454
}
5555

56-
struct UserEvent: Codable {
56+
struct UserEvent {
5757
let user: User
5858
}
5959

Tests/GraphitiTests/ProductAPI/ProductContext.swift

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22

3+
// swiftformat:disable:next enumNamespaces
34
struct ProductContext {
45
static let dimensions = [
56
ProductDimension(

Tests/GraphitiTests/ProductAPI/ProductEntities.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22
import Graphiti
33

4-
struct Product: Codable {
4+
struct Product {
55
let id: String
66
let sku: String?
77
let package: String?
@@ -30,7 +30,7 @@ struct Product: Codable {
3030
}
3131
}
3232

33-
struct DeprecatedProduct: Codable {
33+
struct DeprecatedProduct {
3434
let sku: String
3535
let package: String
3636
let reason: String?
@@ -42,11 +42,11 @@ struct DeprecatedProduct: Codable {
4242
}
4343
}
4444

45-
struct ProductVariation: Codable {
45+
struct ProductVariation {
4646
let id: String
4747
}
4848

49-
struct ProductResearch: Codable {
49+
struct ProductResearch {
5050
let study: CaseStudy
5151
let outcome: String?
5252

@@ -59,18 +59,18 @@ struct ProductResearch: Codable {
5959
}
6060
}
6161

62-
struct CaseStudy: Codable {
62+
struct CaseStudy {
6363
let caseNumber: String
6464
let description: String?
6565
}
6666

67-
struct ProductDimension: Codable {
67+
struct ProductDimension {
6868
let size: String?
6969
let weight: Float?
7070
let unit: String?
7171
}
7272

73-
struct ProductUser: Codable {
73+
struct ProductUser {
7474
let email: String
7575
let name: String?
7676
let totalProductsCreated: Int?

0 commit comments

Comments
 (0)