Skip to content

Instantly share code, notes, and snippets.

@trilliwon
Last active March 24, 2022 04:36
Show Gist options
  • Save trilliwon/219434fceb0bc77cd626e95f2be0fdd9 to your computer and use it in GitHub Desktop.
Save trilliwon/219434fceb0bc77cd626e95f2be0fdd9 to your computer and use it in GitHub Desktop.
import Foundation
@dynamicMemberLookup
public struct Builder<Base: AnyObject> {
let _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 func build() -> Base {
_build()
}
public func set<Value>(_ keyPath: ReferenceWritableKeyPath<Base, Value>, to value: Value) -> Builder<Base> {
Builder {
let object = build()
object[keyPath: keyPath] = value
return object
}
}
public func `do`(_ handler: @escaping (Base) -> Void) -> Builder<Base> {
Builder { [build = _build] in
let object = build()
handler(object)
return object
}
}
}
public protocol Buildable {
associatedtype Base: AnyObject
var builder: Builder<Base> { get }
}
public extension Buildable where Self: AnyObject {
var builder: Builder<Self> {
Builder(self)
}
}
extension NSObject: Buildable {}
@trilliwon
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment