mirror of
https://github.com/pointfreeco/swift-composable-architecture.git
synced 2025-12-20 09:11:33 +01:00
* wip * finish * revert back code snippet identation to 5 * Update Sources/ComposableArchitecture/Effect.swift Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com> Co-authored-by: Brandon Williams <135203+mbrandonw@users.noreply.github.com>
168 lines
5.8 KiB
Swift
168 lines
5.8 KiB
Swift
import CasePaths
|
|
import Dispatch
|
|
|
|
/// Determines how the string description of an action should be printed when using the ``Reducer/debug(prefix:state:action:environment:)``
|
|
/// higher-order reducer.
|
|
public enum ActionFormat {
|
|
/// Prints the action in a single line by only specifying the labels of the associated values:
|
|
///
|
|
/// ```swift
|
|
/// Action.screenA(.row(index:, action: .textChanged(query:)))
|
|
/// ```
|
|
///
|
|
case labelsOnly
|
|
/// Prints the action in a multiline, pretty-printed format, including all the labels of
|
|
/// any associated values, as well as the data held in the associated values:
|
|
///
|
|
/// ```swift
|
|
/// Action.screenA(
|
|
/// ScreenA.row(
|
|
/// index: 1,
|
|
/// action: RowAction.textChanged(
|
|
/// query: "Hi"
|
|
/// )
|
|
/// )
|
|
/// )
|
|
/// ```
|
|
///
|
|
case prettyPrint
|
|
}
|
|
|
|
extension Reducer {
|
|
/// Prints debug messages describing all received actions and state mutations.
|
|
///
|
|
/// Printing is only done in debug (`#if DEBUG`) builds.
|
|
///
|
|
/// - Parameters:
|
|
/// - prefix: A string with which to prefix all debug messages.
|
|
/// - toDebugEnvironment: A function that transforms an environment into a debug environment by
|
|
/// describing a print function and a queue to print from. Defaults to a function that ignores
|
|
/// the environment and returns a default ``DebugEnvironment`` that uses Swift's `print`
|
|
/// function and a background queue.
|
|
/// - Returns: A reducer that prints debug messages for all received actions.
|
|
public func debug(
|
|
_ prefix: String = "",
|
|
actionFormat: ActionFormat = .prettyPrint,
|
|
environment toDebugEnvironment: @escaping (Environment) -> DebugEnvironment = { _ in
|
|
DebugEnvironment()
|
|
}
|
|
) -> Reducer {
|
|
self.debug(
|
|
prefix,
|
|
state: { $0 },
|
|
action: .self,
|
|
actionFormat: actionFormat,
|
|
environment: toDebugEnvironment
|
|
)
|
|
}
|
|
|
|
/// Prints debug messages describing all received actions.
|
|
///
|
|
/// Printing is only done in debug (`#if DEBUG`) builds.
|
|
///
|
|
/// - Parameters:
|
|
/// - prefix: A string with which to prefix all debug messages.
|
|
/// - toDebugEnvironment: A function that transforms an environment into a debug environment by
|
|
/// describing a print function and a queue to print from. Defaults to a function that ignores
|
|
/// the environment and returns a default ``DebugEnvironment`` that uses Swift's `print`
|
|
/// function and a background queue.
|
|
/// - Returns: A reducer that prints debug messages for all received actions.
|
|
public func debugActions(
|
|
_ prefix: String = "",
|
|
actionFormat: ActionFormat = .prettyPrint,
|
|
environment toDebugEnvironment: @escaping (Environment) -> DebugEnvironment = { _ in
|
|
DebugEnvironment()
|
|
}
|
|
) -> Reducer {
|
|
self.debug(
|
|
prefix,
|
|
state: { _ in () },
|
|
action: .self,
|
|
actionFormat: actionFormat,
|
|
environment: toDebugEnvironment
|
|
)
|
|
}
|
|
|
|
/// Prints debug messages describing all received local actions and local state mutations.
|
|
///
|
|
/// Printing is only done in debug (`#if DEBUG`) builds.
|
|
///
|
|
/// - Parameters:
|
|
/// - prefix: A string with which to prefix all debug messages.
|
|
/// - toLocalState: A function that filters state to be printed.
|
|
/// - toLocalAction: A case path that filters actions that are printed.
|
|
/// - toDebugEnvironment: A function that transforms an environment into a debug environment by
|
|
/// describing a print function and a queue to print from. Defaults to a function that ignores
|
|
/// the environment and returns a default ``DebugEnvironment`` that uses Swift's `print`
|
|
/// function and a background queue.
|
|
/// - Returns: A reducer that prints debug messages for all received actions.
|
|
public func debug<LocalState, LocalAction>(
|
|
_ prefix: String = "",
|
|
state toLocalState: @escaping (State) -> LocalState,
|
|
action toLocalAction: CasePath<Action, LocalAction>,
|
|
actionFormat: ActionFormat = .prettyPrint,
|
|
environment toDebugEnvironment: @escaping (Environment) -> DebugEnvironment = { _ in
|
|
DebugEnvironment()
|
|
}
|
|
) -> Reducer {
|
|
#if DEBUG
|
|
return .init { state, action, environment in
|
|
let previousState = toLocalState(state)
|
|
let effects = self.run(&state, action, environment)
|
|
guard let localAction = toLocalAction.extract(from: action) else { return effects }
|
|
let nextState = toLocalState(state)
|
|
let debugEnvironment = toDebugEnvironment(environment)
|
|
return .merge(
|
|
.fireAndForget {
|
|
debugEnvironment.queue.async {
|
|
let actionOutput =
|
|
actionFormat == .prettyPrint
|
|
? debugOutput(localAction).indent(by: 2)
|
|
: debugCaseOutput(localAction).indent(by: 2)
|
|
let stateOutput =
|
|
LocalState.self == Void.self
|
|
? ""
|
|
: debugDiff(previousState, nextState).map { "\($0)\n" } ?? " (No state changes)\n"
|
|
debugEnvironment.printer(
|
|
"""
|
|
\(prefix.isEmpty ? "" : "\(prefix): ")received action:
|
|
\(actionOutput)
|
|
\(stateOutput)
|
|
"""
|
|
)
|
|
}
|
|
},
|
|
effects
|
|
)
|
|
}
|
|
#else
|
|
return self
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/// An environment for debug-printing reducers.
|
|
public struct DebugEnvironment {
|
|
public var printer: (String) -> Void
|
|
public var queue: DispatchQueue
|
|
|
|
public init(
|
|
printer: @escaping (String) -> Void = { print($0) },
|
|
queue: DispatchQueue
|
|
) {
|
|
self.printer = printer
|
|
self.queue = queue
|
|
}
|
|
|
|
public init(
|
|
printer: @escaping (String) -> Void = { print($0) }
|
|
) {
|
|
self.init(printer: printer, queue: _queue)
|
|
}
|
|
}
|
|
|
|
private let _queue = DispatchQueue(
|
|
label: "co.pointfree.ComposableArchitecture.DebugEnvironment",
|
|
qos: .background
|
|
)
|