Skip to content

Instantly share code, notes, and snippets.

@trilliwon
Last active July 26, 2023 09:22
Show Gist options
  • Save trilliwon/e911dd97dd466b83fc4dab77ab463637 to your computer and use it in GitHub Desktop.
Save trilliwon/e911dd97dd466b83fc4dab77ab463637 to your computer and use it in GitHub Desktop.
@dynamicMemberLookup
public struct Builder<Base> {
public var build: () -> Base
public init(_ build: @escaping () -> Base) {
self.build = build
}
public init(_ base: Base) {
self.build = { base }
}
public subscript<Value>(dynamicMember keyPath: ReferenceWritableKeyPath<Base, Value>) -> (Value) -> Builder<Base> {
{ [build = build] value in
Builder {
let object = build()
object[keyPath: keyPath] = value
return object
}
}
}
public subscript<Value>(dynamicMember keyPath: WritableKeyPath<Base, Value>) -> (Value) -> Builder<Base> {
{ [build = build] value in
Builder {
var object = build()
object[keyPath: keyPath] = value
return object
}
}
}
public func `do`(_ handler: @escaping (Base) throws -> Void) rethrows -> Builder<Base> {
let object = build()
try handler(object)
return Builder(object)
}
}
public protocol Buildable {
associatedtype Base
var builder: Builder<Base> { get }
}
public extension Buildable where Self: AnyObject {
var builder: Builder<Self> {
Builder(self)
}
}
public extension Buildable where Self: Any {
var builder: Builder<Self> {
Builder(self)
}
}
extension NSObject: Buildable {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment