Skip to content

Commit 0de3017

Browse files
authored
Merge pull request #17 from 0xOpenBytes/feature/StoreContent
Feature/store content
2 parents a1eeb2d + 208e737 commit 0de3017

File tree

9 files changed

+79
-9
lines changed

9 files changed

+79
-9
lines changed

Sources/CacheStore/Stores/CacheStore.swift renamed to Sources/CacheStore/Stores/CacheStore/CacheStore.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public extension CacheStore {
168168

169169
/// Creates a `ScopedCacheStore` with the given key transformation and default cache
170170
func scope<ScopedKey: Hashable>(
171-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>,
171+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>,
172172
defaultCache: [ScopedKey: Any] = [:]
173173
) -> CacheStore<ScopedKey> {
174174
let scopedCacheStore = ScopedCacheStore(keyTransformation: keyTransformation)

Sources/CacheStore/Stores/ScopedStores/ScopedCacheStore.swift renamed to Sources/CacheStore/Stores/CacheStore/ScopedCacheStore.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import c
22

3+
public typealias BiDirectionalTransformation = c.BiDirectionalTransformation
4+
35
class ScopedCacheStore<Key: Hashable, ScopedKey: Hashable>: CacheStore<ScopedKey> {
46
weak var parentCacheStore: CacheStore<Key>?
5-
private var keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>
7+
private var keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>
68

79
init(
8-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>
10+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>
911
) {
1012
self.keyTransformation = keyTransformation
1113

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import c
2+
3+
public extension Store {
4+
/// Create a StoreContent for the provided content type
5+
func content<Content: StoreContent>(
6+
using contentType: Content.Type = Content.self
7+
) -> Content where Content.Key == Key {
8+
contentType.init(
9+
store: actionlessScope(
10+
keyTransformation: (from: { $0 }, to: { $0 }),
11+
dependencyTransformation: { _ in () }
12+
)
13+
)
14+
}
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// The content a StoreView uses when creating SwiftUI views
2+
public protocol StoreContent {
3+
associatedtype Key: Hashable
4+
5+
/// Creates the content from an actionless store that has a Void dependency
6+
init(store: Store<Key, Void, Void>)
7+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import SwiftUI
2+
3+
/// SwiftUI View that uses a Store and StoreContent
4+
public protocol StoreView: View {
5+
/// Key for the Store
6+
associatedtype Key: Hashable
7+
/// Action for the Store
8+
associatedtype Action
9+
/// Dependency for the Store
10+
associatedtype Dependency
11+
/// The content the View cares about and uses
12+
associatedtype Content: StoreContent
13+
14+
/// An `ObservableObject` that uses actions to modify the state which is a `CacheStore`
15+
var store: Store<Key, Action, Dependency> { get set }
16+
/// The content a StoreView uses when creating SwiftUI views
17+
var content: Content { get }
18+
19+
init(store: Store<Key, Action, Dependency>)
20+
}
21+
22+
public extension StoreView where Content.Key == Key {
23+
var content: Content { store.content() }
24+
}

Sources/CacheStore/Stores/Store.swift renamed to Sources/CacheStore/Stores/Store/Store.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public class Store<Key: Hashable, Action, Dependency>: ObservableObject, ActionH
139139

140140
/// Creates a `ScopedStore`
141141
public func scope<ScopedKey: Hashable, ScopedAction, ScopedDependency>(
142-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>,
142+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>,
143143
actionHandler: StoreActionHandler<ScopedKey, ScopedAction, ScopedDependency>,
144144
dependencyTransformation: (Dependency) -> ScopedDependency,
145145
defaultCache: [ScopedKey: Any] = [:],
@@ -182,7 +182,7 @@ public class Store<Key: Hashable, Action, Dependency>: ObservableObject, ActionH
182182

183183
/// Creates an Actionless `ScopedStore`
184184
public func actionlessScope<ScopedKey: Hashable, ScopedDependency>(
185-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>,
185+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>,
186186
dependencyTransformation: (Dependency) -> ScopedDependency,
187187
defaultCache: [ScopedKey: Any] = [:]
188188
) -> Store<ScopedKey, Void, ScopedDependency> {
@@ -225,7 +225,7 @@ public class Store<Key: Hashable, Action, Dependency>: ObservableObject, ActionH
225225
public extension Store where Dependency == Void {
226226
/// Creates a `ScopedStore`
227227
func scope<ScopedKey: Hashable, ScopedAction>(
228-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>,
228+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>,
229229
actionHandler: StoreActionHandler<ScopedKey, ScopedAction, Void>,
230230
defaultCache: [ScopedKey: Any] = [:],
231231
actionTransformation: @escaping (ScopedAction?) -> Action? = { _ in nil }
@@ -241,7 +241,7 @@ public extension Store where Dependency == Void {
241241

242242
/// Creates a `ScopedStore`
243243
func actionlessScope<ScopedKey: Hashable>(
244-
keyTransformation: c.BiDirectionalTransformation<Key?, ScopedKey?>,
244+
keyTransformation: BiDirectionalTransformation<Key?, ScopedKey?>,
245245
defaultCache: [ScopedKey: Any] = [:]
246246
) -> Store<ScopedKey, Void, Void> {
247247
actionlessScope(

Sources/CacheStore/Stores/TestStore.swift renamed to Sources/CacheStore/Stores/Store/TestStore.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,28 @@ public class TestStore<Key: Hashable, Action, Dependency> {
136136
send(nextAction, file: file, line: line, expecting: expecting)
137137
}
138138

139+
/// Create a StoreContent for the provided content type and make assertions in the expecting closure about the content
140+
public func content<Content: StoreContent>(
141+
using contentType: Content.Type = Content.self,
142+
expecting: @escaping (Content) throws -> Void,
143+
file: StaticString = #filePath,
144+
line: UInt = #line
145+
) where Content.Key == Key {
146+
do {
147+
try expecting(content(using: contentType))
148+
} catch {
149+
TestStoreFailure.handler("❌ Expectation failed: \(error)", file, line)
150+
return
151+
}
152+
}
153+
154+
/// Create a StoreContent for the provided content type
155+
public func content<Content: StoreContent>(
156+
using contentType: Content.Type = Content.self
157+
) -> Content where Content.Key == Key {
158+
store.content(using: contentType)
159+
}
160+
139161
/// Checks to make sure the cache has the required keys, otherwise it will fail
140162
func require(
141163
keys: Set<Key>,

Tests/CacheStoreTests/CacheStoreTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ final class CacheStoreTests: XCTestCase {
141141
}
142142

143143
let scopedCacheStore: CacheStore<ScopedCacheKey> = store.scope(
144-
keyTransformation: c.transformer(
144+
keyTransformation: (
145145
from: { global in
146146
switch global {
147147
case .b: return .b
@@ -190,7 +190,7 @@ final class CacheStoreTests: XCTestCase {
190190
let storeOldScopeValue: String = scopedCacheStore.resolve(.b)
191191

192192
let newlyScopedCacheStore: CacheStore<ScopedCacheKey> = store.scope(
193-
keyTransformation: c.transformer(
193+
keyTransformation: (
194194
from: { global in
195195
switch global {
196196
case .b: return .b

0 commit comments

Comments
 (0)