Skip to content

Commit

Permalink
Add redispatch function to reducer
Browse files Browse the repository at this point in the history
  • Loading branch information
Qata committed Jul 2, 2021
1 parent df3250e commit bc519a6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 28 deletions.
36 changes: 18 additions & 18 deletions Sources/RecombinePackage/Reducer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public protocol Reducer {
var transform: Transform { get }
init()
init(_ transform: Transform)
func reduce(state: State, action: Action) -> State
func reduce(state: State, action: Action, redispatch: (Action...) -> Void) -> State
func concat<R: Reducer>(_ other: R) -> Self where R.Transform == Transform
}

Expand All @@ -23,58 +23,58 @@ public extension Reducer {
}

public struct PureReducer<State, Action>: Reducer {
public typealias Transform = (_ state: State, _ action: Action) -> State
public typealias Transform = (_ state: State, _ action: Action, _ redispatch: (Action...) -> Void) -> State
public let transform: Transform

public init() {
transform = { state, _ in state }
transform = { state, _, _ in state }
}

public init(_ transform: @escaping Transform) {
self.transform = transform
}

public func callAsFunction(state: State, action: Action) -> State {
transform(state, action)
public func callAsFunction(state: State, action: Action, redispatch: (Action...) -> Void) -> State {
transform(state, action, redispatch)
}

public func concat<R: Reducer>(_ other: R) -> Self where R.Transform == Transform {
Self.init { state, action in
other.transform(self.transform(state, action), action)
Self.init { state, action, redispatch in
other.transform(self.transform(state, action, redispatch), action, redispatch)
}
}

public func reduce(state: State, action: Action) -> State {
transform(state, action)
public func reduce(state: State, action: Action, redispatch: (Action...) -> Void) -> State {
transform(state, action, redispatch)
}
}

public struct MutatingReducer<State, Action>: Reducer {
public typealias Transform = (_ state: inout State, _ action: Action) -> Void
public typealias Transform = (_ state: inout State, _ action: Action, _ redispatch: (Action...) -> Void) -> Void
public let transform: Transform

public init() {
transform = { _, _ in }
transform = { _, _, _ in }
}

public init(_ transform: @escaping Transform) {
self.transform = transform
}

public func callAsFunction(state: inout State, action: Action) {
transform(&state, action)
public func callAsFunction(state: inout State, action: Action, redispatch: (Action...) -> Void) {
transform(&state, action, redispatch)
}

public func concat<R: Reducer>(_ other: R) -> Self where R.Transform == Transform {
Self.init { state, action in
self.transform(&state, action)
other.transform(&state, action)
Self.init { state, action, redispatch in
self.transform(&state, action, redispatch)
other.transform(&state, action, redispatch)
}
}

public func reduce(state: State, action: Action) -> State {
public func reduce(state: State, action: Action, redispatch: (Action...) -> Void) -> State {
var s = state
transform(&s, action)
transform(&s, action, redispatch)
return s
}
}
6 changes: 4 additions & 2 deletions Sources/RecombinePackage/Store/BaseStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@ public class BaseStore<State: Equatable, RawAction, RefinedAction>: StoreProtoco
.store(in: &cancellables)

postMiddlewareRefinedActions
.scan(state) { state, actions in
actions.reduce(state, reducer.reduce)
.scan(state) { [weak self] state, actions in
actions.reduce(state) {
reducer.reduce(state: $0, action: $1, redispatch: { self?.dispatch(refined: $0) })
}
}
.receive(on: scheduler)
.sink { [weak self] state in
Expand Down
10 changes: 5 additions & 5 deletions Tests/RecombineTests/ReducerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ class MockReducerContainer<Action> {
var reducer: MutatingReducer<TestFakes.CounterTest.State, Action>!

init() {
reducer = .init { _, action in
reducer = .init { _, action, _ in
self.calledWithAction.append(action)
}
}
}

let increaseByOneReducer: MutatingReducer<TestFakes.CounterTest.State, TestFakes.SetAction> = .init { state, _ in
let increaseByOneReducer: MutatingReducer<TestFakes.CounterTest.State, TestFakes.SetAction> = .init { state, _, _ in
state.count += 1
}

let increaseByTwoReducer: MutatingReducer<TestFakes.CounterTest.State, TestFakes.SetAction> = .init { state, _ in
let increaseByTwoReducer: MutatingReducer<TestFakes.CounterTest.State, TestFakes.SetAction> = .init { state, _, _ in
state.count += 2
}

Expand All @@ -30,7 +30,7 @@ class ReducerTests: XCTestCase {
let combinedReducer = MutatingReducer(mockReducer1.reducer, mockReducer2.reducer)

var state = TestFakes.CounterTest.State()
_ = combinedReducer.transform(&state, .noop)
_ = combinedReducer.transform(&state, .noop) { (_: TestFakes.SetAction...) in }

XCTAssertEqual(mockReducer1.calledWithAction.count, 1)
XCTAssertEqual(mockReducer2.calledWithAction.count, 1)
Expand All @@ -44,7 +44,7 @@ class ReducerTests: XCTestCase {
func testCombinesReducerResults() {
let combinedReducer = MutatingReducer(increaseByOneReducer, increaseByTwoReducer)
var state = TestFakes.CounterTest.State()
combinedReducer.transform(&state, .noop)
combinedReducer.transform(&state, .noop) { (_: TestFakes.SetAction...) in }

XCTAssertEqual(state.count, 3)
}
Expand Down
6 changes: 3 additions & 3 deletions Tests/RecombineTests/TestFakes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ extension TestFakes {
var subState: SubState = .init()
}

static let reducer: MutatingReducer<State, Action> = .init { state, action in
static let reducer: MutatingReducer<State, Action> = .init { state, action, _ in
switch action {
case let .sub(.set(value)):
state.subState.value = value
Expand All @@ -61,7 +61,7 @@ extension TestFakes {
var value: String?
}

static let reducer = MutatingReducer<State, SetAction> { state, action in
static let reducer = MutatingReducer<State, SetAction> { state, action, _ in
switch action {
case let .string(value):
state.value = value
Expand All @@ -78,7 +78,7 @@ extension TestFakes {
var value: Int?
}

static let reducer = MutatingReducer<State, SetAction> { state, action in
static let reducer = MutatingReducer<State, SetAction> { state, action, _ in
switch action {
case let .int(value):
state.value = value
Expand Down

0 comments on commit bc519a6

Please sign in to comment.