Skip to content

Commit 53f7f55

Browse files
committed
Add Poly7 and Include7 because why not
1 parent d8d0302 commit 53f7f55

6 files changed

Lines changed: 365 additions & 0 deletions

File tree

Sources/JSONAPI/Document/Includes.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,11 @@ extension Includes where I: _Poly6 {
115115
}
116116

117117
// MARK: - 7 includes
118+
public typealias Include7 = Poly7
119+
extension Includes where I: _Poly7 {
120+
public subscript(_ lookup: I.G.Type) -> [I.G] {
121+
return values.compactMap { $0.g }
122+
}
123+
}
124+
118125
// MARK: - 8 includes

Sources/JSONAPI/Resource/Poly.swift

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,3 +644,158 @@ extension Poly6: CustomStringConvertible {
644644
return "Poly(\(str))"
645645
}
646646
}
647+
648+
// MARK: - 7 types
649+
public protocol _Poly7: _Poly6 {
650+
associatedtype G: EntityType
651+
var g: G? { get }
652+
653+
init(_ g: G)
654+
}
655+
656+
public extension _Poly7 {
657+
subscript(_ lookup: G.Type) -> G? {
658+
return g
659+
}
660+
}
661+
662+
public enum Poly7<A: EntityType, B: EntityType, C: EntityType, D: EntityType, E: EntityType, F: EntityType, G: EntityType>: _Poly7 {
663+
case a(A)
664+
case b(B)
665+
case c(C)
666+
case d(D)
667+
case e(E)
668+
case f(F)
669+
case g(G)
670+
671+
public var a: A? {
672+
guard case let .a(ret) = self else { return nil }
673+
return ret
674+
}
675+
676+
public init(_ a: A) {
677+
self = .a(a)
678+
}
679+
680+
public var b: B? {
681+
guard case let .b(ret) = self else { return nil }
682+
return ret
683+
}
684+
685+
public init(_ b: B) {
686+
self = .b(b)
687+
}
688+
689+
public var c: C? {
690+
guard case let .c(ret) = self else { return nil }
691+
return ret
692+
}
693+
694+
public init(_ c: C) {
695+
self = .c(c)
696+
}
697+
698+
public var d: D? {
699+
guard case let .d(ret) = self else { return nil }
700+
return ret
701+
}
702+
703+
public init(_ d: D) {
704+
self = .d(d)
705+
}
706+
707+
public var e: E? {
708+
guard case let .e(ret) = self else { return nil }
709+
return ret
710+
}
711+
712+
public init(_ e: E) {
713+
self = .e(e)
714+
}
715+
716+
public var f: F? {
717+
guard case let .f(ret) = self else { return nil }
718+
return ret
719+
}
720+
721+
public init(_ f: F) {
722+
self = .f(f)
723+
}
724+
725+
public var g: G? {
726+
guard case let .g(ret) = self else { return nil }
727+
return ret
728+
}
729+
730+
public init(_ g: G) {
731+
self = .g(g)
732+
}
733+
734+
public init(from decoder: Decoder) throws {
735+
let container = try decoder.singleValueContainer()
736+
737+
let attempts = [
738+
try decode(A.self, from: container).map { Poly7.a($0) },
739+
try decode(B.self, from: container).map { Poly7.b($0) },
740+
try decode(C.self, from: container).map { Poly7.c($0) },
741+
try decode(D.self, from: container).map { Poly7.d($0) },
742+
try decode(E.self, from: container).map { Poly7.e($0) },
743+
try decode(F.self, from: container).map { Poly7.f($0) },
744+
try decode(G.self, from: container).map { Poly7.g($0) }]
745+
746+
let maybeVal: Poly7<A, B, C, D, E, F, G>? = attempts
747+
.compactMap { $0.value }
748+
.first
749+
750+
guard let val = maybeVal else {
751+
throw EncodingError.invalidValue(Poly7<A, B, C, D, E, F, G>.self, .init(codingPath: decoder.codingPath, debugDescription: "Failed to find an include of the expected type. Attempts: \(attempts.map { $0.error }.compactMap { $0 })"))
752+
}
753+
754+
self = val
755+
}
756+
757+
public func encode(to encoder: Encoder) throws {
758+
var container = encoder.singleValueContainer()
759+
760+
switch self {
761+
case .a(let a):
762+
try container.encode(a)
763+
case .b(let b):
764+
try container.encode(b)
765+
case .c(let c):
766+
try container.encode(c)
767+
case .d(let d):
768+
try container.encode(d)
769+
case .e(let e):
770+
try container.encode(e)
771+
case .f(let f):
772+
try container.encode(f)
773+
case .g(let g):
774+
try container.encode(g)
775+
}
776+
}
777+
}
778+
779+
extension Poly7: CustomStringConvertible {
780+
public var description: String {
781+
let str: String
782+
switch self {
783+
case .a(let a):
784+
str = String(describing: a)
785+
case .b(let b):
786+
str = String(describing: b)
787+
case .c(let c):
788+
str = String(describing: c)
789+
case .d(let d):
790+
str = String(describing: d)
791+
case .e(let e):
792+
str = String(describing: e)
793+
case .f(let f):
794+
str = String(describing: f)
795+
case .g(let g):
796+
str = String(describing: g)
797+
}
798+
799+
return "Poly(\(str))"
800+
}
801+
}

