Created
October 15, 2018 20:44
-
-
Save NikolaiRuhe/f9d37ed8e23012f46be48290f8a95319 to your computer and use it in GitHub Desktop.
JSON DOM Swift implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/// A JSONValue is a generic DOM representation of decoded JSON. | |
enum JSONValue { | |
case null | |
case boolean(Bool) | |
case number(Double) | |
case string(String) | |
case array(JSONArray) | |
case object(JSONObject) | |
typealias JSONArray = Array<JSONValue> | |
typealias JSONObject = Dictionary<String, JSONValue> | |
} | |
extension JSONValue : Codable { | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
if (try? decoder.unkeyedContainer()) != nil { | |
self = .array(try container.decode(JSONArray.self)) | |
return | |
} | |
enum AnyKey: CodingKey {} | |
if (try? decoder.container(keyedBy: AnyKey.self)) != nil { | |
self = .object(try container.decode(JSONObject.self)) | |
return | |
} | |
guard !container.decodeNil() else { | |
self = .null | |
return | |
} | |
do { | |
self = .boolean(try container.decode(Bool.self)) | |
return | |
} catch {} | |
do { | |
self = .number(try container.decode(Double.self)) | |
return | |
} catch {} | |
self = .string(try container.decode(String.self)) | |
} | |
func encode(to encoder: Encoder) throws { | |
var encoder = encoder.singleValueContainer() | |
switch self { | |
case .null: try encoder.encodeNil() | |
case .boolean(let value): try encoder.encode(value) | |
case .number (let value): try encoder.encode(value) | |
case .string (let value): try encoder.encode(value) | |
case .array (let value): try encoder.encode(value) | |
case .object (let value): try encoder.encode(value) | |
} | |
} | |
} | |
extension JSONValue : CustomStringConvertible { | |
var description: String { | |
let data = try! JSONEncoder().encode([self]) | |
let string = String(data: data, encoding: .utf8)! | |
return String(string.dropFirst().dropLast()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment