Advertisement
Guest User

Untitled

a guest
Jun 26th, 2017
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.15 KB | None | 0 0
  1. import XCTest
  2.  
  3. // Requires a recent Swift 4 snapshot toolchain (Xcode 9 beta 2 not new enough)
  4.  
  5. public indirect enum JSONValue: Decodable {
  6. case double(Double)
  7. case string(String)
  8. case bool(Bool)
  9. case dictionary([String: JSONValue])
  10. case array([JSONValue])
  11. case `nil`
  12.  
  13. public init(from decoder: Decoder) throws {
  14. let singleValueContainer = try decoder.singleValueContainer()
  15. if let value = try? singleValueContainer.decode(Bool.self) {
  16. self = .bool(value)
  17. return
  18. } else if let value = try? singleValueContainer.decode(String.self) {
  19. self = .string(value)
  20. return
  21. } else if let value = try? singleValueContainer.decode(Double.self) {
  22. self = .double(value)
  23. return
  24. } else if let value = try? singleValueContainer.decode([String: JSONValue].self) {
  25. self = .dictionary(value)
  26. return
  27. } else if let value = try? singleValueContainer.decode([JSONValue].self) {
  28. self = .array(value)
  29. return
  30. } else if singleValueContainer.decodeNil() {
  31. self = .nil
  32. return
  33. }
  34. throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not find reasonable type to map to JSONValue"))
  35. }
  36. }
  37.  
  38. // MARK: - Convenience
  39.  
  40. extension JSONValue {
  41. public var string: String? {
  42. switch self {
  43. case .string(let value):
  44. return value
  45. default:
  46. return nil
  47. }
  48. }
  49. public var double: Double? {
  50. switch self {
  51. case .double(let value):
  52. return value
  53. default:
  54. return nil
  55. }
  56. }
  57. public var bool: Bool? {
  58. switch self {
  59. case .bool(let value):
  60. return value
  61. default:
  62. return nil
  63. }
  64. }
  65. public var dictionary: [String: JSONValue]? {
  66. switch self {
  67. case .dictionary(let value):
  68. return value
  69. default:
  70. return nil
  71. }
  72. }
  73. public var array: [JSONValue]? {
  74. switch self {
  75. case .array(let value):
  76. return value
  77. default:
  78. return nil
  79. }
  80. }
  81. public var isNil: Bool {
  82. switch self {
  83. case .nil:
  84. return true
  85. default:
  86. return false
  87. }
  88. }
  89. }
  90.  
  91. class JSONValueTests: XCTestCase {
  92.  
  93. func testDecoding() {
  94. let decoder = JSONDecoder()
  95. let a = try! decoder.decode(JSONValue.self, from: """
  96. {
  97. "storage": {
  98. "subthing": "stringValue",
  99. "a": 2,
  100. "bool": true,
  101. "nilValue": null,
  102. },
  103. "nilValue": null
  104. }
  105. """.data(using: .utf8)!)
  106. XCTAssertEqual(a.dictionary?["storage"]?.dictionary?["subthing"]?.string, "stringValue")
  107. XCTAssertEqual(a.dictionary?["storage"]?.dictionary?["a"]?.double, 2.0)
  108. XCTAssertEqual(a.dictionary?["storage"]?.dictionary?["bool"]?.bool, true)
  109. XCTAssertEqual(a.dictionary?["storage"]?.dictionary?["nilValue"]?.isNil, true)
  110. }
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement