Skip to content

Instantly share code, notes, and snippets.

@elm4ward
Created September 8, 2017 07:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save elm4ward/df9f7323090b5eaf8cd5582438d122b4 to your computer and use it in GitHub Desktop.
Save elm4ward/df9f7323090b5eaf8cd5582438d122b4 to your computer and use it in GitHub Desktop.
KeyPath
// ------------------------------------
// 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