|
1 | 1 | extension ReducerProtocol {
|
2 |
| - /// Embeds a child reducer in a parent domain that works on elements of a collection in parent |
3 |
| - /// state. |
4 |
| - /// |
5 |
| - /// For example, if a parent feature holds onto an array of child states, then it can |
6 |
| - /// perform its core logic _and_ the child's logic by using the `forEach` operator: |
7 |
| - /// |
8 |
| - /// ```swift |
9 |
| - /// struct Parent: ReducerProtocol { |
10 |
| - /// struct State { |
11 |
| - /// var rows: IdentifiedArrayOf<Row.State> |
12 |
| - /// // ... |
13 |
| - /// } |
14 |
| - /// enum Action { |
15 |
| - /// case row(id: Row.State.ID, action: Row.Action) |
16 |
| - /// // ... |
17 |
| - /// } |
18 |
| - /// |
19 |
| - /// var body: some ReducerProtocol<State, Action> { |
20 |
| - /// Reduce { state, action in |
21 |
| - /// // Core logic for parent feature |
22 |
| - /// } |
23 |
| - /// .forEach(\.rows, action: /Action.row) { |
24 |
| - /// Row() |
25 |
| - /// } |
26 |
| - /// } |
27 |
| - /// } |
28 |
| - /// ``` |
29 |
| - /// |
30 |
| - /// > Tip: We are using `IdentifiedArray` from our |
31 |
| - /// [Identified Collections][swift-identified-collections] library because it provides a safe and |
32 |
| - /// ergonomic API for accessing elements from a stable ID rather than positional indices. |
33 |
| - /// |
34 |
| - /// The `forEach` forces a specific order of operations for the child and parent features. It runs |
35 |
| - /// the child first, and then the parent. If the order was reversed, then it would be possible for |
36 |
| - /// the parent feature to remove the child state from the array, in which case the child feature |
37 |
| - /// would not be able to react to that action. That can cause subtle bugs. |
38 |
| - /// |
39 |
| - /// It is still possible for a parent feature higher up in the application to remove the child |
40 |
| - /// state from the array before the child has a chance to react to the action. In such cases a |
41 |
| - /// runtime warning is shown in Xcode to let you know that there's a potential problem. |
42 |
| - /// |
43 |
| - /// [swift-identified-collections]: http://github.com/pointfreeco/swift-identified-collections |
44 |
| - /// |
45 |
| - /// - Parameters: |
46 |
| - /// - toElementsState: A writable key path from parent state to an `IdentifiedArray` of child |
47 |
| - /// state. |
48 |
| - /// - toElementAction: A case path from parent action to child identifier and child actions. |
49 |
| - /// - element: A reducer that will be invoked with child actions against elements of child |
50 |
| - /// state. |
51 |
| - /// - Returns: A reducer that combines the child reducer with the parent reducer. |
52 |
| - @inlinable |
53 |
| - public func forEach<ID: Hashable, Element: ReducerProtocol>( |
54 |
| - _ toElementsState: WritableKeyPath<State, IdentifiedArray<ID, Element.State>>, |
55 |
| - action toElementAction: CasePath<Action, (ID, Element.Action)>, |
56 |
| - @ReducerBuilderOf<Element> _ element: () -> Element, |
57 |
| - file: StaticString = #file, |
58 |
| - fileID: StaticString = #fileID, |
59 |
| - line: UInt = #line |
60 |
| - ) -> _ForEachReducer<Self, ID, Element> { |
61 |
| - _ForEachReducer( |
62 |
| - parent: self, |
63 |
| - toElementsState: toElementsState, |
64 |
| - toElementAction: toElementAction, |
65 |
| - element: element(), |
66 |
| - file: file, |
67 |
| - fileID: fileID, |
68 |
| - line: line |
69 |
| - ) |
70 |
| - } |
| 2 | + #if swift(>=5.7) |
| 3 | + /// Embeds a child reducer in a parent domain that works on elements of a collection in parent |
| 4 | + /// state. |
| 5 | + /// |
| 6 | + /// For example, if a parent feature holds onto an array of child states, then it can perform |
| 7 | + /// its core logic _and_ the child's logic by using the `forEach` operator: |
| 8 | + /// |
| 9 | + /// ```swift |
| 10 | + /// struct Parent: ReducerProtocol { |
| 11 | + /// struct State { |
| 12 | + /// var rows: IdentifiedArrayOf<Row.State> |
| 13 | + /// // ... |
| 14 | + /// } |
| 15 | + /// enum Action { |
| 16 | + /// case row(id: Row.State.ID, action: Row.Action) |
| 17 | + /// // ... |
| 18 | + /// } |
| 19 | + /// |
| 20 | + /// var body: some ReducerProtocol<State, Action> { |
| 21 | + /// Reduce { state, action in |
| 22 | + /// // Core logic for parent feature |
| 23 | + /// } |
| 24 | + /// .forEach(\.rows, action: /Action.row) { |
| 25 | + /// Row() |
| 26 | + /// } |
| 27 | + /// } |
| 28 | + /// } |
| 29 | + /// ``` |
| 30 | + /// |
| 31 | + /// > Tip: We are using `IdentifiedArray` from our |
| 32 | + /// [Identified Collections][swift-identified-collections] library because it provides a safe |
| 33 | + /// and ergonomic API for accessing elements from a stable ID rather than positional indices. |
| 34 | + /// |
| 35 | + /// The `forEach` forces a specific order of operations for the child and parent features. It |
| 36 | + /// runs the child first, and then the parent. If the order was reversed, then it would be |
| 37 | + /// possible for the parent feature to remove the child state from the array, in which case the |
| 38 | + /// child feature would not be able to react to that action. That can cause subtle bugs. |
| 39 | + /// |
| 40 | + /// It is still possible for a parent feature higher up in the application to remove the child |
| 41 | + /// state from the array before the child has a chance to react to the action. In such cases a |
| 42 | + /// runtime warning is shown in Xcode to let you know that there's a potential problem. |
| 43 | + /// |
| 44 | + /// [swift-identified-collections]: http://github.com/pointfreeco/swift-identified-collections |
| 45 | + /// |
| 46 | + /// - Parameters: |
| 47 | + /// - toElementsState: A writable key path from parent state to an `IdentifiedArray` of child |
| 48 | + /// state. |
| 49 | + /// - toElementAction: A case path from parent action to child identifier and child actions. |
| 50 | + /// - element: A reducer that will be invoked with child actions against elements of child |
| 51 | + /// state. |
| 52 | + /// - Returns: A reducer that combines the child reducer with the parent reducer. |
| 53 | + @inlinable |
| 54 | + public func forEach<ID: Hashable, ElementState, ElementAction>( |
| 55 | + _ toElementsState: WritableKeyPath<State, IdentifiedArray<ID, ElementState>>, |
| 56 | + action toElementAction: CasePath<Action, (ID, ElementAction)>, |
| 57 | + @ReducerBuilder<ElementState, ElementAction> _ element: () -> some ReducerProtocol< |
| 58 | + ElementState, ElementAction |
| 59 | + >, |
| 60 | + file: StaticString = #file, |
| 61 | + fileID: StaticString = #fileID, |
| 62 | + line: UInt = #line |
| 63 | + ) -> some ReducerProtocol<State, Action> { |
| 64 | + _ForEachReducer( |
| 65 | + parent: self, |
| 66 | + toElementsState: toElementsState, |
| 67 | + toElementAction: toElementAction, |
| 68 | + element: element(), |
| 69 | + file: file, |
| 70 | + fileID: fileID, |
| 71 | + line: line |
| 72 | + ) |
| 73 | + } |
| 74 | + #else |
| 75 | + @inlinable |
| 76 | + public func forEach<ID: Hashable, Element: ReducerProtocol>( |
| 77 | + _ toElementsState: WritableKeyPath<State, IdentifiedArray<ID, Element.State>>, |
| 78 | + action toElementAction: CasePath<Action, (ID, Element.Action)>, |
| 79 | + @ReducerBuilderOf<Element> _ element: () -> Element, |
| 80 | + file: StaticString = #file, |
| 81 | + fileID: StaticString = #fileID, |
| 82 | + line: UInt = #line |
| 83 | + ) -> _ForEachReducer<Self, ID, Element> { |
| 84 | + _ForEachReducer( |
| 85 | + parent: self, |
| 86 | + toElementsState: toElementsState, |
| 87 | + toElementAction: toElementAction, |
| 88 | + element: element(), |
| 89 | + file: file, |
| 90 | + fileID: fileID, |
| 91 | + line: line |
| 92 | + ) |
| 93 | + } |
| 94 | + #endif |
71 | 95 | }
|
72 | 96 |
|
73 | 97 | public struct _ForEachReducer<
|
|
0 commit comments