Skip to content

Commit d2d3c14

Browse files
authored
Add BindingViewStore initializers for ViewStore (#2274)
1 parent 55029c2 commit d2d3c14

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

Sources/ComposableArchitecture/SwiftUI/Binding.swift

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,106 @@ extension WithViewStore where ViewState: Equatable, Content: View {
407407
}
408408
}
409409

410+
extension ViewStore {
411+
/// Initializes a view store from a store in order to compute bindings from state.
412+
///
413+
/// Read <doc:Bindings> for more information.
414+
///
415+
/// - Parameters:
416+
/// - store: A store.
417+
/// - toViewState: A function that transforms binding store state into observable view state.
418+
/// All changes to the view state will cause the `ViewStore` to publish the changes.
419+
/// - fromViewAction: A function that transforms a view action into a store action.
420+
/// - isDuplicate: A function to determine when two `ViewState` values are equal. When values
421+
/// are equal, repeat changes are not published.
422+
public convenience init<State, Action>(
423+
_ store: Store<State, Action>,
424+
observe toViewState: @escaping (BindingViewStore<State>) -> ViewState,
425+
send fromViewAction: @escaping (ViewAction) -> Action,
426+
removeDuplicates isDuplicate: @escaping (ViewState, ViewState) -> Bool
427+
) where ViewAction: BindableAction, ViewAction.State == State {
428+
self.init(
429+
store,
430+
observe: { (_: State) in
431+
toViewState(
432+
BindingViewStore(
433+
// TODO: Can we avoid this store scoping?
434+
store: store.scope(state: { $0 }, action: fromViewAction)
435+
)
436+
)
437+
},
438+
send: fromViewAction,
439+
removeDuplicates: isDuplicate
440+
)
441+
}
442+
443+
/// Initializes a view store from a store in order to compute bindings from state.
444+
///
445+
/// Read <doc:Bindings> for more information.
446+
///
447+
/// - Parameters:
448+
/// - store: A store.
449+
/// - toViewState: A function that transforms binding store state into observable view state.
450+
/// All changes to the view state will cause the `ViewStore` to publish the changes.
451+
/// - isDuplicate: A function to determine when two `ViewState` values are equal. When values
452+
/// are equal, repeat changes are not published.
453+
public convenience init<State>(
454+
_ store: Store<State, ViewAction>,
455+
observe toViewState: @escaping (BindingViewStore<State>) -> ViewState,
456+
removeDuplicates isDuplicate: @escaping (ViewState, ViewState) -> Bool
457+
) where ViewAction: BindableAction, ViewAction.State == State {
458+
self.init(
459+
store,
460+
observe: toViewState,
461+
send: { $0 },
462+
removeDuplicates: isDuplicate
463+
)
464+
}
465+
}
466+
467+
extension ViewStore where ViewState: Equatable {
468+
/// Initializes a view store from a store in order to compute bindings from state.
469+
///
470+
/// Read <doc:Bindings> for more information.
471+
///
472+
/// - Parameters:
473+
/// - store: A store.
474+
/// - toViewState: A function that transforms binding store state into observable view state.
475+
/// All changes to the view state will cause the `ViewStore` to publish the changes.
476+
/// - fromViewAction: A function that transforms a view action into a store action.
477+
public convenience init<State, Action>(
478+
_ store: Store<State, Action>,
479+
observe toViewState: @escaping (BindingViewStore<State>) -> ViewState,
480+
send fromViewAction: @escaping (ViewAction) -> Action
481+
) where ViewAction: BindableAction, ViewAction.State == State {
482+
self.init(
483+
store,
484+
observe: toViewState,
485+
send: fromViewAction,
486+
removeDuplicates: ==
487+
)
488+
}
489+
490+
/// Initializes a view store from a store in order to compute bindings from state.
491+
///
492+
/// Read <doc:Bindings> for more information.
493+
///
494+
/// - Parameters:
495+
/// - store: A store.
496+
/// - toViewState: A function that transforms binding store state into observable view state.
497+
/// All changes to the view state will cause the `ViewStore` to publish the changes.
498+
public convenience init<State>(
499+
_ store: Store<State, ViewAction>,
500+
observe toViewState: @escaping (BindingViewStore<State>) -> ViewState
501+
) where ViewAction: BindableAction, ViewAction.State == State {
502+
self.init(
503+
store,
504+
observe: toViewState,
505+
removeDuplicates: ==
506+
)
507+
}
508+
}
509+
410510
extension ViewStore where ViewAction: BindableAction, ViewAction.State == ViewState {
411511
@MainActor
412512
public subscript<Value: Equatable>(

0 commit comments

Comments
 (0)