Tests/JSONAPITests/Includes/IncludeTests.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,24 @@ class IncludedTests: XCTestCase {
121121
test_DecodeEncodeEquality(type: Includes<Include6<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6>>.self,
122122
data: six_different_type_includes)
123123
}
124+
125+
func test_SevenDifferentIncludes() {
126+
let includes = decoded(type: Includes<Include7<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7>>.self,
127+
data: seven_different_type_includes)
128+
129+
XCTAssertEqual(includes[TestEntity.self].count, 1)
130+
XCTAssertEqual(includes[TestEntity2.self].count, 1)
131+
XCTAssertEqual(includes[TestEntity3.self].count, 1)
132+
XCTAssertEqual(includes[TestEntity4.self].count, 1)
133+
XCTAssertEqual(includes[TestEntity5.self].count, 1)
134+
XCTAssertEqual(includes[TestEntity6.self].count, 1)
135+
XCTAssertEqual(includes[TestEntity7.self].count, 1)
136+
}
137+
138+
func test_SevenDifferentIncludes_encode() {
139+
test_DecodeEncodeEquality(type: Includes<Include7<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7>>.self,
140+
data: seven_different_type_includes)
141+
}
124142
}
125143

126144
// MARK: - Test types
@@ -203,4 +221,15 @@ extension IncludedTests {
203221
}
204222

205223
typealias TestEntity6 = BasicEntity<TestEntityType6>
224+
225+
enum TestEntityType7: EntityDescription {
226+
227+
typealias Attributes = NoAttributes
228+
229+
public static var type: String { return "test_entity7" }
230+
231+
typealias Relationships = NoRelationships
232+
}
233+
234+
typealias TestEntity7 = BasicEntity<TestEntityType7>
206235
}

Tests/JSONAPITests/Includes/stubs/IncludeStubs.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,76 @@ let six_different_type_includes = """
281281
}
282282
]
283283
""".data(using: .utf8)!
284+
285+
let seven_different_type_includes = """
286+
[
287+
{
288+
"type": "test_entity1",
289+
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
290+
"attributes": {
291+
"foo": "Hello",
292+
"bar": 123
293+
}
294+
},
295+
{
296+
"type": "test_entity2",
297+
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333",
298+
"attributes": {
299+
"foo": "World",
300+
"bar": 456
301+
},
302+
"relationships": {
303+
"entity1": {
304+
"data": {
305+
"type": "test_entity1",
306+
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
307+
}
308+
}
309+
}
310+
},
311+
{
312+
"type": "test_entity3",
313+
"id": "11223B69-4DF1-467F-B52E-B0C9E44FC443",
314+
"relationships": {
315+
"entity1": {
316+
"data": {
317+
"type": "test_entity1",
318+
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
319+
}
320+
},
321+
"entity2": {
322+
"data": [
323+
{
324+
"type": "test_entity2",
325+
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333"
326+
}
327+
]
328+
}
329+
}
330+
},
331+
{
332+
"type": "test_entity6",
333+
"id": "11113B69-4DF1-467F-B52E-B0C9E44FC444",
334+
"relationships": {
335+
"entity4": {
336+
"data": {
337+
"type": "test_entity4",
338+
"id": "364B3B69-4DF1-467F-B52E-B0C9E44F666E"
339+
}
340+
}
341+
}
342+
},
343+
{
344+
"type": "test_entity5",
345+
"id": "A24B3B69-4DF1-467F-B52E-B0C9E44F436A"
346+
},
347+
{
348+
"type": "test_entity4",
349+
"id": "364B3B69-4DF1-467F-B52E-B0C9E44F666E"
350+
},
351+
{
352+
"type": "test_entity7",
353+
"id": "364B3B69-4DF1-222F-B52E-B0C9E44F666E"
354+
}
355+
]
356+
""".data(using: .utf8)!

0 commit comments

Comments
 (0)