Skip to content

Commit 3a4583b

Browse files
mluisbrownactions-user
authored andcommitted
Run swift-format
1 parent ce7a9d1 commit 3a4583b

File tree

2 files changed

+174
-173
lines changed

2 files changed

+174
-173
lines changed

Sources/ComposableArchitecture/SwiftUI/Binding.swift

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import CasePaths
2+
23
#if canImport(SwiftUI)
3-
import SwiftUI
4+
import SwiftUI
45
#endif
56

67
/// An action that describes simple mutations to some root state at a writable key path.
@@ -127,7 +128,7 @@ import SwiftUI
127128
///
128129
public struct BindingAction<Root>: Equatable {
129130
public let keyPath: PartialKeyPath<Root>
130-
131+
131132
fileprivate let set: (inout Root) -> Void
132133
private let value: Any
133134
private let valueIsEqualTo: (Any) -> Bool
@@ -214,34 +215,34 @@ extension Reducer {
214215
}
215216

216217
#if canImport(SwiftUI)
217-
extension ViewStore {
218-
/// Derives a binding from the store that mutates state at the given writable key path by wrapping
219-
/// a `BindingAction` with the store's action type.
220-
///
221-
/// For example, a text field binding can be created like this:
222-
///
223-
/// struct State { var text = "" }
224-
/// enum Action { case binding(BindingAction<State>) }
225-
///
226-
/// TextField(
227-
/// "Enter text",
228-
/// text: viewStore.binding(keyPath: \.text, Action.binding)
229-
/// )
230-
///
231-
/// - Parameters:
232-
/// - keyPath: A writable key path from the view store's state to a mutable field
233-
/// - action: A function that wraps a binding action in the view store's action type.
234-
/// - Returns: A binding.
235-
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
236-
public func binding<LocalState>(
237-
keyPath: WritableKeyPath<State, LocalState>,
238-
send action: @escaping (BindingAction<State>) -> Action
239-
) -> Binding<LocalState>
240-
where LocalState: Equatable {
241-
self.binding(
242-
get: { $0[keyPath: keyPath] },
243-
send: { action(.set(keyPath, $0)) }
244-
)
218+
extension ViewStore {
219+
/// Derives a binding from the store that mutates state at the given writable key path by wrapping
220+
/// a `BindingAction` with the store's action type.
221+
///
222+
/// For example, a text field binding can be created like this:
223+
///
224+
/// struct State { var text = "" }
225+
/// enum Action { case binding(BindingAction<State>) }
226+
///
227+
/// TextField(
228+
/// "Enter text",
229+
/// text: viewStore.binding(keyPath: \.text, Action.binding)
230+
/// )
231+
///
232+
/// - Parameters:
233+
/// - keyPath: A writable key path from the view store's state to a mutable field
234+
/// - action: A function that wraps a binding action in the view store's action type.
235+
/// - Returns: A binding.
236+
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
237+
public func binding<LocalState>(
238+
keyPath: WritableKeyPath<State, LocalState>,
239+
send action: @escaping (BindingAction<State>) -> Action
240+
) -> Binding<LocalState>
241+
where LocalState: Equatable {
242+
self.binding(
243+
get: { $0[keyPath: keyPath] },
244+
send: { action(.set(keyPath, $0)) }
245+
)
246+
}
245247
}
246-
}
247248
#endif
Lines changed: 142 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,158 @@
11
#if canImport(SwiftUI)
2-
import SwiftUI
2+
import SwiftUI
33

4-
/// A Composable Architecture-friendly wrapper around `ForEach` that simplifies working with
5-
/// collections of state.
6-
///
7-
/// `ForEachStore` loops over a store's collection with a store scoped to the domain of each
8-
/// element. This allows you to extract and modularize an element's view and avoid concerns around
9-
/// collection index math and parent-child store communication.
10-
///
11-
/// For example, a todos app may define the domain and logic associated with an individual todo:
12-
///
13-
/// struct TodoState: Equatable, Identifiable {
14-
/// let id: UUID
15-
/// var description = ""
16-
/// var isComplete = false
17-
/// }
18-
/// enum TodoAction {
19-
/// case isCompleteToggled(Bool)
20-
/// case descriptionChanged(String)
21-
/// }
22-
/// struct TodoEnvironment {}
23-
/// let todoReducer = Reducer<TodoState, TodoAction, TodoEnvironment { ... }
24-
///
25-
/// As well as a view with a domain-specific store:
26-
///
27-
/// struct TodoView: View {
28-
/// let store: Store<TodoState, TodoAction>
29-
/// var body: some View { ... }
30-
/// }
31-
///
32-
/// For a parent domain to work with a collection of todos, it can hold onto this collection in
33-
/// state:
34-
///
35-
/// struct AppState: Equatable {
36-
/// var todos: IdentifiedArrayOf<TodoState> = []
37-
/// }
38-
///
39-
/// Define a case to handle actions sent to the child domain:
40-
///
41-
/// enum AppAction {
42-
/// case todo(id: TodoState.ID, action: TodoAction)
43-
/// }
44-
///
45-
/// Enhance its reducer using `forEach`:
46-
///
47-
/// let appReducer = todoReducer.forEach(
48-
/// state: \.todos,
49-
/// action: /AppAction.todo(id:action:),
50-
/// environment: { _ in TodoEnvironment() }
51-
/// )
52-
///
53-
/// And finally render a list of `TodoView`s using `ForEachStore`:
54-
///
55-
/// ForEachStore(
56-
/// self.store.scope(state: \.todos, AppAction.todo(id:action:))
57-
/// ) { todoStore in
58-
/// TodoView(store: todoStore)
59-
/// }
60-
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
61-
public struct ForEachStore<EachState, EachAction, Data, ID, Content>: DynamicViewContent
62-
where Data: Collection, ID: Hashable, Content: View {
63-
public let data: Data
64-
private let content: () -> Content
65-
66-
/// Initializes a structure that computes views on demand from a store on an array of data and an
67-
/// indexed action.
4+
/// A Composable Architecture-friendly wrapper around `ForEach` that simplifies working with
5+
/// collections of state.
6+
///
7+
/// `ForEachStore` loops over a store's collection with a store scoped to the domain of each
8+
/// element. This allows you to extract and modularize an element's view and avoid concerns around
9+
/// collection index math and parent-child store communication.
10+
///
11+
/// For example, a todos app may define the domain and logic associated with an individual todo:
12+
///
13+
/// struct TodoState: Equatable, Identifiable {
14+
/// let id: UUID
15+
/// var description = ""
16+
/// var isComplete = false
17+
/// }
18+
/// enum TodoAction {
19+
/// case isCompleteToggled(Bool)
20+
/// case descriptionChanged(String)
21+
/// }
22+
/// struct TodoEnvironment {}
23+
/// let todoReducer = Reducer<TodoState, TodoAction, TodoEnvironment { ... }
24+
///
25+
/// As well as a view with a domain-specific store:
26+
///
27+
/// struct TodoView: View {
28+
/// let store: Store<TodoState, TodoAction>
29+
/// var body: some View { ... }
30+
/// }
31+
///
32+
/// For a parent domain to work with a collection of todos, it can hold onto this collection in
33+
/// state:
34+
///
35+
/// struct AppState: Equatable {
36+
/// var todos: IdentifiedArrayOf<TodoState> = []
37+
/// }
38+
///
39+
/// Define a case to handle actions sent to the child domain:
40+
///
41+
/// enum AppAction {
42+
/// case todo(id: TodoState.ID, action: TodoAction)
43+
/// }
44+
///
45+
/// Enhance its reducer using `forEach`:
6846
///
69-
/// - Parameters:
70-
/// - store: A store on an array of data and an indexed action.
71-
/// - id: A key path identifying an element.
72-
/// - content: A function that can generate content given a store of an element.
73-
public init<EachContent>(
74-
_ store: Store<Data, (Data.Index, EachAction)>,
75-
id: KeyPath<EachState, ID>,
76-
content: @escaping (Store<EachState, EachAction>) -> EachContent
77-
)
78-
where
79-
Data == [EachState],
80-
EachContent: View,
81-
Content == WithViewStore<
82-
[ID], (Data.Index, EachAction), ForEach<[(offset: Int, element: ID)], ID, EachContent>
83-
>
84-
{
85-
let data = store.state
86-
self.data = data
87-
self.content = {
88-
WithViewStore(store.scope(state: { $0.map { $0[keyPath: id] } })) { viewStore in
89-
ForEach(Array(viewStore.state.enumerated()), id: \.element) { index, _ in
90-
content(
91-
store.scope(
92-
state: { index < $0.endIndex ? $0[index] : data[index] },
93-
action: { (index, $0) }
47+
/// let appReducer = todoReducer.forEach(
48+
/// state: \.todos,
49+
/// action: /AppAction.todo(id:action:),
50+
/// environment: { _ in TodoEnvironment() }
51+
/// )
52+
///
53+
/// And finally render a list of `TodoView`s using `ForEachStore`:
54+
///
55+
/// ForEachStore(
56+
/// self.store.scope(state: \.todos, AppAction.todo(id:action:))
57+
/// ) { todoStore in
58+
/// TodoView(store: todoStore)
59+
/// }
60+
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
61+
public struct ForEachStore<EachState, EachAction, Data, ID, Content>: DynamicViewContent
62+
where Data: Collection, ID: Hashable, Content: View {
63+
public let data: Data
64+
private let content: () -> Content
65+
66+
/// Initializes a structure that computes views on demand from a store on an array of data and an
67+
/// indexed action.
68+
///
69+
/// - Parameters:
70+
/// - store: A store on an array of data and an indexed action.
71+
/// - id: A key path identifying an element.
72+
/// - content: A function that can generate content given a store of an element.
73+
public init<EachContent>(
74+
_ store: Store<Data, (Data.Index, EachAction)>,
75+
id: KeyPath<EachState, ID>,
76+
content: @escaping (Store<EachState, EachAction>) -> EachContent
77+
)
78+
where
79+
Data == [EachState],
80+
EachContent: View,
81+
Content == WithViewStore<
82+
[ID], (Data.Index, EachAction), ForEach<[(offset: Int, element: ID)], ID, EachContent>
83+
>
84+
{
85+
let data = store.state
86+
self.data = data
87+
self.content = {
88+
WithViewStore(store.scope(state: { $0.map { $0[keyPath: id] } })) { viewStore in
89+
ForEach(Array(viewStore.state.enumerated()), id: \.element) { index, _ in
90+
content(
91+
store.scope(
92+
state: { index < $0.endIndex ? $0[index] : data[index] },
93+
action: { (index, $0) }
94+
)
9495
)
95-
)
96+
}
9697
}
9798
}
9899
}
99-
}
100100

101-
/// Initializes a structure that computes views on demand from a store on an array of data and an
102-
/// indexed action.
103-
///
104-
/// - Parameters:
105-
/// - store: A store on an array of data and an indexed action.
106-
/// - content: A function that can generate content given a store of an element.
107-
public init<EachContent>(
108-
_ store: Store<Data, (Data.Index, EachAction)>,
109-
content: @escaping (Store<EachState, EachAction>) -> EachContent
110-
)
111-
where
112-
Data == [EachState],
113-
EachContent: View,
114-
Content == WithViewStore<
115-
[ID], (Data.Index, EachAction), ForEach<[(offset: Int, element: ID)], ID, EachContent>
116-
>,
117-
EachState: Identifiable,
118-
EachState.ID == ID
119-
{
120-
self.init(store, id: \.id, content: content)
121-
}
101+
/// Initializes a structure that computes views on demand from a store on an array of data and an
102+
/// indexed action.
103+
///
104+
/// - Parameters:
105+
/// - store: A store on an array of data and an indexed action.
106+
/// - content: A function that can generate content given a store of an element.
107+
public init<EachContent>(
108+
_ store: Store<Data, (Data.Index, EachAction)>,
109+
content: @escaping (Store<EachState, EachAction>) -> EachContent
110+
)
111+
where
112+
Data == [EachState],
113+
EachContent: View,
114+
Content == WithViewStore<
115+
[ID], (Data.Index, EachAction), ForEach<[(offset: Int, element: ID)], ID, EachContent>
116+
>,
117+
EachState: Identifiable,
118+
EachState.ID == ID
119+
{
120+
self.init(store, id: \.id, content: content)
121+
}
122122

123-
/// Initializes a structure that computes views on demand from a store on a collection of data and
124-
/// an identified action.
125-
///
126-
/// - Parameters:
127-
/// - store: A store on an identified array of data and an identified action.
128-
/// - content: A function that can generate content given a store of an element.
129-
public init<EachContent: View>(
130-
_ store: Store<IdentifiedArray<ID, EachState>, (ID, EachAction)>,
131-
content: @escaping (Store<EachState, EachAction>) -> EachContent
132-
)
133-
where
134-
EachContent: View,
135-
Data == IdentifiedArray<ID, EachState>,
136-
Content == WithViewStore<[ID], (ID, EachAction), ForEach<[ID], ID, EachContent>>
137-
{
138-
let data = store.state
139-
self.data = data
140-
self.content = {
141-
WithViewStore(store.scope(state: { $0.ids })) { viewStore in
142-
ForEach(viewStore.state, id: \.self) { id in
143-
content(
144-
store.scope(
145-
state: { $0[id: id] ?? data[id: id]! },
146-
action: { (id, $0) }
123+
/// Initializes a structure that computes views on demand from a store on a collection of data and
124+
/// an identified action.
125+
///
126+
/// - Parameters:
127+
/// - store: A store on an identified array of data and an identified action.
128+
/// - content: A function that can generate content given a store of an element.
129+
public init<EachContent: View>(
130+
_ store: Store<IdentifiedArray<ID, EachState>, (ID, EachAction)>,
131+
content: @escaping (Store<EachState, EachAction>) -> EachContent
132+
)
133+
where
134+
EachContent: View,
135+
Data == IdentifiedArray<ID, EachState>,
136+
Content == WithViewStore<[ID], (ID, EachAction), ForEach<[ID], ID, EachContent>>
137+
{
138+
let data = store.state
139+
self.data = data
140+
self.content = {
141+
WithViewStore(store.scope(state: { $0.ids })) { viewStore in
142+
ForEach(viewStore.state, id: \.self) { id in
143+
content(
144+
store.scope(
145+
state: { $0[id: id] ?? data[id: id]! },
146+
action: { (id, $0) }
147+
)
147148
)
148-
)
149+
}
149150
}
150151
}
151152
}
152-
}
153153

154-
public var body: some View {
155-
self.content()
154+
public var body: some View {
155+
self.content()
156+
}
156157
}
157-
}
158158
#endif

0 commit comments

Comments
 (0)