Created
February 26, 2015 14:17
-
-
Save yashigani/cbc88af9c0b0d463cebf to your computer and use it in GitHub Desktop.
JSON Parser
This file contains hidden or 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
import Foundation | |
public class JSON: Printable { | |
private let object: JSONObject | |
init(_ object: AnyObject?) { | |
self.object = JSONObject.parse(object) | |
} | |
private init(_ object: JSONObject) { | |
self.object = object | |
} | |
private class var error: JSON { return JSON(.Err(JSONObject.parseError)) } | |
subscript(k: String) -> JSON { | |
switch self.object { | |
case .Obj(let obj) where obj[k] != nil: return JSON(obj[k]!) | |
default: return JSON.error | |
} | |
} | |
subscript(n: Int) -> JSON { | |
switch self.object { | |
case .Arr(let arr): return JSON(arr[n]) | |
default: return JSON.error | |
} | |
} | |
var string: String { | |
switch self.object { | |
case .Str(let str): return str | |
default: abort() | |
} | |
} | |
var number: NSNumber { | |
switch self.object { | |
case .Num(let num): return num | |
default: abort() | |
} | |
} | |
public var description: String { return "JSON(\(object))" } | |
private enum JSONObject: Printable { | |
case Obj([String: JSONObject]) | |
case Arr([JSONObject]) | |
case Str(String) | |
case Num(NSNumber) | |
case Null | |
case Err(NSError) | |
static var parseError: NSError { | |
return NSError(domain: "JSONObject parse error", code: -100, userInfo: nil) | |
} | |
static func parse(JSON: AnyObject?) -> JSONObject { | |
switch JSON { | |
case let obj as [String: AnyObject]: | |
var object: [String: JSONObject] = [:] | |
map(obj) { object[$0] = self.parse($1) } | |
return .Obj(object) | |
case let arr as [AnyObject]: return .Arr(arr.map { self.parse($0) }) | |
case let str as String: return .Str(str) | |
case let num as NSNumber: return .Num(num) | |
case let null as NSNull: return .Null | |
default: return .Err(parseError) | |
} | |
} | |
private var description: String { | |
switch self { | |
case .Obj(let obj): return "Obj(\(obj))" | |
case .Arr(let arr): return "Arr(\(arr))" | |
case .Str(let str): return "Str(\(str))" | |
case .Num(let num): return "Num(\(num))" | |
case .Null: return "Null" | |
case .Err(let e): return "Err\(e)" | |
default: "abon" | |
} | |
} | |
} | |
} | |
let obj = [ | |
"Alfa": ["age": 20, "gender": "male"], | |
"Bravo": ["age": 21, "gender": "male"], | |
"Charlie": ["age": 23, "gender": "male"], | |
] | |
let json = JSON(obj) | |
json["Alfa"]["age"].number | |
json["Bravo"]["age"].number | |
json["Charlie"]["age"].number |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment