Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Created June 18, 2019 09:34
Show Gist options
  • Save oleksii-demedetskyi/ba70deee27f0b2a072e1f95240788203 to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/ba70deee27f0b2a072e1f95240788203 to your computer and use it in GitHub Desktop.
Proxy object for registering object reads.
import Cocoa
protocol ImplicitlyConvertible {
associatedtype ConversionResult
func convert() -> ConversionResult
}
@dynamicMemberLookup
struct Reader<State>: ImplicitlyConvertible {
let state: State
let registerRead: (PartialKeyPath<State>) -> Void
subscript<Value>(dynamicMember keyPath: KeyPath<State,Value>) -> Reader<Value> {
return Reader<Value>(state: state[keyPath: keyPath]) { innerKeyPath in
let outerPath = keyPath as PartialKeyPath<State>
guard let fullKeyPath = outerPath.appending(path: innerKeyPath) else {
fatalError("Not matching key path")
}
self.registerRead(fullKeyPath)
}
}
func convert() -> State {
registerRead(\.self)
return state
}
}
postfix operator ~
postfix func ~<T>(value: T) -> T.ConversionResult where T: ImplicitlyConvertible {
value.convert()
}
struct CounterPair {
let left: Int
let right: Int
}
struct AppState {
let counter: Int
let history: [Int]
let pair: CounterPair
}
struct Props {
let currentValue: Int
}
func map(state: Reader<AppState>) -> Props {
return Props(currentValue: state.pair.left~)
}
let state = AppState(counter: 10, history: [], pair: CounterPair(left: 20, right: 30))
let reader = Reader(state: state) { kp in
print(kp)
}
let props = map(state: reader)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment