diff --git a/Decide/Accessor/Default/DefaultBind.swift b/Decide/Accessor/Default/DefaultBind.swift index 6b1f308..5010eb5 100644 --- a/Decide/Accessor/Default/DefaultBind.swift +++ b/Decide/Accessor/Default/DefaultBind.swift @@ -14,16 +14,15 @@ import Foundation -/// @propertyWrapper -@MainActor public struct DefaultBind { +@MainActor public struct DefaultBind { @DefaultEnvironment var environment - private let propertyKeyPath: KeyPath> + private let propertyKeyPath: KeyPath> let context: Context public init( - _ keyPath: KeyPath>, + _ keyPath: KeyPath>, file: String = #fileID, line: Int = #line ) { diff --git a/Decide/Accessor/Default/DefaultBindKeyed.swift b/Decide/Accessor/Default/DefaultBindKeyed.swift index 7d4b066..c4ec35e 100644 --- a/Decide/Accessor/Default/DefaultBindKeyed.swift +++ b/Decide/Accessor/Default/DefaultBindKeyed.swift @@ -16,15 +16,15 @@ import Foundation /// @propertyWrapper -@MainActor public struct DefaultBindKeyed, Value> { +@MainActor public struct DefaultBindKeyed, Value> { @DefaultEnvironment var environment - private let propertyKeyPath: KeyPath> - private var valueBinding: KeyedValueBinding? + private let propertyKeyPath: KeyPath> + private var valueBinding: KeyedValueBinding? let context: Context public init( - _ keyPath: KeyPath>, + _ keyPath: KeyPath>, file: String = #fileID, line: Int = #line ) { @@ -35,9 +35,9 @@ import Foundation public static subscript( _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath>, + wrapped wrappedKeyPath: KeyPath>, storage storageKeyPath: WritableKeyPath - ) -> KeyedValueBinding { + ) -> KeyedValueBinding { get { var storage = instance[keyPath: storageKeyPath] let propertyKeyPath = storage.propertyKeyPath @@ -60,21 +60,21 @@ import Foundation public var projectedValue: Self { self } @available(*, unavailable, message: "@DefaultBind can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: KeyedValueBinding { + public var wrappedValue: KeyedValueBinding { get { fatalError() } set { fatalError() } } } -@MainActor public struct KeyedValueBinding, Value> { +@MainActor public struct KeyedValueBinding, Value> { unowned var environment: ApplicationEnvironment let observer: Observer - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> let context: Context init( - bind propertyKeyPath: KeyPath>, + bind propertyKeyPath: KeyPath>, observer: Observer, environment: ApplicationEnvironment, context: Context @@ -85,7 +85,7 @@ import Foundation self.environment = environment } - public subscript(_ identifier: I) -> Value { + public subscript(_ identifier: Identifier) -> Value { get { environment.subscribe(observer, on: propertyKeyPath, at: identifier) return environment.getValue(propertyKeyPath, at: identifier) diff --git a/Decide/Accessor/Default/DefaultObserve.swift b/Decide/Accessor/Default/DefaultObserve.swift index a951c06..10570ff 100644 --- a/Decide/Accessor/Default/DefaultObserve.swift +++ b/Decide/Accessor/Default/DefaultObserve.swift @@ -17,18 +17,18 @@ import Foundation /// @propertyWrapper -@MainActor public struct DefaultObserve { +@MainActor public struct DefaultObserve { @DefaultEnvironment var environment - private let propertyKeyPath: KeyPath> + private let propertyKeyPath: KeyPath> - public init(_ keyPath: KeyPath>) { + public init(_ keyPath: KeyPath>) { self.propertyKeyPath = keyPath } - public init( - _ keyPath: KeyPath - ) where P.Value == Value { + public init( + _ keyPath: KeyPath + ) where WrappedProperty.Value == Value { propertyKeyPath = keyPath.appending(path: \.wrappedValue) } diff --git a/Decide/Accessor/Default/DefaultObserveKeyed.swift b/Decide/Accessor/Default/DefaultObserveKeyed.swift index 555e894..96aaa06 100644 --- a/Decide/Accessor/Default/DefaultObserveKeyed.swift +++ b/Decide/Accessor/Default/DefaultObserveKeyed.swift @@ -17,32 +17,32 @@ import Foundation /// @propertyWrapper @MainActor public struct DefaultObserveKeyed< - I: Hashable, - S: KeyedState, + Identifier: Hashable, + State: KeyedState, Value > { @DefaultEnvironment var environment - private let propertyKeyPath: KeyPath> - private var valueObserve: KeyedValueObserve? + private let propertyKeyPath: KeyPath> + private var valueObserve: KeyedValueObserve? public init( - _ keyPath: KeyPath> + _ keyPath: KeyPath> ) { propertyKeyPath = keyPath } - public init( - _ keyPath: KeyPath - ) where P.Value == Value { + public init( + _ keyPath: KeyPath + ) where WrappedProperty.Value == Value { propertyKeyPath = keyPath.appending(path: \.wrappedValue) } public static subscript( _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath>, + wrapped wrappedKeyPath: KeyPath>, storage storageKeyPath: WritableKeyPath - ) -> KeyedValueObserve { + ) -> KeyedValueObserve { get { var storage = instance[keyPath: storageKeyPath] let propertyKeyPath = storage.propertyKeyPath @@ -50,7 +50,7 @@ import Foundation storage.environment = environment let observer = Observer(instance) if storage.valueObserve == nil { - storage.valueObserve = KeyedValueObserve( + storage.valueObserve = KeyedValueObserve( bind: propertyKeyPath, observer: observer, environment: environment @@ -64,20 +64,20 @@ import Foundation public var projectedValue: Self { self } @available(*, unavailable, message: "@DefaultBind can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: KeyedValueObserve { + public var wrappedValue: KeyedValueObserve { get { fatalError() } set { fatalError() } } } -@MainActor public struct KeyedValueObserve, Value> { +@MainActor public struct KeyedValueObserve, Value> { unowned var environment: ApplicationEnvironment let observer: Observer - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> init( - bind propertyKeyPath: KeyPath>, + bind propertyKeyPath: KeyPath>, observer: Observer, environment: ApplicationEnvironment ) { @@ -86,7 +86,7 @@ import Foundation self.environment = environment } - public subscript(_ identifier: I) -> Value { + public subscript(_ identifier: Identifier) -> Value { get { environment.subscribe(observer, on: propertyKeyPath, at: identifier) return environment.getValue(propertyKeyPath, at: identifier) diff --git a/Decide/Accessor/Instance.swift b/Decide/Accessor/Instance.swift index dd6ae1e..215786c 100644 --- a/Decide/Accessor/Instance.swift +++ b/Decide/Accessor/Instance.swift @@ -14,21 +14,21 @@ import SwiftUI @propertyWrapper -@MainActor public struct Instance { +@MainActor public struct Instance { - public typealias PropertyKeyPath = KeyPath> + public typealias PropertyKeyPath = KeyPath> private let instanceKeyPath: PropertyKeyPath - public init(_ keyPath: KeyPath>) { + public init(_ keyPath: KeyPath>) { self.instanceKeyPath = keyPath } public static subscript( _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath, + wrapped wrappedKeyPath: KeyPath, storage storageKeyPath: KeyPath - ) -> O { + ) -> Object { get { let storage = instance[keyPath: storageKeyPath] let instanceKeyPath = storage.instanceKeyPath @@ -38,16 +38,16 @@ import SwiftUI } @available(*, unavailable, message: "@Instance must be enclosed in EnvironmentManagedObject.") - public var wrappedValue: O { + public var wrappedValue: Object { get { fatalError() } } } extension ApplicationEnvironment { - func defaultInstance( - at keyPath: KeyPath> - ) -> DefaultInstance { - let storage: S = self[S.key()] + func defaultInstance( + at keyPath: KeyPath> + ) -> DefaultInstance { + let storage: State = self[State.key()] return storage[keyPath: keyPath] } } diff --git a/Decide/Accessor/SwiftUI/Bind.swift b/Decide/Accessor/SwiftUI/Bind.swift index 98ba4f0..f6db033 100644 --- a/Decide/Accessor/SwiftUI/Bind.swift +++ b/Decide/Accessor/SwiftUI/Bind.swift @@ -17,14 +17,18 @@ import SwiftUI /// **SwiftUI** property wrapper that provides two-way access to the value by ``Property`` KeyPath on ``AtomicState``from the view environment. @propertyWrapper -@MainActor public struct Bind: DynamicProperty { +@MainActor public struct Bind: DynamicProperty { @SwiftUI.Environment(\.stateEnvironment) var environment @ObservedObject var observer = ObservedObjectWillChangeNotification() let context: Context - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> - public init(_ propertyKeyPath: KeyPath>, file: String = #fileID, line: Int = #line) { + public init( + _ propertyKeyPath: KeyPath>, + file: String = #fileID, + line: Int = #line + ) { let context = Context(file: file, line: line) self.context = context self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) diff --git a/Decide/Accessor/SwiftUI/BindKeyed.swift b/Decide/Accessor/SwiftUI/BindKeyed.swift index 97106ec..5c6a26b 100644 --- a/Decide/Accessor/SwiftUI/BindKeyed.swift +++ b/Decide/Accessor/SwiftUI/BindKeyed.swift @@ -16,22 +16,26 @@ import SwiftUI /// **SwiftUI** property wrapper that provides two-way access to the value by ``Property`` KeyPath and a Key on ``KeyedState`` from the view environment. @propertyWrapper -@MainActor public struct BindKeyed, Value>: DynamicProperty { +@MainActor public struct BindKeyed, Value>: DynamicProperty { @SwiftUI.Environment(\.stateEnvironment) var environment @ObservedObject var observer = ObservedObjectWillChangeNotification() let context: Context - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> - public init(_ propertyKeyPath: KeyPath>, file: String = #fileID, line: Int = #line) { + public init( + _ propertyKeyPath: KeyPath>, + file: String = #fileID, + line: Int = #line + ) { let context = Context(file: file, line: line) self.context = context self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) } - public subscript(_ identifier: I) -> Binding { + public subscript(_ identifier: Identifier) -> Binding { Binding( get: { environment.subscribe( @@ -47,7 +51,7 @@ import SwiftUI ) } - public subscript(_ identifier: I) -> Value { + public subscript(_ identifier: Identifier) -> Value { get { environment.subscribe(Observer(observer), on: propertyKeyPath, at: identifier) return environment.getValue(propertyKeyPath, at: identifier) diff --git a/Decide/Accessor/SwiftUI/Observe.swift b/Decide/Accessor/SwiftUI/Observe.swift index 3484462..b604616 100644 --- a/Decide/Accessor/SwiftUI/Observe.swift +++ b/Decide/Accessor/SwiftUI/Observe.swift @@ -17,19 +17,19 @@ import SwiftUI /// **SwiftUI** property wrapper that provides read only access to the value by ``Property`` KeyPath on ``AtomicState``from the view environment. @propertyWrapper -@MainActor public struct Observe: DynamicProperty { +@MainActor public struct Observe: DynamicProperty { @SwiftUI.Environment(\.stateEnvironment) var environment @ObservedObject var observer = ObservedObjectWillChangeNotification() - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> - public init(_ propertyKeyPath: KeyPath>) { + public init(_ propertyKeyPath: KeyPath>) { self.propertyKeyPath = propertyKeyPath } - public init( - _ propertyKeyPath: KeyPath - ) where P.Value == Value { + public init( + _ propertyKeyPath: KeyPath + ) where WrappedProperty.Value == Value { self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) } diff --git a/Decide/Accessor/SwiftUI/ObserveKeyed.swift b/Decide/Accessor/SwiftUI/ObserveKeyed.swift index 34e9fc9..dfb2f0e 100644 --- a/Decide/Accessor/SwiftUI/ObserveKeyed.swift +++ b/Decide/Accessor/SwiftUI/ObserveKeyed.swift @@ -17,27 +17,27 @@ import SwiftUI /// **SwiftUI** property wrapper that provides read only access to the value by ``Property`` KeyPath and a Key on ``KeyedState`` from the view environment. @propertyWrapper @MainActor public struct ObserveKeyed< - I: Hashable, - S: KeyedState, + Identifier: Hashable, + State: KeyedState, Value >: DynamicProperty { @SwiftUI.Environment(\.stateEnvironment) var environment @ObservedObject var observer = ObservedObjectWillChangeNotification() - let propertyKeyPath: KeyPath> + let propertyKeyPath: KeyPath> - public init(_ propertyKeyPath: KeyPath>) { + public init(_ propertyKeyPath: KeyPath>) { self.propertyKeyPath = propertyKeyPath } - public init( - _ propertyKeyPath: KeyPath - ) where P.Value == Value { + public init( + _ propertyKeyPath: KeyPath + ) where WrappedProperty.Value == Value { self.propertyKeyPath = propertyKeyPath.appending(path: \.wrappedValue) } - public subscript(_ identifier: I) -> Value { + public subscript(_ identifier: Identifier) -> Value { get { environment.subscribe(Observer(observer), on: propertyKeyPath, at: identifier) return environment.getValue(propertyKeyPath, at: identifier) diff --git a/Decide/Container/AtomicState.swift b/Decide/Container/AtomicState.swift index 37fff5f..1bad081 100644 --- a/Decide/Container/AtomicState.swift +++ b/Decide/Container/AtomicState.swift @@ -40,17 +40,17 @@ extension ApplicationEnvironment { //===------------------------------------------------------------------===// // MARK: - Observability //===------------------------------------------------------------------===// - func notifyObservers( - _ keyPath: KeyPath> + func notifyObservers( + _ keyPath: KeyPath> ) { let observers = popObservers(keyPath) observers.forEach { $0.notify() } } - func popObservers( - _ keyPath: KeyPath> + func popObservers( + _ keyPath: KeyPath> ) -> Set { - let storage: S = self[S.key()] + let storage: State = self[State.key()] return storage[keyPath: keyPath].valueContainer.observerStorage.popObservers() } @@ -60,23 +60,23 @@ extension ApplicationEnvironment { //===------------------------------------------------------------------===// /// Subscribe ``Observer`` at ``Property`` KeyPath on ``AtomicState``. - func subscribe( + func subscribe( _ observer: Observer, - on keyPath: KeyPath> + on keyPath: KeyPath> ) { - let storage: S = self[S.key()] + let storage: State = self[State.key()] storage[keyPath: keyPath].projectedValue.valueContainer.observerStorage.subscribe(observer) } /// Get value at ``Property`` KeyPath on ``AtomicState``. - func getValue(_ keyPath: KeyPath>) -> Value { - let storage: S = self[S.key()] + func getValue(_ keyPath: KeyPath>) -> Value { + let storage: State = self[State.key()] return storage[keyPath: keyPath].wrappedValue } /// Set value at ``Property`` KeyPath on ``AtomicState``. - func setValue(_ newValue: Value, _ keyPath: KeyPath>) { - let storage: S = self[S.key()] + func setValue(_ newValue: Value, _ keyPath: KeyPath>) { + let storage: State = self[State.key()] storage[keyPath: keyPath].wrappedValue = newValue notifyObservers(keyPath) } diff --git a/Decide/Container/DefaultInstance.swift b/Decide/Container/DefaultInstance.swift index ba838bc..f65f5a8 100644 --- a/Decide/Container/DefaultInstance.swift +++ b/Decide/Container/DefaultInstance.swift @@ -16,8 +16,8 @@ import Foundation /// Managed by ``ApplicationEnvironment`` storage for objects, unlike ``Property`` it doesn't support mutation nor observation. @propertyWrapper -@MainActor public final class DefaultInstance { - public var wrappedValue: O { +@MainActor public final class DefaultInstance { + public var wrappedValue: Object { get { if let storage { return storage } let newValue = defaultValue() @@ -26,19 +26,19 @@ import Foundation } } - public var projectedValue: DefaultInstance { + public var projectedValue: DefaultInstance { self } - public init(wrappedValue: @autoclosure @escaping () -> O, file: StaticString = #fileID, line: UInt = #line) { + public init(wrappedValue: @autoclosure @escaping () -> Object, file: StaticString = #fileID, line: UInt = #line) { self.defaultValue = wrappedValue self.file = file.description self.line = line } // MARK: - Value Storage - private var storage: O? - private let defaultValue: () -> O + private var storage: Object? + private let defaultValue: () -> Object // MARK: - Tracing let file: String diff --git a/Decide/Container/KeyedState.swift b/Decide/Container/KeyedState.swift index 0eae8a1..f4126f7 100644 --- a/Decide/Container/KeyedState.swift +++ b/Decide/Container/KeyedState.swift @@ -35,9 +35,9 @@ extension ApplicationEnvironment { // MARK: - Observability //===------------------------------------------------------------------===// - func notifyObservers, Value>( - _ keyPath: KeyPath>, - _ identifier: I + func notifyObservers, Value>( + _ keyPath: KeyPath>, + _ identifier: Identifier ) { let observers = popObservers(keyPath, identifier) observers.forEach { $0.notify() } @@ -56,31 +56,31 @@ extension ApplicationEnvironment { //===------------------------------------------------------------------===// /// Subscribe ``ObservableValue`` at ``Property`` KeyPath on ``KeyedState``. - func subscribe, Value>( + func subscribe, Value>( _ observer: Observer, - on keyPath: KeyPath>, - at identifier: I + on keyPath: KeyPath>, + at identifier: Identifier ) { - let storage: S = self[S.key(identifier)] + let storage: State = self[State.key(identifier)] storage[keyPath: keyPath].projectedValue.valueContainer.observerStorage.subscribe(observer) } /// Get value at ``Property`` KeyPath on ``KeyedState``. - func getValue, Value>( - _ keyPath: KeyPath>, - at identifier: I + func getValue, Value>( + _ keyPath: KeyPath>, + at identifier: Identifier ) -> Value { - let storage: S = self[S.key(identifier)] + let storage: State = self[State.key(identifier)] return storage[keyPath: keyPath].wrappedValue } /// Set value at ``Property`` KeyPath on ``KeyedState``. - func setValue, Value>( + func setValue, Value>( _ newValue: Value, - _ keyPath: KeyPath>, - at identifier: I + _ keyPath: KeyPath>, + at identifier: Identifier ) { - let storage: S = self[S.key(identifier)] + let storage: State = self[State.key(identifier)] storage[keyPath: keyPath].wrappedValue = newValue notifyObservers(keyPath, identifier) } diff --git a/Decide/Environment/Environment.swift b/Decide/Environment/Environment.swift index 30bee9a..28cce2b 100644 --- a/Decide/Environment/Environment.swift +++ b/Decide/Environment/Environment.swift @@ -44,9 +44,9 @@ import Foundation return Telemetry(observer: OSLogTelemetryObserver()) // .noTelemetry }() - subscript(_ key: Key) -> S { - if let state = storage[key] as? S { return state } - let newValue = S.init() + subscript(_ key: Key) -> Storage { + if let state = storage[key] as? Storage { return state } + let newValue = Storage.init() storage[key] = newValue return newValue } diff --git a/Decide/Structured State Mutation/Decision.swift b/Decide/Structured State Mutation/Decision.swift index 72b76d4..24b10ea 100644 --- a/Decide/Structured State Mutation/Decision.swift +++ b/Decide/Structured State Mutation/Decision.swift @@ -46,9 +46,9 @@ import Foundation } } - public subscript, Value>( + public subscript, Value>( _ propertyKeyPath: KeyPath>, - at identifier: ID + at identifier: Identifier ) -> Value { get { environment.getValue(propertyKeyPath, at: identifier) @@ -68,17 +68,17 @@ import Foundation } /// Set value at ``Property`` KeyPath on ``KeyedState``. - func setValue, Value>( + func setValue, Value>( _ keyPath: KeyPath>, _ newValue: Value, - at identifier: ID + at identifier: Identifier ) { transactions.insert( Transaction(keyPath, newValue: newValue, at: identifier) ) } - public func perform(effect: E) { + public func perform(effect: SideEffect) { effects.append(effect) } } diff --git a/Decide/Structured State Mutation/Effect.swift b/Decide/Structured State Mutation/Effect.swift index 82c5d8f..e354c5e 100644 --- a/Decide/Structured State Mutation/Effect.swift +++ b/Decide/Structured State Mutation/Effect.swift @@ -28,30 +28,30 @@ public protocol Effect: Actor { self.environment = environment } - public subscript(_ propertyKeyPath: KeyPath>) -> V { + public subscript(_ propertyKeyPath: KeyPath>) -> Value { get { environment.getValue(propertyKeyPath) } } - public subscript( - _ propertyKeyPath: KeyPath>, - at identifier: I - ) -> V - where I: Hashable, S: KeyedState + public subscript( + _ propertyKeyPath: KeyPath>, + at identifier: Identifier + ) -> Value + where Identifier: Hashable, State: KeyedState { get { environment.getValue(propertyKeyPath, at: identifier) } } - public subscript(_ propertyKeyPath: KeyPath>) -> V { + public subscript(_ propertyKeyPath: KeyPath>) -> Value { get { environment.getValue(propertyKeyPath.appending(path: \.wrappedValue)) } } - public subscript( - _ propertyKeyPath: KeyPath>, - at identifier: I - ) -> V - where I: Hashable, S: KeyedState + public subscript( + _ propertyKeyPath: KeyPath>, + at identifier: Identifier + ) -> Value + where Identifier: Hashable, State: KeyedState { get { environment.getValue(propertyKeyPath.appending(path: \.wrappedValue), at: identifier) @@ -63,14 +63,14 @@ public protocol Effect: Actor { await environment.makeAwaiting(decision: decision) } - @MainActor public func instance(_ keyPath: KeyPath>) -> O { - let obj = environment.defaultInstance(at: keyPath).wrappedValue - return obj + @MainActor public func instance(_ keyPath: KeyPath>) -> Object { + let object = environment.defaultInstance(at: keyPath).wrappedValue + return object } - @MainActor public func instance(_ keyPath: KeyPath>) -> O { - let obj = environment.defaultInstance(at: keyPath).wrappedValue - obj.environment = self.environment - return obj + @MainActor public func instance(_ keyPath: KeyPath>) -> Object { + let object = environment.defaultInstance(at: keyPath).wrappedValue + object.environment = self.environment + return object } } diff --git a/Decide/Structured State Mutation/Transaction.swift b/Decide/Structured State Mutation/Transaction.swift index fe8f10e..3488015 100644 --- a/Decide/Structured State Mutation/Transaction.swift +++ b/Decide/Structured State Mutation/Transaction.swift @@ -49,10 +49,10 @@ final class Transaction: Hashable { self.identity = propertyKeyPath } - @MainActor init, Value>( + @MainActor init, Value>( _ propertyKeyPath: KeyPath>, newValue: Value, - at identifier: ID + at identifier: Identifier ) { self.mutate = { environment in environment.setValue(newValue, propertyKeyPath, at: identifier) diff --git a/Decide/Telemetry/Events/UnstructuredMutation.swift b/Decide/Telemetry/Events/UnstructuredMutation.swift index 0e95cd7..9dd869d 100644 --- a/Decide/Telemetry/Events/UnstructuredMutation.swift +++ b/Decide/Telemetry/Events/UnstructuredMutation.swift @@ -14,16 +14,16 @@ import OSLog -final class UnstructuredMutation: TelemetryEvent { +final class UnstructuredMutation: TelemetryEvent { let category: String = "Unstructured State Mutation" let name: String = "Property updated:" let logLevel: OSLogType = .debug let context: Decide.Context let keyPath: String - let value: V + let value: Value - init(context: Decide.Context, keyPath: String, value: V) { + init(context: Decide.Context, keyPath: String, value: Value) { self.keyPath = keyPath self.context = context self.value = value diff --git a/Decide/Telemetry/LoggerObserver.swift b/Decide/Telemetry/LoggerObserver.swift index d73c4a8..fa3e290 100644 --- a/Decide/Telemetry/LoggerObserver.swift +++ b/Decide/Telemetry/LoggerObserver.swift @@ -41,7 +41,7 @@ final class OSLogTelemetryObserver: TelemetryObserver { return false }() - func eventDidOccur(_ event: E) where E : TelemetryEvent { + func eventDidOccur(_ event: Event) where Event: TelemetryEvent { let logger = Logger(subsystem: Self.subsystem, category: event.category) if Self.unsafeTracingEnabled { unsafeTrace(event: event, logger: logger) @@ -51,7 +51,7 @@ final class OSLogTelemetryObserver: TelemetryObserver { } - func trace(event: E, logger: Logger) where E : TelemetryEvent { + func trace(event: Event, logger: Logger) where Event: TelemetryEvent { switch event.logLevel { case .debug: logger.debug("\(event.name): \(event.message(), privacy: .sensitive)\n context: \(event.context.debugDescription)") @@ -66,7 +66,7 @@ final class OSLogTelemetryObserver: TelemetryObserver { } } - func unsafeTrace(event: E, logger: Logger) where E : TelemetryEvent { + func unsafeTrace(event: Event, logger: Logger) where Event: TelemetryEvent { switch event.logLevel { case .debug: logger.debug("\(event.name): \(event.message(), privacy: .sensitive)\n context: \(event.context.debugDescription)") diff --git a/Decide/Telemetry/Telemetry.swift b/Decide/Telemetry/Telemetry.swift index b4e9180..21a1e5a 100644 --- a/Decide/Telemetry/Telemetry.swift +++ b/Decide/Telemetry/Telemetry.swift @@ -27,7 +27,7 @@ final class Telemetry { self.observer = observer } - func log(event: E) { + func log(event: Event) { guard event.logLevel.rawValue >= self.logLevel.rawValue else { return } observer.eventDidOccur(event) @@ -35,7 +35,7 @@ final class Telemetry { } final class DoNotObserve: TelemetryObserver { - func eventDidOccur(_ event: E) where E : TelemetryEvent {} + func eventDidOccur(_ event: Event) where Event : TelemetryEvent {} } extension Telemetry { static let noTelemetry = Telemetry(observer: DoNotObserve()) @@ -54,6 +54,6 @@ protocol TelemetryEvent { protocol TelemetryObserver { /// Called every time an event with debug level /// equal or greater than current occur. - func eventDidOccur(_ event: E) + func eventDidOccur(_ event: Event) } diff --git a/DecideTesting/AssertValueAt.swift b/DecideTesting/AssertValueAt.swift index dc3ca4f..2f829c3 100644 --- a/DecideTesting/AssertValueAt.swift +++ b/DecideTesting/AssertValueAt.swift @@ -21,9 +21,9 @@ public extension ApplicationEnvironment { //===------------------------------------------------------------------===// /// Asserts that value of given container is equal to given value. - func AssertValueIn( - _ valueA: V, - isEqual valueB: V, + func AssertValueIn( + _ valueA: Value, + isEqual valueB: Value, file: StaticString = #file, line: UInt = #line ) { @@ -37,46 +37,46 @@ public extension ApplicationEnvironment { /// Asserts that value at given KeyPath is equal to given value. func AssertValueAt< - P: PropertyModifier, - V: Equatable, - S: AtomicState - > ( - _ keyPath: KeyPath, - isEqual value: V, + WrappedProperty: PropertyModifier, + Value: Equatable, + State: AtomicState + >( + _ keyPath: KeyPath, + isEqual value: Value, file: StaticString = #file, line: UInt = #line - ) where P.Value == V { + ) where WrappedProperty.Value == Value { let containerValue = getValue(keyPath.appending(path: \.wrappedValue)) AssertValueIn(containerValue, isEqual: value, file: file, line: line) } /// Asserts that value at given KeyPath is equal to given value. func AssertValueAt< - V: Equatable, - S: AtomicState + Value: Equatable, + State: AtomicState >( - _ keyPath: KeyPath>, - isEqual value: V, + _ keyPath: KeyPath>, + isEqual value: Value, file: StaticString = #file, line: UInt = #line ) { let containerValue = getValue(keyPath) AssertValueIn(containerValue, isEqual: value, file: file, line: line) } - + //===------------------------------------------------------------------===// // MARK: - Keyed //===------------------------------------------------------------------===// /// Asserts that value of given container and Identifier is equal to given value. func AssertValueIn< - V: Equatable, - I: Hashable, - S: KeyedState + Value: Equatable, + Identifier: Hashable, + State: KeyedState >( - _ valueA: V, - identifier: I, - isEqual valueB: V, + _ valueA: Value, + identifier: Identifier, + isEqual valueB: Value, file: StaticString = #file, line: UInt = #line ) { @@ -89,30 +89,30 @@ public extension ApplicationEnvironment { /// Asserts that value at given KeyPath and Identifier is equal to given value. func AssertValueAt< - P: PropertyModifier, - V: Equatable, - I: Hashable, - S: KeyedState + WrappedProperty: PropertyModifier, + Value: Equatable, + Identifier: Hashable, + State: KeyedState >( - _ keyPath: KeyPath, - at identifier: I, - isEqual value: V, + _ keyPath: KeyPath, + at identifier: Identifier, + isEqual value: Value, file: StaticString = #file, line: UInt = #line - ) where P.Value == V { + ) where WrappedProperty.Value == Value { let containerValue = getValue(keyPath.appending(path: \.wrappedValue), at: identifier) AssertValueIn(containerValue, identifier: identifier, isEqual: value, file: file, line: line) } /// Asserts that value at given KeyPath and Identifier is equal to given value. func AssertValueAt< - V: Equatable, - I: Hashable, - S: KeyedState + Value: Equatable, + Identifier: Hashable, + State: KeyedState >( - _ keyPath: KeyPath>, - at identifier: I, - isEqual value: V, + _ keyPath: KeyPath>, + at identifier: Identifier, + isEqual value: Value, file: StaticString = #file, line: UInt = #line ) { diff --git a/DecideTesting/Mirror+EnvironmentOverride.swift b/DecideTesting/Mirror+EnvironmentOverride.swift index b573cbd..185ba99 100644 --- a/DecideTesting/Mirror+EnvironmentOverride.swift +++ b/DecideTesting/Mirror+EnvironmentOverride.swift @@ -14,7 +14,10 @@ import Decide -@MainActor public func WithEnvironment(_ environment: ApplicationEnvironment, object: T) -> T { +@MainActor public func WithEnvironment( + _ environment: ApplicationEnvironment, + object: Object +) -> Object { Mirror(reflecting: object).replaceEnvironment(with: environment) return object } @@ -27,12 +30,12 @@ private extension Mirror { } @MainActor func replaceEnvironment(on child: inout Mirror.Child, with newEnvironment: ApplicationEnvironment) { - if let obj = child.value as? DefaultEnvironment { - obj.wrappedValue = newEnvironment + if let object = child.value as? DefaultEnvironment { + object.wrappedValue = newEnvironment return } - let m = Mirror(reflecting: child.value) - m.replaceEnvironment(with: newEnvironment) + let mirror = Mirror(reflecting: child.value) + mirror.replaceEnvironment(with: newEnvironment) } } diff --git a/DecideTesting/SetValue+Environment.swift b/DecideTesting/SetValue+Environment.swift index 32b1c85..17271de 100644 --- a/DecideTesting/SetValue+Environment.swift +++ b/DecideTesting/SetValue+Environment.swift @@ -17,16 +17,19 @@ import OSLog public extension ApplicationEnvironment { /// Set value at ``Mutable`` KeyPath on ``AtomicState``. - func setValue(_ newValue: Value, _ keyPath: KeyPath>) { + func setValue( + _ newValue: Value, + _ keyPath: KeyPath> + ) { setValue(newValue, keyPath.appending(path: \.wrappedValue)) telemetry.log(event: TestingMutation(context: .init(), keyPath: "\(keyPath)", value: newValue)) } /// Set value at ``Mutable`` KeyPath on ``AtomicState``. - func setValue, Value>( + func setValue, Value>( _ newValue: Value, - _ keyPath: KeyPath>, - at identifier: I + _ keyPath: KeyPath>, + at identifier: Identifier ) { setValue(newValue, keyPath.appending(path: \.wrappedValue), at: identifier) telemetry.log(event: TestingMutation(context: .init(), keyPath: "\(keyPath):\(identifier)", value: newValue)) @@ -34,16 +37,16 @@ public extension ApplicationEnvironment { } -final class TestingMutation: TelemetryEvent { +final class TestingMutation: TelemetryEvent { let category: String = "Testing: State Mutation" let name: String = "Property updated:" let logLevel: OSLogType = .debug let context: Decide.Context let keyPath: String - let value: V + let value: Value - init(context: Decide.Context, keyPath: String, value: V) { + init(context: Decide.Context, keyPath: String, value: Value) { self.keyPath = keyPath self.context = context self.value = value