Last active
March 23, 2023 18:21
-
-
Save IanKeen/890910d344d9cab9b2ab2ec409370e14 to your computer and use it in GitHub Desktop.
Combined: A type composed of other types (potential alternative to my Partial<T> type)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@dynamicMemberLookup | |
struct Combined<A, B> { | |
private let a: A | |
private let b: B | |
init(a: A, b: B) { (self.a, self.b) = (a, b) } | |
subscript<T>(dynamicMember keyPath: KeyPath<A, T>) -> T { | |
return a[keyPath: keyPath] | |
} | |
subscript<T>(dynamicMember keyPath: KeyPath<B, T>) -> T { | |
return b[keyPath: keyPath] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension Combined: Encodable where A: Encodable, B: Encodable { | |
func encode(to encoder: Encoder) throws { | |
try a.encode(to: encoder) | |
try b.encode(to: encoder) | |
} | |
} | |
extension Combined: Decodable where A: Decodable, B: Decodable { | |
init(from decoder: Decoder) throws { | |
try self.init( | |
a: A(from: decoder), | |
b: B(from: decoder) | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct A: Codable { var a: Int } | |
struct B: Codable { var b: Int } | |
struct C: Codable { var c: Int } | |
let json = """ | |
{"a": 1, "b": 2, "c": 3} | |
""" | |
let decoded = try! JSONDecoder().decode(Combined<A, Combined<B, C>>.self, from: Data(json.utf8)) | |
print(decoded.a, decoded.b, decoded.c) // 1 2 3 | |
let string = try! String(data: JSONEncoder().encode(decoded), encoding: .utf8)! | |
print(string) // {"a":1,"b":2,"c":3} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Foo: Equatable { let fooValue: String } | |
struct Bar: Equatable { let barValue: String } | |
struct Baz: Equatable { let bazValue: String } | |
typealias Step1 = Combined<Void, Foo> | |
typealias Step2 = Combined<Step1, Bar> | |
typealias Step3 = Combined<Step2, Baz> | |
let step1 = Step1(a: (), b: .init(fooValue: "foo")) | |
step1.fooValue // foo | |
let step2 = Step2(a: step1, b: .init(barValue: "bar")) | |
step2.fooValue // foo | |
step2.barValue // bar | |
let step3 = Step3(a: step2, b: .init(bazValue: "baz")) | |
step3.fooValue // foo | |
step3.barValue // bar | |
step3.bazValue // baz |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment