feat: Adds TCA Helpers, some are wip.
This commit is contained in:
@@ -14,6 +14,7 @@ let package = Package(
|
|||||||
.library(name: "AirflowAtPressureFeature", targets: ["AirflowAtPressureFeature"]),
|
.library(name: "AirflowAtPressureFeature", targets: ["AirflowAtPressureFeature"]),
|
||||||
.library(name: "EstimatedPressureDependency", targets: ["EstimatedPressureDependency"]),
|
.library(name: "EstimatedPressureDependency", targets: ["EstimatedPressureDependency"]),
|
||||||
.library(name: "SharedModels", targets: ["SharedModels"]),
|
.library(name: "SharedModels", targets: ["SharedModels"]),
|
||||||
|
.library(name: "TCAHelpers", targets: ["TCAHelpers"]),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(
|
.package(
|
||||||
@@ -24,6 +25,10 @@ let package = Package(
|
|||||||
url:"https://github.com/pointfreeco/swift-composable-architecture.git",
|
url:"https://github.com/pointfreeco/swift-composable-architecture.git",
|
||||||
from: "1.10.0"
|
from: "1.10.0"
|
||||||
),
|
),
|
||||||
|
.package(
|
||||||
|
url: "https://github.com/tgrapperon/swift-dependencies-additions.git",
|
||||||
|
from: "1.0.1"
|
||||||
|
),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
@@ -32,7 +37,9 @@ let package = Package(
|
|||||||
"EstimatedPressureDependency",
|
"EstimatedPressureDependency",
|
||||||
"SharedModels",
|
"SharedModels",
|
||||||
"Styleguide",
|
"Styleguide",
|
||||||
|
"TCAHelpers",
|
||||||
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
.product(name: "ComposableArchitecture", package: "swift-composable-architecture"),
|
||||||
|
.product(name: "DependenciesAdditions", package: "swift-dependencies-additions")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import ComposableArchitecture
|
import ComposableArchitecture
|
||||||
|
import DependenciesAdditions
|
||||||
import EstimatedPressureDependency
|
import EstimatedPressureDependency
|
||||||
import SharedModels
|
import SharedModels
|
||||||
import Styleguide
|
import Styleguide
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import TCAHelpers
|
||||||
|
|
||||||
@Reducer
|
@Reducer
|
||||||
public struct AirflowAtPressureFeature {
|
public struct AirflowAtPressureFeature {
|
||||||
@@ -34,9 +36,9 @@ public struct AirflowAtPressureFeature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Action: BindableAction, ViewAction {
|
public enum Action: BindableAction, ReceiveAction, ViewAction {
|
||||||
case binding(BindingAction<State>)
|
case binding(BindingAction<State>)
|
||||||
case receive(ReceiveAction)
|
case receive(TaskResult<ReceiveAction>)
|
||||||
case view(View)
|
case view(View)
|
||||||
|
|
||||||
@CasePathable
|
@CasePathable
|
||||||
@@ -53,8 +55,8 @@ public struct AirflowAtPressureFeature {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Dependency(\.estimatedPressuresClient) var estimatedPressuresClient
|
@Dependency(\.estimatedPressuresClient) var estimatedPressuresClient
|
||||||
|
@Dependency(\.logger["\(Self.self)"]) var logger
|
||||||
|
|
||||||
public var body: some Reducer<State, Action> {
|
public var body: some Reducer<State, Action> {
|
||||||
BindingReducer()
|
BindingReducer()
|
||||||
@@ -63,7 +65,10 @@ public struct AirflowAtPressureFeature {
|
|||||||
case .binding:
|
case .binding:
|
||||||
return .none
|
return .none
|
||||||
|
|
||||||
case let .receive(action):
|
case let .receive(.failure(error)):
|
||||||
|
return .fail(error: error, logger: logger)
|
||||||
|
|
||||||
|
case let .receive(.success(action)):
|
||||||
switch action {
|
switch action {
|
||||||
case let .calculatedAirflow(airflow):
|
case let .calculatedAirflow(airflow):
|
||||||
state.calculatedAirflow = airflow
|
state.calculatedAirflow = airflow
|
||||||
@@ -86,18 +91,13 @@ public struct AirflowAtPressureFeature {
|
|||||||
|
|
||||||
case .submit:
|
case .submit:
|
||||||
guard state.isValid else { return .none }
|
guard state.isValid else { return .none }
|
||||||
return .run { [state] send in
|
return .receive(\.calculatedAirflow) { [state] in
|
||||||
await send(
|
try await estimatedPressuresClient.estimatedAirflow(.init(
|
||||||
.receive(.calculatedAirflow(
|
existingAirflow: state.existingAirflow ?? 0,
|
||||||
try? await estimatedPressuresClient.estimatedAirflow(.init(
|
existingPressure: state.existingPressure ?? 0,
|
||||||
existingAirflow: state.existingAirflow ?? 0,
|
targetPressure: state.targetPressure ?? 0
|
||||||
existingPressure: state.existingPressure ?? 0,
|
))
|
||||||
targetPressure: state.targetPressure ?? 0
|
|
||||||
))
|
|
||||||
))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import ComposableArchitecture
|
import ComposableArchitecture
|
||||||
|
|
||||||
public protocol ReceiveAction<ReceiveAction> {
|
public protocol ReceiveAction<ReceiveAction>: CasePathable {
|
||||||
associatedtype ReceiveAction
|
associatedtype ReceiveAction: CasePathable
|
||||||
static func receive(_ result: TaskResult<ReceiveAction>) -> Self
|
static func receive(_ result: TaskResult<ReceiveAction>) -> Self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
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