Skip to content

Instantly share code, notes, and snippets.

@swift2931
Created August 18, 2019 12:35
Show Gist options
  • Save swift2931/6c9fb7fb828777a50860be2b9ae05fe0 to your computer and use it in GitHub Desktop.
Save swift2931/6c9fb7fb828777a50860be2b9ae05fe0 to your computer and use it in GitHub Desktop.
Elf
//
// Redux.swift
// Elf
//
// Created by JimLai on 2019/8/18.
// Copyright © 2019 JimLai. All rights reserved.
//
import SwiftUI
protocol Redux {
associatedtype Store
var binding: Binding<Store> {get}
var store: Store {get}
var action: Action<Store> {get}
func effect(desc: String, _ action: Action<Store>)
}
extension Redux {
var store: Store {
binding.value
}
var action: Action<Store> {
var s = store
let b = Binding<Store>(get: {s}, set: {s = $0})
return Action<Store>(binding: b)
}
func effect(desc: String = #function, _ action: Action<Store>) {
binding.value = action.binding.value
}
}
@dynamicMemberLookup
struct Action<T> {
var binding: Binding<T>
subscript<V>(dynamicMember kp: WritableKeyPath<T, V>) -> V {
get {
binding.value[keyPath: kp]
}
nonmutating set {
binding.value[keyPath: kp] = newValue
debug(kp, newValue)
}
}
func map(_ transform: (Action<T>) -> Void) -> Action<T> {
var s = binding.value
let b = Binding<T>(get: {s}, set: {s = $0})
let action = Action<T>(binding: b)
transform(action)
return action
}
func debug<V>(_ kp: WritableKeyPath<T, V>, _ v: V) {
#if DEBUG
let mirror = Mirror(reflecting: binding.value)
for c in mirror.children {
guard c.value as AnyObject === binding.value[keyPath: kp] as AnyObject else {continue}
print("\(c.label ?? "") <- \(v)")
}
#endif
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment