Reputation: 4176
I have a need to extend struct
having failable initializer with a throwing initializer calling that failable initializer. And I see no elegant or clear way to do that in Swift 3.1.
Something like this:
extension Product: JSONDecodable {
public enum Error: Swift.Error {
case unableToParseJSON
}
init(decodeFromJSON json: JSON) throws {
guard let jsonObject = json as? JSONObject else {
throw Error.unableToParseJSON
}
// Meta-code
self.init(dictionary: jsonObject) ?? throw Error.unableToParseJSON
}
}
Is there an elegant and clean way to do that?
Upvotes: 6
Views: 1813
Reputation: 4176
Found a semi-clean way to do that while writing the question:
extension Product: JSONDecodable {
public enum Error: Swift.Error {
case unableToParseJSON
}
init(decodeFromJSON json: JSON) throws {
guard let jsonObject = json as? JSONObject,
let initialized = Self(dictionary: jsonObject)
else {
throw Error.unableToParseJSON
}
self = initialized
}
}
Upvotes: 16
Reputation: 19
The above is the best method I've seen, nice work. Just a small tweak that uses Self
instead of type(of: self)
for neatness:
extension Product: JSONDecodable {
public enum Error: Swift.Error {
case unableToParseJSON
}
init(decodeFromJSON json: JSON) throws {
guard let jsonObject = json as? JSONObject,
let initialized = Self.init(dictionary: jsonObject)
else {
throw Error.unableToParseJSON
}
self = initialized
}
}
Upvotes: 0