Skip to content

Instantly share code, notes, and snippets.

@lokshunhung
Created November 9, 2023 12:13
Show Gist options
  • Save lokshunhung/73a9367b32512f2c721b2130a27d3f2b to your computer and use it in GitHub Desktop.
Save lokshunhung/73a9367b32512f2c721b2130a27d3f2b to your computer and use it in GitHub Desktop.
Proxy for reference types, like SwiftUI.Binding
import Foundation
@propertyWrapper
public struct OptionalProxy<Value> where Value: OptionalProtocol {
public var wrappedValue: Value {
get { get() }
set { set(newValue) }
}
public let get: () -> Value
public let set: (Value) -> Void
public init(get: @escaping () -> Value,
set: @escaping (Value) -> Void) {
self.get = get
self.set = set
}
public init<Root: AnyObject>(
object: Root,
keyPath: ReferenceWritableKeyPath<Root, Value>
) {
self.get = { [weak object] in
guard let object else { return nil }
return object[keyPath: keyPath]
}
self.set = { [weak object] value in
guard let object else { return }
object[keyPath: keyPath] = value
}
}
}
public protocol OptionalProtocol: ExpressibleByNilLiteral {
associatedtype OptionalType
}
extension Optional: OptionalProtocol {
public typealias OptionalType = Wrapped
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment