Guest User

Untitled

a guest
Jul 17th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.72 KB | None | 0 0
  1. class JSONAny: Codable {
  2. public let value: Any
  3.  
  4. public init<T>(_ value: T?) {
  5. self.value = value ?? ()
  6. }
  7.  
  8. static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
  9. let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
  10. return DecodingError.typeMismatch(JSONAny.self, context)
  11. }
  12.  
  13. static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError {
  14. let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
  15. return EncodingError.invalidValue(value, context)
  16. }
  17.  
  18. static func decode(from container: SingleValueDecodingContainer) throws -> Any {
  19. if let value = try? container.decode(Bool.self) {
  20. return value
  21. }
  22. if let value = try? container.decode(Int64.self) {
  23. return value
  24. }
  25. if let value = try? container.decode(Double.self) {
  26. return value
  27. }
  28. if let value = try? container.decode(String.self) {
  29. return value
  30. }
  31. if container.decodeNil() {
  32. return JSONNull()
  33. }
  34. throw decodingError(forCodingPath: container.codingPath)
  35. }
  36.  
  37. static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any {
  38. if let value = try? container.decode(Bool.self) {
  39. return value
  40. }
  41. if let value = try? container.decode(Int64.self) {
  42. return value
  43. }
  44. if let value = try? container.decode(Double.self) {
  45. return value
  46. }
  47. if let value = try? container.decode(String.self) {
  48. return value
  49. }
  50. if let value = try? container.decodeNil() {
  51. if value {
  52. return JSONNull()
  53. }
  54. }
  55. if var container = try? container.nestedUnkeyedContainer() {
  56. return try decodeArray(from: &container)
  57. }
  58. if var container = try? container.nestedContainer(keyedBy: MyCodingKey.self) {
  59. return try decodeDictionary(from: &container)
  60. }
  61. throw decodingError(forCodingPath: container.codingPath)
  62. }
  63.  
  64. static func decode(from container: inout KeyedDecodingContainer<MyCodingKey>, forKey key: MyCodingKey) throws -> Any {
  65. if let value = try? container.decode(Bool.self, forKey: key) {
  66. return value
  67. }
  68. if let value = try? container.decode(Int64.self, forKey: key) {
  69. return value
  70. }
  71. if let value = try? container.decode(Double.self, forKey: key) {
  72. return value
  73. }
  74. if let value = try? container.decode(String.self, forKey: key) {
  75. return value
  76. }
  77. if let value = try? container.decodeNil(forKey: key) {
  78. if value {
  79. return JSONNull()
  80. }
  81. }
  82. if var container = try? container.nestedUnkeyedContainer(forKey: key) {
  83. return try decodeArray(from: &container)
  84. }
  85. if var container = try? container.nestedContainer(keyedBy: MyCodingKey.self, forKey: key) {
  86. return try decodeDictionary(from: &container)
  87. }
  88. throw decodingError(forCodingPath: container.codingPath)
  89. }
  90.  
  91. static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
  92. var arr: [Any] = []
  93. while !container.isAtEnd {
  94. let value = try decode(from: &container)
  95. arr.append(value)
  96. }
  97. return arr
  98. }
  99.  
  100. static func decodeDictionary(from container: inout KeyedDecodingContainer<MyCodingKey>) throws -> [String: Any] {
  101. var dict = [String: Any]()
  102. for key in container.allKeys {
  103. let value = try decode(from: &container, forKey: key)
  104. dict[key.stringValue] = value
  105. }
  106. return dict
  107. }
  108.  
  109. static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
  110. for value in array {
  111. if let value = value as? Bool {
  112. try container.encode(value)
  113. } else if let value = value as? Int64 {
  114. try container.encode(value)
  115. } else if let value = value as? Double {
  116. try container.encode(value)
  117. } else if let value = value as? String {
  118. try container.encode(value)
  119. } else if value is JSONNull {
  120. try container.encodeNil()
  121. } else if let value = value as? [Any] {
  122. var container = container.nestedUnkeyedContainer()
  123. try encode(to: &container, array: value)
  124. } else if let value = value as? [String: Any] {
  125. var container = container.nestedContainer(keyedBy: MyCodingKey.self)
  126. try encode(to: &container, dictionary: value)
  127. } else {
  128. throw encodingError(forValue: value, codingPath: container.codingPath)
  129. }
  130. }
  131. }
  132.  
  133. static func encode(to container: inout KeyedEncodingContainer<MyCodingKey>, dictionary: [String: Any]) throws {
  134. for (key, value) in dictionary {
  135. let key = MyCodingKey(stringValue: key)!
  136. if let value = value as? Bool {
  137. try container.encode(value, forKey: key)
  138. } else if let value = value as? Int64 {
  139. try container.encode(value, forKey: key)
  140. } else if let value = value as? Double {
  141. try container.encode(value, forKey: key)
  142. } else if let value = value as? String {
  143. try container.encode(value, forKey: key)
  144. } else if value is JSONNull {
  145. try container.encodeNil(forKey: key)
  146. } else if let value = value as? [Any] {
  147. var container = container.nestedUnkeyedContainer(forKey: key)
  148. try encode(to: &container, array: value)
  149. } else if let value = value as? [String: Any] {
  150. var container = container.nestedContainer(keyedBy: MyCodingKey.self, forKey: key)
  151. try encode(to: &container, dictionary: value)
  152. } else {
  153. throw encodingError(forValue: value, codingPath: container.codingPath)
  154. }
  155. }
  156. }
  157.  
  158. static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
  159. if let value = value as? Bool {
  160. try container.encode(value)
  161. } else if let value = value as? Int64 {
  162. try container.encode(value)
  163. } else if let value = value as? Double {
  164. try container.encode(value)
  165. } else if let value = value as? String {
  166. try container.encode(value)
  167. } else if value is JSONNull {
  168. try container.encodeNil()
  169. } else {
  170. throw encodingError(forValue: value, codingPath: container.codingPath)
  171. }
  172. }
  173.  
  174. public required init(from decoder: Decoder) throws {
  175. if var arrayContainer = try? decoder.unkeyedContainer() {
  176. self.value = try JSONAny.decodeArray(from: &arrayContainer)
  177. } else if var container = try? decoder.container(keyedBy: MyCodingKey.self) {
  178. self.value = try JSONAny.decodeDictionary(from: &container)
  179. } else {
  180. let container = try decoder.singleValueContainer()
  181. self.value = try JSONAny.decode(from: container)
  182. }
  183. }
  184.  
  185. public func encode(to encoder: Encoder) throws {
  186. if let arr = self.value as? [Any] {
  187. var container = encoder.unkeyedContainer()
  188. try JSONAny.encode(to: &container, array: arr)
  189. } else if let dict = self.value as? [String: Any] {
  190. var container = encoder.container(keyedBy: MyCodingKey.self)
  191. try JSONAny.encode(to: &container, dictionary: dict)
  192. } else {
  193. var container = encoder.singleValueContainer()
  194. try JSONAny.encode(to: &container, value: self.value)
  195. }
  196. }
  197. }
  198.  
  199. class JSONNull: Codable {
  200. public init() {
  201. }
  202.  
  203. public required init(from decoder: Decoder) throws {
  204. let container = try decoder.singleValueContainer()
  205. if !container.decodeNil() {
  206. throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
  207. }
  208. }
  209.  
  210. public func encode(to encoder: Encoder) throws {
  211. var container = encoder.singleValueContainer()
  212. try container.encodeNil()
  213. }
  214. }
  215.  
  216. class MyCodingKey : CodingKey {
  217. let key: String
  218.  
  219. required init?(intValue: Int) {
  220. return nil
  221. }
  222.  
  223. required init?(stringValue: String) {
  224. key = stringValue
  225. }
  226.  
  227. var intValue: Int? {
  228. return nil
  229. }
  230.  
  231. var stringValue: String {
  232. return key
  233. }
  234. }
Add Comment
Please, Sign In to add comment