Last active
August 7, 2018 10:50
-
-
Save kaqu/762e29e12a984b4a53cd9fb720f2ea89 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol Buildable { | |
init(dict: [AnyKeyPath: Any]) throws | |
} | |
struct BuilderError : Error { | |
let reason: String | |
} | |
struct SomeBuildable : Buildable { | |
let field1: String | |
let field2: Int? | |
let field3: [SomeEnum] | |
enum SomeEnum { | |
case first | |
} | |
init(dict: [AnyKeyPath: Any]) throws { | |
guard let field1 = dict[\SomeBuildable.field1] as? String else { | |
throw BuilderError(reason: "Missing field1") | |
} | |
self.field1 = field1 | |
guard let field2 = dict[\SomeBuildable.field2] as? Int else { | |
throw BuilderError(reason: "Missing field2") | |
} | |
self.field2 = field2 | |
guard let field3 = dict[\SomeBuildable.field3] as? [SomeEnum] else { | |
throw BuilderError(reason: "Missing field3") | |
} | |
self.field3 = field3 | |
} | |
} | |
struct Builder<E : Buildable> { | |
var dict: [AnyKeyPath: Any] = [:] | |
mutating func setValue<T>(_ val: T, for keyPath: KeyPath<E, T>) { | |
dict[keyPath] = val | |
} | |
func build() throws -> E { | |
return try E.init(dict: dict) | |
} | |
} | |
var builder = Builder<SomeBuildable>.init() | |
builder.setValue("Value", for: \SomeBuildable.field1) | |
builder.setValue(nil, for: \SomeBuildable.field2) | |
builder.setValue([.first], for: \SomeBuildable.field3) | |
let product = try? builder.build() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment