From da4bdb6e413ace11cdf3327cb2d64d60bda24350 Mon Sep 17 00:00:00 2001 From: delba Date: Wed, 2 Sep 2015 13:18:53 +0200 Subject: [PATCH] Add static types --- JASON.playground/contents.xcplayground | 2 +- Source/JASON.swift | 109 +++++++++++++++++++++++++ Tests/JASONTests.swift | 56 +++++++++++++ 3 files changed, 166 insertions(+), 1 deletion(-) diff --git a/JASON.playground/contents.xcplayground b/JASON.playground/contents.xcplayground index a6f1353..ee7c14f 100644 --- a/JASON.playground/contents.xcplayground +++ b/JASON.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/Source/JASON.swift b/Source/JASON.swift index 3a9713a..57a35ce 100644 --- a/Source/JASON.swift +++ b/Source/JASON.swift @@ -190,6 +190,115 @@ private extension JSON { var nsArray: NSArray? { return object as? NSArray } } +// MARK: Static subscripts + +public class JSONKeys {} + +public class JSONKey: JSONKeys { + public let _key: String + + public init(_ key: String) { + self._key = key + } +} + +extension JSON { + /// The value as a string or nil if not present/convertible + public subscript(key: JSONKey) -> String? { + return self[key._key].string + } + + /// The value as a string or "" if not present/convertible + public subscript(key: JSONKey) -> String { + return self[key._key].stringValue + } + + /// The value as a boolean or nil if not present/convertible + public subscript(key: JSONKey) -> Bool? { + return self[key._key].bool + } + + /// The value as a boolean or false if not present/convertible + public subscript(key: JSONKey) -> Bool { + return self[key._key].boolValue + } + + /// The value as a 64-bit signed integer or nil if not present/convertible + public subscript(key: JSONKey) -> Int? { + return self[key._key].int + } + + /// The value as a 64-bit signed integer or 0 if not present/convertible + public subscript(key: JSONKey) -> Int { + return self[key._key].intValue + } + + /// The value as a 64-bit floating-point number or nil if not present/convertible + public subscript(key: JSONKey) -> Double? { + return self[key._key].double + } + + /// The value as a 64-bit floating-point number or 0.0 if not present/convertible + public subscript(key: JSONKey) -> Double { + return self[key._key].doubleValue + } + + /// The value as a 32-bit floating-point number or nil if not present/convertible + public subscript(key: JSONKey) -> Float? { + return self[key._key].float + } + + /// The value as a 32-bit floating-point number or 0.0 if not present/convertible + public subscript(key: JSONKey) -> Float { + return self[key._key].floatValue + } + +} + +extension JSON { + /// The value as an array or nil if not present/convertible + public subscript(key: JSONKey<[AnyObject]?>) -> [AnyObject]? { + return self[key._key].array + } + + /// The value as an array or an empty array if not present/convertible + public subscript(key: JSONKey<[AnyObject]>) -> [AnyObject] { + return self[key._key].arrayValue + } + + /// The value as an array or nil if not present/convertible + public subscript(key: JSONKey<[JSON]?>) -> [JSON]? { + return self[key._key].jsonArray + } + + /// The value as an array or an empty array if not present/convertible + public subscript(key: JSONKey<[JSON]>) -> [JSON] { + return self[key._key].jsonArrayValue + } +} + +extension JSON { + /// The value as a dictionary or nil if not present/convertible + public subscript(key: JSONKey<[String: AnyObject]?>) -> [String: AnyObject]? { + return self[key._key].dictionary + } + + /// The value as a dictionary or an empty dictionary if not present/convertible + public subscript(key: JSONKey<[String: AnyObject]>) -> [String: AnyObject] { + return self[key._key].dictionaryValue + } + + /// The value as a dictionary or nil if not present/convertible + public subscript(key: JSONKey<[String: JSON]?>) -> [String: JSON]? { + return self[key._key].jsonDictionary + } + + /// The value as a dictionary or an empty dictionary if not present/convertible + public subscript(key: JSONKey<[String: JSON]>) -> [String: JSON] { + return self[key._key].jsonDictionaryValue + } +} + // MARK: Operators infix operator <| { diff --git a/Tests/JASONTests.swift b/Tests/JASONTests.swift index fa6502b..cf68b43 100644 --- a/Tests/JASONTests.swift +++ b/Tests/JASONTests.swift @@ -26,7 +26,63 @@ import UIKit import XCTest import JASON +extension JSONKeys { + static let string = JSONKey("string") + static let optionalString = JSONKey("optionalString") + static let int = JSONKey("int") + static let optionalInt = JSONKey("optionalInt") + static let double = JSONKey("double") + static let optionalDouble = JSONKey("optionalDouble") + static let float = JSONKey("float") + static let optionalFloat = JSONKey("optionalFloat") + static let bool = JSONKey("bool") + static let optionalBool = JSONKey("optionalBool") + static let array = JSONKey<[AnyObject]>("array") + static let optionalArray = JSONKey<[AnyObject]?>("optionalArray") + static let dictionary = JSONKey<[String: AnyObject]>("dictionary") + static let optionalDictionary = JSONKey<[String: AnyObject]>("optionalDictionary") + static let arrayJSON = JSONKey<[JSON]>("arrayJSON") + static let optionalArrayJSON = JSONKey<[JSON]?>("optionalArrayJSON") + static let dictionaryJSON = JSONKey<[String: JSON]>("dictionaryJSON") + static let optinoalDictionaryJSON = JSONKey<[String: JSON]?>("optionalDictionaryJSON") +} + + class JASONTests: XCTestCase { + + func testStaticSubscripts() { + let json: JSON = [ + "string": "string", + "optionalString": "string", + "int": 42, + "optionalInt": 42, + "double": 4.2, + "optionalDouble": 4.2, + "float": 4.2, + "optionalFloat": 4.2, + "bool": true, + "optionalBool": true, + "array": ["string", 42, 4.2, true], + "optionalArray": ["string", 42, 4.2, true], + "dictionary": ["string": 42], + "optionalDictionary": ["string": 42], + ] + + XCTAssertEqual("string", json[.string]) + XCTAssertEqual("string", json[.optionalString]) + XCTAssertEqual(42, json[.int]) + XCTAssertEqual(42, json[.optionalInt]) + XCTAssertEqual(4.2, json[.double]) + XCTAssertEqual(4.2, json[.optionalDouble]) + XCTAssertEqual(4.2, json[.float]) + XCTAssertEqual(4.2, json[.optionalFloat]) + XCTAssertEqual(true, json[.bool]) + XCTAssertEqual(true, json[.optionalBool]) + XCTAssertEqualArrays(["string", 42, 4.2, true], json[.array]) + XCTAssertEqualArrays(["string", 42, 4.2, true], json[.optionalArray]!) + XCTAssertEqualDictionaries(["string": 42], json[.dictionary]) + XCTAssertEqualDictionaries(["string": 42], json[.optionalDictionary]) + } func testInitWithObject() { let object: AnyObject = ["name": "Brandon Walsh"]