feat: Adds TCA Helpers, some are wip.
This commit is contained in:
@@ -45,6 +45,12 @@ let package = Package(
|
||||
),
|
||||
.target(name: "SharedModels"),
|
||||
.target(name: "Styleguide"),
|
||||
.target(
|
||||
name: "TCAHelpers",
|
||||
dependencies: [
|
||||
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "EstimatedPressureTests",
|
||||
dependencies: [
|
||||
|
||||
25
Sources/TCAHelpers/Effect+fail.swift
Normal file
25
Sources/TCAHelpers/Effect+fail.swift
Normal file
@@ -0,0 +1,25 @@
|
||||
import ComposableArchitecture
|
||||
import OSLog
|
||||
|
||||
extension Effect {
|
||||
public static func fail(
|
||||
prefix: String = "Failed error:",
|
||||
error: Error,
|
||||
logger: Logger? = nil
|
||||
) -> Self {
|
||||
let message = "\(prefix) \(error)"
|
||||
XCTFail("\(message)")
|
||||
logger?.error("\(message)")
|
||||
return .none
|
||||
}
|
||||
|
||||
public static func fail(
|
||||
_ message: String,
|
||||
logger: Logger? = nil
|
||||
) -> Self {
|
||||
XCTFail("\(message)")
|
||||
logger?.error("\(message)")
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
40
Sources/TCAHelpers/Effect+receive.swift
Normal file
40
Sources/TCAHelpers/Effect+receive.swift
Normal file
@@ -0,0 +1,40 @@
|
||||
import ComposableArchitecture
|
||||
|
||||
public protocol ReceiveAction<ReceiveAction> {
|
||||
associatedtype ReceiveAction
|
||||
static func receive(_ result: TaskResult<ReceiveAction>) -> Self
|
||||
}
|
||||
|
||||
extension Effect where Action: ReceiveAction {
|
||||
|
||||
public static func receive(
|
||||
_ operation: @escaping () async throws -> Action.ReceiveAction
|
||||
) -> Self {
|
||||
.run { send in
|
||||
await send(.receive(
|
||||
TaskResult { try await operation() }
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
public static func receive<T>(
|
||||
_ operation: @escaping () async throws -> T,
|
||||
transform: @escaping (T) -> Action.ReceiveAction
|
||||
) -> Self {
|
||||
.run { send in
|
||||
await send(.receive(
|
||||
TaskResult { try await operation() }
|
||||
.map(transform)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
public static func receive<T>(
|
||||
_ toReceiveAction: CaseKeyPath<Action.ReceiveAction, T>,
|
||||
_ operation: @escaping () async throws -> T
|
||||
) -> Self {
|
||||
return .receive(operation) {
|
||||
AnyCasePath(toReceiveAction).embed($0)
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Sources/TCAHelpers/ReceiveFailureReducer.swift
Normal file
51
Sources/TCAHelpers/ReceiveFailureReducer.swift
Normal file
@@ -0,0 +1,51 @@
|
||||
import ComposableArchitecture
|
||||
import OSLog
|
||||
|
||||
public struct _ReceiveFailureReducer<State, Action>: Reducer {
|
||||
|
||||
@usableFromInline
|
||||
let toReceiveActionError: (Action) -> Error?
|
||||
|
||||
@usableFromInline
|
||||
let logger: Logger
|
||||
|
||||
@inlinable
|
||||
public init<ViewAction: ReceiveAction>(
|
||||
action toReceiveAction: CaseKeyPath<Action, ViewAction>,
|
||||
logger: Logger
|
||||
) {
|
||||
self.init(
|
||||
internal: { action in
|
||||
if case let .receive(.failure(error)) = AnyCasePath(toReceiveAction).extract(from: action) {
|
||||
return error
|
||||
}
|
||||
return nil
|
||||
},
|
||||
logger: logger
|
||||
)
|
||||
}
|
||||
|
||||
@usableFromInline
|
||||
init(internal toReceiveActionError: @escaping (Action) -> Error?, logger: Logger) {
|
||||
self.toReceiveActionError = toReceiveActionError
|
||||
self.logger = logger
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public func reduce(
|
||||
into state: inout State,
|
||||
action: Action
|
||||
) -> Effect<Action> {
|
||||
guard let error = toReceiveActionError(action) else { return .none }
|
||||
return .fail(error: error, logger: logger)
|
||||
}
|
||||
}
|
||||
|
||||
extension Reducer where Action: ReceiveAction, Action: CasePathable {
|
||||
public func onFail(_ logger: Logger) -> _ReceiveFailureReducer<State, Action, Action> {
|
||||
_ReceiveFailureReducer(
|
||||
action: \.receive,
|
||||
logger: logger
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user