Blame view

Pods/HandyJSON/Source/BuiltInBasicType.swift 7.43 KB
75d24c15   yangbin   123
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
  /*
   * Copyright 1999-2101 Alibaba Group.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  //  Created by zhouzhuo on 7/7/16.
  //
  
  import Foundation
  
  protocol _BuiltInBasicType: _Transformable {
  
      static func _transform(from object: Any) -> Self?
      func _plainValue() -> Any?
  }
  
  // Suppport integer type
  
  protocol IntegerPropertyProtocol: FixedWidthInteger, _BuiltInBasicType {
      init?(_ text: String, radix: Int)
      init(_ number: NSNumber)
  }
  
  extension IntegerPropertyProtocol {
  
      static func _transform(from object: Any) -> Self? {
          switch object {
          case let str as String:
              return Self(str, radix: 10)
          case let num as NSNumber:
              return Self(num)
          default:
              return nil
          }
      }
      
      func _plainValue() -> Any? {
          return self
      }
  }
  
  extension Int: IntegerPropertyProtocol {}
  extension UInt: IntegerPropertyProtocol {}
  extension Int8: IntegerPropertyProtocol {}
  extension Int16: IntegerPropertyProtocol {}
  extension Int32: IntegerPropertyProtocol {}
  extension Int64: IntegerPropertyProtocol {}
  extension UInt8: IntegerPropertyProtocol {}
  extension UInt16: IntegerPropertyProtocol {}
  extension UInt32: IntegerPropertyProtocol {}
  extension UInt64: IntegerPropertyProtocol {}
  
  extension Bool: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> Bool? {
          switch object {
          case let str as NSString:
              let lowerCase = str.lowercased
              if ["0", "false"].contains(lowerCase) {
                  return false
              }
              if ["1", "true"].contains(lowerCase) {
                  return true
              }
              return nil
          case let num as NSNumber:
              return num.boolValue
          default:
              return nil
          }
      }
  
      func _plainValue() -> Any? {
          return self
      }
  }
  
  // Support float type
  
  protocol FloatPropertyProtocol: _BuiltInBasicType, LosslessStringConvertible {
      init(_ number: NSNumber)
  }
  
  extension FloatPropertyProtocol {
  
      static func _transform(from object: Any) -> Self? {
          switch object {
          case let str as String:
              return Self(str)
          case let num as NSNumber:
              return Self(num)
          default:
              return nil
          }
      }
  
      func _plainValue() -> Any? {
          return self
      }
  }
  
  extension Float: FloatPropertyProtocol {}
  extension Double: FloatPropertyProtocol {}
  
  fileprivate let formatter: NumberFormatter = {
      let formatter = NumberFormatter()
      formatter.usesGroupingSeparator = false
      formatter.numberStyle = .decimal
      formatter.maximumFractionDigits = 16
      return formatter
  }()
  
  extension String: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> String? {
          switch object {
          case let str as String:
              return str
          case let num as NSNumber:
              // Boolean Type Inside
              if NSStringFromClass(type(of: num)) == "__NSCFBoolean" {
                  if num.boolValue {
                      return "true"
                  } else {
                      return "false"
                  }
              }
              return formatter.string(from: num)
          case _ as NSNull:
              return nil
          default:
              return "\(object)"
          }
      }
  
      func _plainValue() -> Any? {
          return self
      }
  }
  
  // MARK: Optional Support
  
  extension Optional: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> Optional? {
          if let value = (Wrapped.self as? _Transformable.Type)?.transform(from: object) as? Wrapped {
              return Optional(value)
          } else if let value = object as? Wrapped {
              return Optional(value)
          }
          return nil
      }
  
      func _getWrappedValue() -> Any? {
          return self.map( { (wrapped) -> Any in
              return wrapped as Any
          })
      }
  
      func _plainValue() -> Any? {
          if let value = _getWrappedValue() {
              if let transformable = value as? _Transformable {
                  return transformable.plainValue()
              } else {
                  return value
              }
          }
          return nil
      }
  }
  
  // MARK: Collection Support : Array & Set
  
  extension Collection {
  
      static func _collectionTransform(from object: Any) -> [Iterator.Element]? {
          guard let arr = object as? [Any] else {
              InternalLogger.logDebug("Expect object to be an array but it's not")
              return nil
          }
          typealias Element = Iterator.Element
          var result: [Element] = [Element]()
          arr.forEach { (each) in
              if let element = (Element.self as? _Transformable.Type)?.transform(from: each) as? Element {
                  result.append(element)
              } else if let element = each as? Element {
                  result.append(element)
              }
          }
          return result
      }
  
      func _collectionPlainValue() -> Any? {
          typealias Element = Iterator.Element
          var result: [Any] = [Any]()
          self.forEach { (each) in
              if let transformable = each as? _Transformable, let transValue = transformable.plainValue() {
                  result.append(transValue)
              } else {
                  InternalLogger.logError("value: \(each) isn't transformable type!")
              }
          }
          return result
      }
  }
  
  extension Array: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> [Element]? {
          return self._collectionTransform(from: object)
      }
  
      func _plainValue() -> Any? {
          return self._collectionPlainValue()
      }
  }
  
  extension Set: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> Set<Element>? {
          if let arr = self._collectionTransform(from: object) {
              return Set(arr)
          }
          return nil
      }
  
      func _plainValue() -> Any? {
          return self._collectionPlainValue()
      }
  }
  
  // MARK: Dictionary Support
  
  extension Dictionary: _BuiltInBasicType {
  
      static func _transform(from object: Any) -> [Key: Value]? {
          guard let dict = object as? [String: Any] else {
              InternalLogger.logDebug("Expect object to be an NSDictionary but it's not")
              return nil
          }
          var result = [Key: Value]()
          for (key, value) in dict {
              if let sKey = key as? Key {
                  if let nValue = (Value.self as? _Transformable.Type)?.transform(from: value) as? Value {
                      result[sKey] = nValue
                  } else if let nValue = value as? Value {
                      result[sKey] = nValue
                  }
              }
          }
          return result
      }
  
      func _plainValue() -> Any? {
          var result = [String: Any]()
          for (key, value) in self {
              if let key = key as? String {
                  if let transformable = value as? _Transformable {
                      if let transValue = transformable.plainValue() {
                          result[key] = transValue
                      }
                  }
              }
          }
          return result
      }
  }