Skip to content

Instantly share code, notes, and snippets.

@Alexander-Ignition
Created November 14, 2016 13:32
Show Gist options
  • Save Alexander-Ignition/2a814a9cbe01f07ee82ff6311cb2e0df to your computer and use it in GitHub Desktop.
Save Alexander-Ignition/2a814a9cbe01f07ee82ff6311cb2e0df to your computer and use it in GitHub Desktop.
import Foundation
public enum Error: Int, ErrorType {
public static let Domain = "Italmass.Error.Domain"
case Missing
case Invalid
}
extension NSError {
convenience init(_ code: Error, _ description: String) {
let userInfo = [NSLocalizedDescriptionKey: description]
self.init(domain: Error.Domain, code: code.rawValue, userInfo: userInfo)
}
}
extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
public func valueFor<T>(key key: Key) throws -> T {
guard let value = self[key] else {
throw NSError(.Missing, "Missing value for key `\(key)`.")
}
guard let correct = value as? T else {
throw NSError(.Invalid, "Invalid value for key `\(key)`. Expected type `\(T.self)`. Unexpected type `\(value.dynamicType)`.")
}
return correct
}
public func valueFor<T>(keyPath keys: [Key]) throws -> T {
var keyPath = keys
guard let lastKey = keyPath.popLast() else {
throw NSError(.Missing, "Key path is empty.")
}
let dict = try keyPath.reduce(self) { try $0.valueFor(key: $1) }
return try dict.valueFor(key: lastKey)
}
public func valueFor<T, U>(key key: Key, transform: (U throws -> T?)) throws -> T {
let origin: U = try valueFor(key: key)
guard let value = try transform(origin) else {
throw NSError(.Missing, "Value: \(origin) for key: `\(key)` not transformed.")
}
return value
}
}
struct User {
let id: UInt
let name: String
let birthday: NSDate
let cars: [Car]
init(dictyonary: [String: AnyObject]) throws {
id = try dictyonary.valueFor(key: "object_id")
name = try dictyonary.valueFor(key: "first_name")
birthday = try dictyonary.valueFor(key: "birthday") { NSDate(timeIntervalSince1970: $0) }
let array: [[String: AnyObject]] = try dictyonary.valueFor(key: "cars")
cars = try array.map { try Car(dictyonary: $0) }
}
}
struct Car {
let name: String
init(dictyonary: [String: AnyObject]) throws {
name = try dictyonary.valueFor(keyPath: ["model", "name"])
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment