Skip to content

Commit

Permalink
Merge pull request #129 from NeedleInAJayStack/feature/drop-type-coda…
Browse files Browse the repository at this point in the history
…ble-requirement

Drops Encodable requirement on GraphQL types
  • Loading branch information
NeedleInAJayStack authored Nov 12, 2023
2 parents 742dba5 + 0bd4dfd commit 61f714d
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 62 deletions.
20 changes: 10 additions & 10 deletions Sources/Graphiti/Connection/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import GraphQL
import NIO

public struct Connection<Node: Encodable>: Encodable {
public struct Connection<Node> {
public let edges: [Edge<Node>]
public let pageInfo: PageInfo
}
Expand All @@ -19,7 +19,7 @@ public extension Connection where Node: Identifiable, Node.ID: LosslessStringCon
}

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

public extension EventLoopFuture where Value: Sequence, Value.Element: Encodable {
public extension EventLoopFuture where Value: Sequence {
func connection(
from arguments: Paginatable,
makeCursor: @escaping (Value.Element) throws -> String
Expand Down Expand Up @@ -66,7 +66,7 @@ public extension EventLoopFuture where Value: Sequence, Value.Element: Encodable
}

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

public extension Sequence where Element: Encodable {
public extension Sequence {
func connection(
from arguments: Paginatable,
makeCursor: @escaping (Element) throws -> String
Expand Down Expand Up @@ -120,7 +120,7 @@ func connect<Node>(
to elements: [Node],
arguments: PaginationArguments,
makeCursor: @escaping (Node) throws -> String
) throws -> Connection<Node> where Node: Encodable {
) throws -> Connection<Node> {
let edges = try elements.map { element in
// swiftformat:disable:next hoistTry
Edge<Node>(node: element, cursor: try makeCursor(element))
Expand All @@ -140,7 +140,7 @@ func connect<Node>(
)
}

func slicingCursor<Node: Encodable>(
func slicingCursor<Node>(
edges: [Edge<Node>],
arguments: PaginationArguments
) -> ArraySlice<Edge<Node>> {
Expand All @@ -166,7 +166,7 @@ func slicingCursor<Node: Encodable>(
return edges
}

func slicingCount<Node: Encodable>(
func slicingCount<Node>(
edges: ArraySlice<Edge<Node>>,
arguments: PaginationArguments
) throws -> [Edge<Node>] {
Expand Down Expand Up @@ -195,7 +195,7 @@ func slicingCount<Node: Encodable>(
return Array(edges)
}

func hasPreviousPage<Node: Encodable>(
func hasPreviousPage<Node>(
edges: ArraySlice<Edge<Node>>,
arguments: PaginationArguments
) -> Bool {
Expand All @@ -206,7 +206,7 @@ func hasPreviousPage<Node: Encodable>(
return false
}

func hasNextPage<Node: Encodable>(
func hasNextPage<Node>(
edges: ArraySlice<Edge<Node>>,
arguments: PaginationArguments
) -> Bool {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Graphiti/Connection/ConnectionType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import GraphQL
public final class ConnectionType<
Resolver,
Context,
ObjectType: Encodable
ObjectType
>: TypeComponent<
Resolver,
Context
Expand Down
4 changes: 2 additions & 2 deletions Sources/Graphiti/Connection/Edge.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
protocol Edgeable {
associatedtype Node: Encodable
associatedtype Node
var node: Node { get }
var cursor: String { get }
}

public struct Edge<Node: Encodable>: Edgeable, Encodable {
public struct Edge<Node>: Edgeable {
public let node: Node
public let cursor: String
}
1 change: 1 addition & 0 deletions Sources/Graphiti/Definition/Reflection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public enum Reflection {
return description.hasSuffix("Protocol")
}

@available(*, deprecated, message: "No longer used")
public static func isEncodable(type: Any.Type) -> Bool {
if isProtocol(type: type) {
return true
Expand Down
10 changes: 0 additions & 10 deletions Sources/Graphiti/Definition/TypeProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,6 @@ extension TypeProvider {
}

func getOutputType(from type: Any.Type, field: String) throws -> GraphQLOutputType {
// TODO: Remove this when Reflection error is fixed
guard Reflection.isEncodable(type: type) else {
throw GraphQLError(
message:
// TODO: Add field type and use "type.field" format.
"Cannot use type \"\(type)\" for field \"\(field)\". " +
"Type does not conform to \"Encodable\"."
)
}

let graphQLType: GraphQLType

do {
Expand Down
15 changes: 11 additions & 4 deletions Sources/Graphiti/Field/Field/Field.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public class Field<ObjectType, Context, FieldType, Arguments: Decodable>: FieldC

// MARK: AsyncResolve Initializers

public extension Field where FieldType: Encodable {
public extension Field {
convenience init(
_ name: String,
at function: @escaping AsyncResolve<ObjectType, Context, Arguments, FieldType>,
Expand Down Expand Up @@ -154,7 +154,7 @@ public extension Field {

// MARK: SimpleAsyncResolve Initializers

public extension Field where FieldType: Encodable {
public extension Field {
convenience init(
_ name: String,
at function: @escaping SimpleAsyncResolve<ObjectType, Context, Arguments, FieldType>,
Expand Down Expand Up @@ -196,7 +196,11 @@ public extension Field {

// MARK: SyncResolve Initializers

public extension Field where FieldType: Encodable {
// '@_disfavoredOverload' is included below because otherwise `SimpleAsyncResolve` initializers also match this signature, causing the
// calls to be ambiguous. We prefer that if an EventLoopFuture is returned from the resolve, that `SimpleAsyncResolve` is matched.

public extension Field {
@_disfavoredOverload
convenience init(
_ name: String,
at function: @escaping SyncResolve<ObjectType, Context, Arguments, FieldType>,
Expand All @@ -205,6 +209,7 @@ public extension Field where FieldType: Encodable {
self.init(name: name, arguments: [argument()], syncResolve: function)
}

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

public extension Field {
@_disfavoredOverload
convenience init<ResolveType>(
_ name: String,
at function: @escaping SyncResolve<ObjectType, Context, Arguments, ResolveType>,
Expand All @@ -225,6 +231,7 @@ public extension Field {
self.init(name: name, arguments: [argument()], syncResolve: function)
}

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

// MARK: ConcurrentResolve Initializers

public extension Field where FieldType: Encodable {
public extension Field {
@available(macOS 10.15, iOS 15, watchOS 8, tvOS 15, *)
convenience init(
_ name: String,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Graphiti/Input/Input.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import GraphQL
public final class Input<
Resolver,
Context,
InputObjectType: Decodable
InputObjectType
>: TypeComponent<
Resolver,
Context
Expand Down
17 changes: 13 additions & 4 deletions Sources/Graphiti/Subscription/SubscribeField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public class SubscriptionField<

// MARK: AsyncResolve Initializers

public extension SubscriptionField where FieldType: Encodable {
public extension SubscriptionField {
convenience init(
_ name: String,
at function: @escaping AsyncResolve<SourceEventType, Context, Arguments, FieldType>,
Expand Down Expand Up @@ -376,7 +376,7 @@ public extension SubscriptionField {

// MARK: SimpleAsyncResolve Initializers

public extension SubscriptionField where FieldType: Encodable {
public extension SubscriptionField {
convenience init(
_ name: String,
at function: @escaping SimpleAsyncResolve<SourceEventType, Context, Arguments, FieldType>,
Expand Down Expand Up @@ -491,7 +491,11 @@ public extension SubscriptionField {

// MARK: SyncResolve Initializers

public extension SubscriptionField where FieldType: Encodable {
// '@_disfavoredOverload' is included below because otherwise `SimpleAsyncResolve` initializers also match this signature, causing the
// calls to be ambiguous. We prefer that if an EventLoopFuture is returned from the resolve, that `SimpleAsyncResolve` is matched.

public extension SubscriptionField {
@_disfavoredOverload
convenience init(
_ name: String,
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, FieldType>,
Expand All @@ -511,6 +515,7 @@ public extension SubscriptionField where FieldType: Encodable {
)
}

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

public extension SubscriptionField {
@_disfavoredOverload
convenience init(
_ name: String,
as: FieldType.Type,
Expand All @@ -542,6 +548,7 @@ public extension SubscriptionField {
self.init(name: name, arguments: [argument()], as: `as`, syncSubscribe: subFunc)
}

@_disfavoredOverload
convenience init(
_ name: String,
as: FieldType.Type,
Expand All @@ -557,6 +564,7 @@ public extension SubscriptionField {
self.init(name: name, arguments: arguments(), as: `as`, syncSubscribe: subFunc)
}

@_disfavoredOverload
convenience init<ResolveType>(
_ name: String,
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, ResolveType>,
Expand All @@ -577,6 +585,7 @@ public extension SubscriptionField {
)
}

@_disfavoredOverload
convenience init<ResolveType>(
_ name: String,
at function: @escaping SyncResolve<SourceEventType, Context, Arguments, ResolveType>,
Expand Down Expand Up @@ -680,7 +689,7 @@ public extension SubscriptionField {

// MARK: ConcurrentResolve Initializers

public extension SubscriptionField where FieldType: Encodable {
public extension SubscriptionField {
@available(macOS 10.15, iOS 15, watchOS 8, tvOS 15, *)
convenience init(
_ name: String,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Graphiti/Type/Type.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import GraphQL

public final class Type<Resolver, Context, ObjectType: Encodable>: TypeComponent<
public final class Type<Resolver, Context, ObjectType>: TypeComponent<
Resolver,
Context
> {
Expand Down
2 changes: 1 addition & 1 deletion Tests/GraphitiTests/ConnectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import NIO
import XCTest

class ConnectionTests: XCTestCase {
struct Comment: Codable, Identifiable {
struct Comment: Identifiable {
let id: Int
let message: String
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/GraphitiTests/HelloWorldTests/HelloWorldTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct ID: Codable {
}
}

struct User: Codable {
struct User {
let id: String
let name: String?
let friends: [User]?
Expand Down Expand Up @@ -53,7 +53,7 @@ struct UserInput: Codable {
let friends: [UserInput]?
}

struct UserEvent: Codable {
struct UserEvent {
let user: User
}

Expand Down
1 change: 1 addition & 0 deletions Tests/GraphitiTests/ProductAPI/ProductContext.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Foundation

// swiftformat:disable:next enumNamespaces
struct ProductContext {
static let dimensions = [
ProductDimension(
Expand Down
14 changes: 7 additions & 7 deletions Tests/GraphitiTests/ProductAPI/ProductEntities.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import Graphiti

struct Product: Codable {
struct Product {
let id: String
let sku: String?
let package: String?
Expand Down Expand Up @@ -30,7 +30,7 @@ struct Product: Codable {
}
}

struct DeprecatedProduct: Codable {
struct DeprecatedProduct {
let sku: String
let package: String
let reason: String?
Expand All @@ -42,11 +42,11 @@ struct DeprecatedProduct: Codable {
}
}

struct ProductVariation: Codable {
struct ProductVariation {
let id: String
}

struct ProductResearch: Codable {
struct ProductResearch {
let study: CaseStudy
let outcome: String?

Expand All @@ -59,18 +59,18 @@ struct ProductResearch: Codable {
}
}

struct CaseStudy: Codable {
struct CaseStudy {
let caseNumber: String
let description: String?
}

struct ProductDimension: Codable {
struct ProductDimension {
let size: String?
let weight: Float?
let unit: String?
}

struct ProductUser: Codable {
struct ProductUser {
let email: String
let name: String?
let totalProductsCreated: Int?
Expand Down
Loading

0 comments on commit 61f714d

Please sign in to comment.