Skip to content

Instantly share code, notes, and snippets.

@oleksii-demedetskyi
Created May 25, 2017 09:27
Show Gist options
  • Save oleksii-demedetskyi/c6ca6b3d47dcadfbce302a673d8ea034 to your computer and use it in GitHub Desktop.
Save oleksii-demedetskyi/c6ca6b3d47dcadfbce302a673d8ea034 to your computer and use it in GitHub Desktop.
protocol Parsable {
static func parse(from object: Any) throws -> Self
}
public typealias JSON = [String: Any]
enum ParseError<T>: Swift.Error {
case cannotConvert(value: Any, toType: T.Type)
}
extension Parsable {
static func parse(from object: Any) throws -> Self {
guard let result = object as? Self else {
throw ParseError.cannotConvert(value: object, toType: Self.self)
}
return result
}
}
extension String: Parsable {}
extension Int: Parsable {}
extension UInt: Parsable {}
extension Bool: Parsable {}
extension Float: Parsable {}
extension Double: Parsable {}
extension Dictionary: Parsable {}
extension Array: Parsable {}
extension Array where Element: Parsable {
static func parse(from object: Any) throws -> Array {
guard let array = object as? [Any] else {
throw ParseError.cannotConvert(value: object, toType: [Any].self)
}
return try array.map(Element.parse(from:))
}
}
enum JSONError<Key>: Swift.Error {
case missedKey(Key)
case cannotParse(key: Key, error: Error)
}
extension Dictionary {
func parse <T: Parsable> (_ key: Key) throws -> T {
guard let value = self[key] else {
throw JSONError.missedKey(key)
}
do {
return try T.parse(from: value)
} catch let parseError {
throw JSONError.cannotParse(key: key, error: parseError)
}
}
func parse <T: Parsable> (_ key: Key) -> T? {
guard let object = self[key] else { return nil }
return try? T.parse(from: object)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment