-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathEffectRouterDSL.swift
More file actions
110 lines (101 loc) · 4.02 KB
/
EffectRouterDSL.swift
File metadata and controls
110 lines (101 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright Spotify AB.
// SPDX-License-Identifier: Apache-2.0
import Dispatch
public extension EffectRouter where Effect: Equatable {
/// Add a route for effects which are equal to `constant`.
///
/// - Parameter `constant`: the effect that should be handled by this route.
func routeEffects(
equalTo constant: Effect
) -> _PartialEffectRouter<Effect, Effect, Event> {
return routeEffects(withParameters: { effect in effect == constant ? effect : nil })
}
}
public extension _PartialEffectRouter {
/// Route to the anonymous `EffectHandler` defined by the `handle` closure.
///
/// - Parameter handle: A closure which defines an `EffectHandler`.
func to(
_ handle: @escaping (EffectParameters, EffectCallback<Event>) -> Disposable
) -> EffectRouter<Effect, Event> {
return to(AnyEffectHandler(handle: handle))
}
/// Route to a side-effecting closure.
///
/// - Parameter fireAndForget: a function which given some input carries out a side effect.
func to(
_ fireAndForget: @escaping (EffectParameters) -> Void
) -> EffectRouter<Effect, Event> {
return to { parameters, callback in
fireAndForget(parameters)
callback.end()
return AnonymousDisposable {}
}
}
/// Route main-isolated effects through the same queue path as `.on(queue: .main)`.
///
/// This returns a dedicated builder exposing `to(...)` for `@MainActor` closures.
#if compiler(>=5.10)
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
func onMainActor() -> _MainActorPartialEffectRouter<Effect, EffectParameters, Event> {
return _MainActorPartialEffectRouter(partialRouter: on(queue: .main))
}
#endif
/// Route to a closure which returns an optional event when given the parameters as input.
///
/// - Parameter eventClosure: a function which returns an optional event given some input. No events will be
/// propagated if this function returns `nil`.
func toEvent(
_ eventClosure: @escaping (EffectParameters) -> Event?
) -> EffectRouter<Effect, Event> {
return to { parameters, callback in
if let event = eventClosure(parameters) {
callback.send(event)
}
callback.end()
return AnonymousDisposable {}
}
}
}
#if compiler(>=5.10)
/// A `_MainActorPartialEffectRouter` represents the state between an `onMainActor` call and a `to`.
///
/// Client code should not refer to this type directly.
public struct _MainActorPartialEffectRouter<Effect, EffectParameters, Event> {
fileprivate let partialRouter: _PartialEffectRouter<Effect, EffectParameters, Event>
}
public extension _MainActorPartialEffectRouter {
/// Route to a `@MainActor` side-effecting closure.
///
/// Dispatches through the `.on(queue: .main)` path and assumes actor isolation once scheduled on the main queue.
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
func to(
_ fireAndForget: @MainActor @escaping (EffectParameters) -> Void
) -> EffectRouter<Effect, Event> {
return partialRouter.to { parameters, callback in
MainActor.assumeIsolated {
fireAndForget(parameters)
}
callback.end()
return AnonymousDisposable {}
}
}
}
public extension _MainActorPartialEffectRouter where EffectParameters == Void {
/// Route to a `@MainActor` side-effecting closure with no input parameters.
///
/// Dispatches through the `.on(queue: .main)` path and assumes actor isolation once scheduled on the main queue.
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
func to(
_ fireAndForget: @MainActor @escaping () -> Void
) -> EffectRouter<Effect, Event> {
return partialRouter.to { _, callback in
MainActor.assumeIsolated {
fireAndForget()
}
callback.end()
return AnonymousDisposable {}
}
}
}
#endif