Skip to content

Instantly share code, notes, and snippets.

@EmingK
Created September 24, 2021 11:56
Show Gist options
  • Save EmingK/2c01e63f5946f6a15b9a984c1d2cfaa1 to your computer and use it in GitHub Desktop.
Save EmingK/2c01e63f5946f6a15b9a984c1d2cfaa1 to your computer and use it in GitHub Desktop.
脑洞(
struct Test1 {
var ww: Int
var xx: String
}
struct Partial<T> {
internal var values: [PartialKeyPath<T>: Any] = [:]
subscript<V>(key: KeyPath<T, V>) -> V? {
get {
values[key] as? V
}
set {
values[key] = newValue
}
}
}
struct PatchablePropertyDescriptor<T> {
internal let applicator: (inout T, Any) -> ()
init<V>(keyPath: WritableKeyPath<T, V>) {
applicator = { this, value in
if let v = value as? V {
this[keyPath: keyPath] = v
}
}
}
}
protocol Patchable {
static var patchableProperties: [PartialKeyPath<Self>: PatchablePropertyDescriptor<Self>] { get }
}
extension Patchable {
mutating func apply(partial: Partial<Self>) {
partial.values.forEach { (k, v) in
if let property = Self.patchableProperties[k] {
property.applicator(&self, v)
} else {
print(type(of: k))
}
}
}
}
extension Test1: Patchable {
static let patchableProperties: [PartialKeyPath<Test1>: PatchablePropertyDescriptor<Test1>] = [
\Test1.ww: PatchablePropertyDescriptor(keyPath: \Test1.ww),
\Test1.xx: PatchablePropertyDescriptor(keyPath: \Test1.xx)
]
}
var t = Test1(ww: 1, xx: "aa")
var patch = Partial<Test1>()
patch[\Test1.xx] = "bb"
t.apply(partial: patch)
print(t)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment