Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Last active August 9, 2019 10:38
Show Gist options
  • Save oleksii-demedetskyi/e9b5f3aaf321a9cdb8bca6cb763ead8d to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/e9b5f3aaf321a9cdb8bca6cb763ead8d to your computer and use it in GitHub Desktop.
Combine reducers together with state that they are represent into single structure.
//
// main.swift
// ReducerComponents
//
// Created by Alexey Demedetskii on 6/19/19.
// Copyright © 2019 Sigma software. All rights reserved.
//
import Foundation
protocol Action {}
protocol Component {
associatedtype State
var state: State { get }
mutating func reduce(action: Action)
}
protocol ComponentGroup: Component {}
@dynamicMemberLookup
struct ComponentState<C: ComponentGroup> {
private let component: C
init(component: C) {
self.component = component
}
subscript<Subject>(dynamicMember keyPath: KeyPath<C, Subject>)
-> Subject.State where Subject: Component {
component[keyPath: keyPath].state
}
}
extension ComponentGroup {
var state: ComponentState<Self> {
ComponentState(component: self)
}
}
struct Increment: Action {}
struct Decrement: Action {}
struct Counter: Component {
var state = 0
mutating func reduce(action: Action) {
switch action {
case is Increment: state += 1
case is Decrement: state -= 1
default: break
}
}
}
struct CounterPair: ComponentGroup {
var left = Counter()
var right = Counter()
mutating func reduce(action: Action) {
left.reduce(action: action)
right.reduce(action: action)
}
}
struct App: ComponentGroup {
var first = CounterPair()
var second = CounterPair()
mutating func reduce(action: Action) {
first.reduce(action: action)
second.reduce(action: action)
}
}
var app = App()
app.reduce(action: Increment())
print(app.state.first.left)
final class Store<Root> where Root: Component {
init(root: Root) {
self.root = root
}
private var root: Root
func dispatch(action: Action) {
root.reduce(action: action)
}
var state: Root.State { root.state }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment