Created
September 8, 2017 07:34
-
-
Save elm4ward/df9f7323090b5eaf8cd5582438d122b4 to your computer and use it in GitHub Desktop.
KeyPath
This file contains hidden or 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
// ------------------------------------ | |
// Network | |
// ------------------------------------ | |
struct MeetupResponse { | |
var groupName: String = "" | |
var groupOrganizers: [String] = [] | |
var meetupTitle: String = "" | |
var meetupAttendes: Int = 0 | |
var meetupSpeakers: [String]? = nil | |
} | |
// ------------------------------------ | |
// Domain | |
// ------------------------------------ | |
struct MeetupGroup { | |
var name: String = "" | |
var organizers: [String] = [] | |
var event: MeetupEvent = MeetupEvent() | |
} | |
struct MeetupEvent { | |
var title: String = "" | |
var attendes: Int = 0 | |
var speakers: [String]? = nil | |
} | |
// ------------------------------------ | |
// Binding | |
// ------------------------------------ | |
struct Binding<L, R> { | |
var left: (L, R) -> L | |
var right: (R, L) -> R | |
init<V>(_ left: WritableKeyPath<L, V>, _ right: WritableKeyPath<R, V>){ | |
self.left = { l, r in | |
var lx = l | |
lx[keyPath: left] = r[keyPath: right] | |
return lx | |
} | |
self.right = { r, l in | |
var rx = r | |
rx[keyPath: right] = l[keyPath: left] | |
return rx | |
} | |
} | |
} | |
// ------------------------------------ | |
// Binding operator | |
// ------------------------------------ | |
precedencegroup BindGroup {} | |
infix operator ~ : BindGroup | |
func ~ <L, R, V>(lhs: WritableKeyPath<L, V>, rhs: WritableKeyPath<R, V>) -> Binding<L, R> { | |
return Binding(lhs, rhs) | |
} | |
// ------------------------------------ | |
// Binding | |
// ------------------------------------ | |
let bindings = [ | |
\MeetupResponse.groupOrganizers ~ \MeetupGroup.organizers, | |
\.groupName ~ \.name, | |
\.meetupTitle ~ \.event.title, | |
\.meetupAttendes ~ \.event.attendes, | |
\.meetupSpeakers ~ \.event.speakers | |
] | |
// ------------------------------------ | |
// Map from Response to Domain and back | |
// ------------------------------------ | |
var r = MeetupResponse() | |
r.groupName = "group" | |
r.groupOrganizers = ["a", "b"] | |
r.meetupTitle = "Meetup title" | |
r.meetupAttendes = 12 | |
r.meetupSpeakers = ["1", "2"] | |
let meetup = bindings.reduce(MeetupGroup()) { group, binding in binding.right(group, r) } | |
let meetupResponse = bindings.reduce(MeetupResponse()) { group, binding in binding.left(group, meetup) } | |
print(meetupResponse) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment