@@ -405,58 +405,57 @@ public struct Reducer<State, Action, Environment> {
405405 . map { toLocalAction. embed ( ( index, $0) ) }
406406 }
407407 }
408-
409- #if canImport(SwiftUI)
410- /// A version of `pullback` that transforms a reducer that works on an element into one that works
411- /// on an identified array of elements.
412- ///
413- /// // Global domain that holds a collection of local domains:
414- /// struct AppState { var todos: IdentifiedArrayOf<Todo> }
415- /// struct AppAction { case todo(id: Todo.ID, action: TodoAction) }
416- /// struct AppEnvironment { var mainQueue: DateScheduler }
417- ///
418- /// // A reducer that works on a local domain:
419- /// let todoReducer = Reducer<Todo, TodoAction, TodoEnvironment> { ... }
420- ///
421- /// // Pullback the local todo reducer so that it works on all of the app domain:
422- /// let appReducer = Reducer<AppState, AppAction, AppEnvironment>.combine(
423- /// todoReducer.forEach(
424- /// state: \.todos,
425- /// action: /AppAction.todo(id:action:),
426- /// environment: { _ in TodoEnvironment() }
427- /// ),
428- /// Reducer { state, action, environment in
429- /// ...
430- /// }
431- /// )
432- ///
433- /// Take care when combining `forEach` reducers into parent domains, as order matters. Always
434- /// combine `forEach` reducers _before_ parent reducers that can modify the collection.
435- ///
436- /// - Parameters:
437- /// - toLocalState: A key path that can get/set a collection of `State` elements inside
438- /// `GlobalState`.
439- /// - toLocalAction: A case path that can extract/embed `(Collection.Index, Action)` from
440- /// `GlobalAction`.
441- /// - toLocalEnvironment: A function that transforms `GlobalEnvironment` into `Environment`.
442- /// - Returns: A reducer that works on `GlobalState`, `GlobalAction`, `GlobalEnvironment`.
443- @available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
444- public func forEach< GlobalState, GlobalAction, GlobalEnvironment, ID> (
445- state toLocalState: WritableKeyPath < GlobalState , IdentifiedArray < ID , State > > ,
446- action toLocalAction: CasePath < GlobalAction , ( ID , Action ) > ,
447- environment toLocalEnvironment: @escaping ( GlobalEnvironment ) -> Environment ,
448- _ file: StaticString = #file,
449- _ line: UInt = #line
450- ) -> Reducer < GlobalState , GlobalAction , GlobalEnvironment > {
451- . init { globalState, globalAction, globalEnvironment in
452- guard let ( id, localAction) = toLocalAction. extract ( from: globalAction) else {
453- return . none
454- }
455-
456- // This does not need to be a fatal error because of the unwrap that follows it.
457- assert (
458- globalState [ keyPath: toLocalState] [ id: id] != nil ,
459- """
408+
409+ /// A version of `pullback` that transforms a reducer that works on an element into one that works
410+ /// on an identified array of elements.
411+ ///
412+ /// // Global domain that holds a collection of local domains:
413+ /// struct AppState { var todos: IdentifiedArrayOf<Todo> }
414+ /// struct AppAction { case todo(id: Todo.ID, action: TodoAction) }
415+ /// struct AppEnvironment { var mainQueue: DateScheduler }
416+ ///
417+ /// // A reducer that works on a local domain:
418+ /// let todoReducer = Reducer<Todo, TodoAction, TodoEnvironment> { ... }
419+ ///
420+ /// // Pullback the local todo reducer so that it works on all of the app domain:
421+ /// let appReducer = Reducer<AppState, AppAction, AppEnvironment>.combine(
422+ /// todoReducer.forEach(
423+ /// state: \.todos,
424+ /// action: /AppAction.todo(id:action:),
425+ /// environment: { _ in TodoEnvironment() }
426+ /// ),
427+ /// Reducer { state, action, environment in
428+ /// ...
429+ /// }
430+ /// )
431+ ///
432+ /// Take care when combining `forEach` reducers into parent domains, as order matters. Always
433+ /// combine `forEach` reducers _before_ parent reducers that can modify the collection.
434+ ///
435+ /// - Parameters:
436+ /// - toLocalState: A key path that can get/set a collection of `State` elements inside
437+ /// `GlobalState`.
438+ /// - toLocalAction: A case path that can extract/embed `(Collection.Index, Action)` from
439+ /// `GlobalAction`.
440+ /// - toLocalEnvironment: A function that transforms `GlobalEnvironment` into `Environment`.
441+ /// - Returns: A reducer that works on `GlobalState`, `GlobalAction`, `GlobalEnvironment`.
442+ @available ( iOS 13 . 0 , OSX 10 . 15 , tvOS 13 . 0 , watchOS 6 . 0 , * )
443+ public func forEach< GlobalState, GlobalAction, GlobalEnvironment, ID> (
444+ state toLocalState: WritableKeyPath < GlobalState , IdentifiedArray < ID , State > > ,
445+ action toLocalAction: CasePath < GlobalAction , ( ID , Action ) > ,
446+ environment toLocalEnvironment: @escaping ( GlobalEnvironment ) -> Environment ,
447+ _ file: StaticString = #file,
448+ _ line: UInt = #line
449+ ) -> Reducer < GlobalState , GlobalAction , GlobalEnvironment > {
450+ . init { globalState, globalAction, globalEnvironment in
451+ guard let ( id, localAction) = toLocalAction. extract ( from: globalAction) else {
452+ return . none
453+ }
454+
455+ // This does not need to be a fatal error because of the unwrap that follows it.
456+ assert (
457+ globalState [ keyPath: toLocalState] [ id: id] != nil ,
458+ """
460459 " \( debugCaseOutput ( localAction) ) " was received by a " forEach " reducer at id \( id) \
461460 when its state contained no element at this id. This is considered an application logic \
462461 error, and can happen for a few reasons:
@@ -476,21 +475,20 @@ public struct Reducer<State, Action, Environment> {
476475 To fix this make sure that actions for this reducer can only be sent to a view store when \
477476 its state contains an element at this id. In SwiftUI applications, use `ForEachStore`.
478477 """ ,
479- file: file,
480- line: line
478+ file: file,
479+ line: line
480+ )
481+
482+ return
483+ self
484+ . reducer (
485+ & globalState[ keyPath: toLocalState] [ id: id] !,
486+ localAction,
487+ toLocalEnvironment ( globalEnvironment)
481488 )
482-
483- return
484- self
485- . reducer (
486- & globalState[ keyPath: toLocalState] [ id: id] !,
487- localAction,
488- toLocalEnvironment ( globalEnvironment)
489- )
490- . map { toLocalAction. embed ( ( id, $0) ) }
491- }
489+ . map { toLocalAction. embed ( ( id, $0) ) }
492490 }
493- #endif
491+ }
494492
495493 /// A version of `pullback` that transforms a reducer that works on an element into one that works
496494 /// on a dictionary of element values.
0 commit comments