Skip to content

Instantly share code, notes, and snippets.

@IanKeen
Created February 15, 2018 20:03
Show Gist options
  • Save IanKeen/b921224eb430f1ea305df243c55ffa47 to your computer and use it in GitHub Desktop.
Save IanKeen/b921224eb430f1ea305df243c55ffa47 to your computer and use it in GitHub Desktop.
A simpler swifty lens pattern
public protocol KeypathUpdatable {
func update<T>(_ keyPath: WritableKeyPath<Self, T>, to value: T) -> Self
}
public extension KeypathUpdatable {
public func update<T>(_ keyPath: WritableKeyPath<Self, T>, to value: T) -> Self {
var copy = self
copy[keyPath: keyPath] = value
return copy
}
}
// User.swift
struct User {
private(set) var name: String
private(set) var pet: Pet
}
extension User: KeypathUpdatable { }
// Pet.swift
struct Pet {
private(set) var name: String
}
extension Pet: KeypathUpdatable { }
// elsewhere...
let user = User(name: "John", pet: Pet(name: "Fido"))
user.name // John
user.pet.name // Fido
let newName = user.update(\.name, to: "Jane")
newName.name // Jane
newName.pet.name // Fido
let newPetName = newName.update(\.pet.name, to: "Tabby")
newPetName.name // Jane
newPetName.pet.name // Tabby
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment