-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mapper.swift
98 lines (80 loc) · 2.41 KB
/
Mapper.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import Foundation
public class Mapper {
private let jsonObject: [String: Any]?
private let jsonArray: [Any]?
public init(_ json: [String: Any]) {
self.jsonObject = json
self.jsonArray = nil
}
public init(_ json: [Any]) {
self.jsonObject = nil
self.jsonArray = json
}
public func value<T: Transform>(_ key: String, using transform: T) throws -> T.Object {
if let object = jsonObject?[key], let t = transform.transform(input: object) {
return t
} else {
throw MappingError()
}
}
public func value<T: Transform>(_ index: Int, using transform: T) throws -> T.Object {
if index >= 0, index < jsonArray?.count ?? 0, let object = jsonArray?[index], let t = transform.transform(input: object) {
return t
} else {
throw MappingError()
}
}
public func value<T>(_ key: String) throws -> T {
if let t = jsonObject?[key] as? T {
return t
} else {
throw MappingError()
}
}
public func value<T>(_ index: Int) throws -> T {
if index >= 0, index < jsonArray?.count ?? 0, let t = jsonArray?[index] as? T {
return t
} else {
throw MappingError()
}
}
}
public protocol Transform {
associatedtype Object
func transform(input: Any) -> Object?
}
public final class DateFormatterTransform: Transform {
typealias Object = Date
private let dateFormatter: DateFormatter
init(dateFormatter: DateFormatter) {
self.dateFormatter = dateFormatter
}
func transform(input: Any) -> Date? {
if let dateString = input as? String, let date = dateFormatter.date(from: dateString) {
return date
} else {
return nil
}
}
}
public class URLTransform: Transform {
typealias Object = URL
func transform(input: Any) -> URL? {
if let urlString = input as? String, let url = URL(string: urlString) {
return url
} else {
return nil
}
}
}
public class RawRepresentableTransform<R: RawRepresentable>: Transform {
typealias Object = R
func transform(input: Any) -> R? {
if let rawValue = input as? R.RawValue, let r = R(rawValue: rawValue) {
return r
} else {
return nil
}
}
}
public struct MappingError: Error {}