This commit is contained in:
2024-05-30 22:54:58 -04:00
parent bd0f90894f
commit dac5d932dd
5 changed files with 238 additions and 52 deletions

View File

@@ -1,31 +1,13 @@
import ComposableArchitecture
import OSLog
extension Effect {
@usableFromInline
static func receive<T>(
_ casePath: AnyCasePath<Action, TaskResult<T>>,
_ operation: @escaping @Sendable () async throws -> T
static func receive<Input, Result>(
operation: ReceiveOperation<Action, Input, Result>
) -> Self {
.run { send in
await send(casePath.embed(
TaskResult { try await operation() }
))
}
}
@usableFromInline
static func receive<T, V>(
_ casePath: AnyCasePath<Action, TaskResult<V>>,
_ operation: @escaping @Sendable () async throws -> T,
_ transform: @escaping @Sendable (T) -> V
) -> Self {
.run { send in
await send(casePath.embed(
TaskResult { try await operation() }
.map(transform)
))
await operation(send: send)
}
}
@@ -34,7 +16,7 @@ extension Effect {
action toResult: CaseKeyPath<Action, TaskResult<T>>,
operation: @escaping @Sendable () async throws -> T
) -> Self {
.receive(AnyCasePath(toResult), operation)
.receive(operation: .case(AnyCasePath(toResult), operation))
}
@inlinable
@@ -43,7 +25,7 @@ extension Effect {
operation: @escaping @Sendable () async throws -> T,
transform: @escaping @Sendable (T) -> V
) -> Self {
.receive(AnyCasePath(toResult), operation, transform)
.receive(operation: .case(AnyCasePath(toResult), operation, transform))
}
}
@@ -54,7 +36,7 @@ extension Effect where Action: ReceiveAction {
_ operation: @escaping @Sendable () async throws -> T,
transform: @escaping @Sendable (T) -> Action.ReceiveAction
) -> Self {
.receive(AnyCasePath(unsafe: Action.receive), operation, transform)
.receive(operation: .case(AnyCasePath(unsafe: Action.receive), operation, transform))
}
@inlinable
@@ -68,3 +50,51 @@ extension Effect where Action: ReceiveAction {
}
}
@usableFromInline
struct ReceiveOperation<Action, Input, Result> {
@usableFromInline
let embed: @Sendable (TaskResult<Result>) -> Action
@usableFromInline
let operation: @Sendable () async throws -> Input
@usableFromInline
let transform: @Sendable (Input) -> Result
@usableFromInline
func callAsFunction(send: Send<Action>) async {
await send(embed(
TaskResult { try await operation() }
.map(transform)
))
}
@usableFromInline
static func `case`(
_ casePath: AnyCasePath<Action, TaskResult<Result>>,
_ operation: @escaping @Sendable () async throws -> Input,
_ transform: @escaping @Sendable (Input) -> Result
) -> Self {
.init(embed: { casePath.embed($0) }, operation: operation, transform: transform)
}
}
extension ReceiveOperation where Input == Result {
@usableFromInline
init(
embed: @escaping @Sendable (TaskResult<Result>) -> Action,
operation: @escaping @Sendable () async throws -> Input
) {
self.init(embed: embed, operation: operation, transform: { $0 })
}
@usableFromInline
static func `case`(
_ casePath: AnyCasePath<Action, TaskResult<Result>>,
_ operation: @escaping @Sendable () async throws -> Input
) -> Self {
.init(embed: { casePath.embed($0) }, operation: operation)
}
}