Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

Swift 3.0 Beta Seed 6 #70

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 33 additions & 22 deletions Sources/Mapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ public struct Mapper {

- returns: An array of the RawRepresentable value, with all nils removed
*/
public func from<T: RawRepresentable where T.RawValue: Convertible,
T.RawValue == T.RawValue.ConvertedType>(_ field: String, defaultValue: T? = nil) throws -> [T]
public func from<T: RawRepresentable>(_ field: String, defaultValue: T? = nil) throws -> [T] where T.RawValue: Convertible,
T.RawValue == T.RawValue.ConvertedType
{
let value = try self.JSONFromField(field)
guard let array = value as? [AnyObject] else {
Expand Down Expand Up @@ -218,7 +218,7 @@ public struct Mapper {

- returns: The value for the given field, if it can be converted to the expected type T
*/
public func from<T: Convertible where T == T.ConvertedType>(_ field: String) throws -> T {
public func from<T: Convertible>(_ field: String) throws -> T where T == T.ConvertedType {
return try self.from(field, transformation: T.fromMap)
}

Expand All @@ -236,7 +236,7 @@ public struct Mapper {

- returns: The value for the given field, if it can be converted to the expected type Optional<T>
*/
public func from<T: Convertible where T == T.ConvertedType>(_ field: String) throws -> T? {
public func from<T: Convertible>(_ field: String) throws -> T? where T == T.ConvertedType {
return try self.from(field, transformation: T.fromMap)
}

Expand All @@ -254,7 +254,7 @@ public struct Mapper {

- returns: The value for the given field, if it can be converted to the expected type [T]
*/
public func from<T: Convertible where T == T.ConvertedType>(_ field: String) throws -> [T] {
public func from<T: Convertible>(_ field: String) throws -> [T] where T == T.ConvertedType {
let value = try self.JSONFromField(field)
if let JSON = value as? [AnyObject] {
return try JSON.map(T.fromMap)
Expand All @@ -273,7 +273,7 @@ public struct Mapper {

- returns: The value for the given field, if it can be converted to the expected type T otherwise nil
*/
public func optionalFrom<T: Convertible where T == T.ConvertedType>(_ field: String) -> T? {
public func optionalFrom<T: Convertible>(_ field: String) -> T? where T == T.ConvertedType {
return try? self.from(field, transformation: T.fromMap)
}

Expand All @@ -287,7 +287,7 @@ public struct Mapper {

- returns: The value for the given field, if it can be converted to the expected type [T]
*/
public func optionalFrom<T: Convertible where T == T.ConvertedType>(_ field: String) -> [T]? {
public func optionalFrom<T: Convertible>(_ field: String) -> [T]? where T == T.ConvertedType {
return try? self.from(field)
}

Expand All @@ -304,19 +304,27 @@ public struct Mapper {

- returns: A dictionary where the keys and values are created using their convertible implementations
*/
public func from<U: Convertible, T: Convertible
where U == U.ConvertedType, T == T.ConvertedType>(_ field: String) throws -> [U: T]
public func from<U: Convertible, T: Convertible>(_ field: String) throws -> [U: T]
where U == U.ConvertedType, T == T.ConvertedType
{
let object = try self.JSONFromField(field)
guard let data = object as? NSDictionary else {
throw MapperError.typeMismatchError(field: field, value: object, type: NSDictionary.self)
}

var result = [U: T]()
for (key, value) in data {
result[try U.fromMap(key)] = try T.fromMap(value)
if let data = object as? NSDictionary {
for (key, value) in data {
result[try U.fromMap(key as AnyObject?)] = try T.fromMap(value as AnyObject?)
}
}
else if let data = object as? [AnyHashable: Any] {
for (key, value) in data {
result[try U.fromMap(key as AnyObject?)] = try T.fromMap(value as AnyObject?)
}
}
else {
throw MapperError.typeMismatchError(field: field, value: object, type: NSDictionary.self)
}


return result
}

Expand All @@ -331,8 +339,8 @@ public struct Mapper {
- returns: A dictionary where the keys and values are created using their convertible implementations or
nil if anything throws
*/
public func optionalFrom<U: Convertible, T: Convertible
where U == U.ConvertedType, T == T.ConvertedType>(_ field: String) -> [U: T]?
public func optionalFrom<U: Convertible, T: Convertible>(_ field: String) -> [U: T]?
where U == U.ConvertedType, T == T.ConvertedType
{
return try? self.from(field)
}
Expand All @@ -345,7 +353,7 @@ public struct Mapper {

- returns: The first non-nil value to be produced from the array of fields, or nil if none exist
*/
public func optionalFrom<T: Convertible where T == T.ConvertedType>(_ fields: [String]) -> T? {
public func optionalFrom<T: Convertible>(_ fields: [String]) -> T? where T == T.ConvertedType {
for field in fields {
if let value: T = try? self.from(field) {
return value
Expand All @@ -370,8 +378,10 @@ public struct Mapper {

- returns: The value of type T for the given field
*/
public func from<T>(_ field: String, transformation: @noescape (AnyObject?) throws -> T) throws -> T {
return try transformation(try self.JSONFromField(field))
public func from<T>(_ field: String, transformation: (AnyObject?) throws -> T) throws -> T {
let json = try self.JSONFromField(field)

return try transformation(json)
}

/**
Expand All @@ -384,7 +394,7 @@ public struct Mapper {
- returns: The value of type T for the given field, if the transformation function doesn't throw
otherwise nil
*/
public func optionalFrom<T>(_ field: String, transformation: @noescape (AnyObject?) throws -> T?) -> T? {
public func optionalFrom<T>(_ field: String, transformation: (AnyObject?) throws -> T?) -> T? {
return (try? transformation(try? self.JSONFromField(field))).flatMap { $0 }
}

Expand All @@ -402,8 +412,9 @@ public struct Mapper {
- returns: The object for the given field
*/
private func JSONFromField(_ field: String) throws -> AnyObject {
if let value = field.isEmpty ? self.JSON : self.JSON.safeValue(forKeyPath: field) {
return value
let optionalValue: Any? = field.isEmpty ? self.JSON : self.JSON.safeValue(forKeyPath: field)
if let value = optionalValue {
return value as AnyObject
}

throw MapperError.missingFieldError(field: field)
Expand Down
2 changes: 1 addition & 1 deletion Sources/MapperError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- MissingFieldError: An error thrown when the desired key isn't in the JSON
- TypeMismatchError: Thrown when the desired key exists in the JSON, but does not match the expected type
*/
public enum MapperError: ErrorProtocol {
public enum MapperError: Error {
case convertibleError(value: AnyObject?, type: Any.Type)
case customError(field: String?, message: String)
case invalidRawValueError(field: String, value: Any, type: Any.Type)
Expand Down
4 changes: 2 additions & 2 deletions Sources/NSDictionary+Safety.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Foundation

extension NSDictionary {
func safeValue(forKeyPath keyPath: String) -> AnyObject? {
var object: AnyObject? = self
func safeValue(forKeyPath keyPath: String) -> Any? {
var object: Any? = self
var keys = keyPath.characters.split(separator: ".").map(String.init)

while keys.count > 0, let currentObject = object {
Expand Down
4 changes: 2 additions & 2 deletions Sources/Transform+Dictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public extension Transform {
- returns: A dictionary of [U: T] where the keys U are produced from the passed `key` function and the
values T are the objects
*/
public static func toDictionary<T, U where T: Mappable, U: Hashable>(key getKey: (T) -> U) ->
(object: AnyObject?) throws -> [U: T]
public static func toDictionary<T, U>(key getKey: @escaping (T) -> U) ->
(_ object: AnyObject?) throws -> [U: T] where T: Mappable, U: Hashable
{
return { object in
guard let objects = object as? [NSDictionary] else {
Expand Down
5 changes: 3 additions & 2 deletions Tests/Mapper/ConvertibleValueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ final class ConvertibleValueTests: XCTestCase {
}
}

let test = Test.from(["foo": ["key": 1]])
let JSON = ["foo": ["key": 1]]
let test = Test.from(JSON as NSDictionary)
XCTAssertTrue(test?.dictionary["key"] == 1)
}

Expand All @@ -164,7 +165,7 @@ final class ConvertibleValueTests: XCTestCase {
}

let test = Test.from(["foo": ["key": "value"]])
XCTAssertTrue(test?.dictionary.count > 0)
XCTAssertGreaterThan(test?.dictionary.count ?? 0, 0)
}

func testOptionalDictionaryConvertibleNil() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/Mapper/ErrorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ final class ErrorTests: XCTestCase {
} catch MapperError.missingFieldError(let field) {
XCTAssert(field == "string")
} catch {
XCTFail()
XCTFail("Expected only missing field error, got \(error)")
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/Mapper/NormalValueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ final class NormalValueTests: XCTestCase {
}

let JSON = ["a": "b", "c": "d"]
let test = try? Test(map: Mapper(JSON: JSON))
let test = try? Test(map: Mapper(JSON: JSON as NSDictionary))
let parsedJSON = test?.JSON as? [String: String] ?? [:]
XCTAssertTrue(parsedJSON == JSON)
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/Mapper/TransformTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ final class TransformTests: XCTestCase {
]
]

let test = Test.from(JSON)
let test = Test.from(JSON as NSDictionary)
XCTAssertTrue(test?.dictionary.count == 2)
XCTAssertTrue(test?.dictionary["hi"] == Example(key: "hi", value: 1))
XCTAssertTrue(test?.dictionary["bye"] == Example(key: "bye", value: 2))
Expand Down Expand Up @@ -95,7 +95,7 @@ final class TransformTests: XCTestCase {
]
]

let test = try? Test(map: Mapper(JSON: JSON))
let test = try? Test(map: Mapper(JSON: JSON as NSDictionary))
XCTAssertNil(test)
}

Expand Down