Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Created September 28, 2019 13:02
Show Gist options
  • Save oleksii-demedetskyi/725e50bf0beb0d0946ac559a4faba227 to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/725e50bf0beb0d0946ac559a4faba227 to your computer and use it in GitHub Desktop.
import Cocoa
struct State {
var posts: [Post.ID: Post]
var users: [User.ID: User]
var currentUser: User.ID?
}
struct Post {
var id: ID
var author: User.ID
var text: String
struct ID: Hashable {
var value: String
}
}
struct User {
var id: ID
var posts: [Post.ID]
var name: String
struct ID: Hashable {
var value: String
}
}
struct CurrentUserGuard {
func verify(state: State) {
if var user = state.currentUser {
assert(
state.users.keys.contains(user)
)
}
}
}
protocol Action {}
class Store<State> {
var state: State {
didSet {
observers.forEach {
$0.handler(self.state)
}
}
}
var reducer: (inout State, Action) -> ()
init(initial: State,
reducer: @escaping (inout State, Action) -> ())
{
self.state = initial
self.reducer = reducer
}
func dispatch(action: Action) {
reducer(&state, action)
}
var observers: Set<Observer> = []
class Observer: Hashable {
let handler: (State) -> ()
init(handler: @escaping (State) -> ()) {
self.handler = handler
}
static func == (lhs: Store<State>.Observer, rhs: Store<State>.Observer) -> Bool {
lhs === rhs
}
func hash(into hasher: inout Hasher) {
hasher.combine(ObjectIdentifier(self))
hasher.finalize()
}
}
}
let state = State(
posts: [:],
users: [:],
currentUser: nil
)
struct UserDidLogin: Action {
let id: User.ID
let name: String
}
let store = Store(initial: state) { state, action in
switch action {
case let action as UserDidLogin:
state.currentUser = action.id
state.users[action.id] = User(
id: action.id,
posts: [],
name: action.name
)
default: break
}
}
store.observers.insert(.init(
handler: CurrentUserGuard().verify)
)
store.dispatch(action: UserDidLogin(
id: .init(value: "20"), name: "Jonh")
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment