From a1299dd50e79760b5216525b12a96536f159149b Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 20 Feb 2017 12:12:49 +0100 Subject: [PATCH 1/2] Add flatMap method on JSON Object --- SwiftyJSONModel/JSONObject.swift | 20 ++++++++++++++++++++ SwiftyJSONModelTests/JSONObjectTests.swift | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/SwiftyJSONModel/JSONObject.swift b/SwiftyJSONModel/JSONObject.swift index 097d6ed..b5b2dec 100644 --- a/SwiftyJSONModel/JSONObject.swift +++ b/SwiftyJSONModel/JSONObject.swift @@ -97,6 +97,26 @@ public extension JSONObject where PropertyType.RawValue == String { } } + public func flatMap(for keyPath: PropertyType...) throws -> [T] { + return try flatMap(for: keyPath) + } + + private func flatMap(for keyPath: [PropertyType]) throws -> [T] { + assert(keyPath.isEmpty == false, "KeyPath cannot be empty") + + let key = keyPath[0] + do { + if keyPath.count == 1 { + return try self[key].arrayValue().lazy.flatMap({ try? T(json: $0) }) + } else { + let subPath: [PropertyType] = .init(keyPath[1..(json: self[key]).flatMap(for: subPath) + } + } catch let error as JSONModelError { + throw JSONModelError.invalidValueFor(key: key.rawValue, error) + } + } + // MARK: - Optional methods public func value(for keyPath: PropertyType...) -> T? { return try? value(for: keyPath) diff --git a/SwiftyJSONModelTests/JSONObjectTests.swift b/SwiftyJSONModelTests/JSONObjectTests.swift index 0f29e86..78bc0dc 100644 --- a/SwiftyJSONModelTests/JSONObjectTests.swift +++ b/SwiftyJSONModelTests/JSONObjectTests.swift @@ -124,4 +124,22 @@ class JSONObjectTests: XCTestCase { XCTAssertEqual((object.value(for: .first, .second, .array) as [Int]?)!, [1, 2, 3]) XCTAssertNil(object.value(for: .first, .second, .array) as [String]?) } + + func testJSONObjectFlatMap() { + enum PropertyKey: String { + case first, second, third, array + } + + let nestedJSON: JSON = ["first": ["second": ["third": 3, "array": [1, "test", 3]]]] + let object = try! JSONObject(json: nestedJSON) + + XCTAssertEqual(try! object.flatMap(for: .first, .second, .array), [1, 3]) + XCTAssertEqual(try! object.flatMap(for: .first, .second, .array), ["test"]) + XCTAssertThrowsError(try object.flatMap(for: .first, .second, .third) as [Int]) { error in + let first = PropertyKey.first.rawValue + let second = PropertyKey.second.rawValue + let third = PropertyKey.third.rawValue + XCTAssertEqual(error as? JSONModelError, .invalidValueFor(key: first, .invalidValueFor(key: second, .invalidValueFor(key: third, .invalidElement)))) + } + } } From 1a633626f27912b01171f7879a6d387b3d9be0cb Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 20 Feb 2017 12:14:05 +0100 Subject: [PATCH 2/2] Make method that take as param keyPath array private --- SwiftyJSONModel/JSONObject.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SwiftyJSONModel/JSONObject.swift b/SwiftyJSONModel/JSONObject.swift index b5b2dec..c498592 100644 --- a/SwiftyJSONModel/JSONObject.swift +++ b/SwiftyJSONModel/JSONObject.swift @@ -55,7 +55,7 @@ public extension JSONObject where PropertyType.RawValue == String { return try value(for: keyPath) } - public func value(for keyPath: [PropertyType]) throws -> T { + private func value(for keyPath: [PropertyType]) throws -> T { assert(keyPath.isEmpty == false, "KeyPath cannot be empty") let key = keyPath[0] @@ -75,7 +75,7 @@ public extension JSONObject where PropertyType.RawValue == String { return try value(for: keyPath) } - public func value(for keyPath: [PropertyType]) throws -> [T] { + private func value(for keyPath: [PropertyType]) throws -> [T] { assert(keyPath.isEmpty == false, "KeyPath cannot be empty") let key = keyPath[0]