Skip to content

Instantly share code, notes, and snippets.

@koher
Created October 23, 2021 00:32
Show Gist options
  • Save koher/b6edb3d9bf806e77d03a8de0464c4470 to your computer and use it in GitHub Desktop.
Save koher/b6edb3d9bf806e77d03a8de0464c4470 to your computer and use it in GitHub Desktop.
Codable JSON type in Swift
enum JSON {
case number(Double)
case boolean(Bool)
case string(String)
case array([JSON])
case object([String: JSON])
case null
}
extension JSON: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let value = try? container.decode(Double.self) {
self = .number(value)
} else if let value = try? container.decode(Bool.self) {
self = .boolean(value)
} else if let value = try? container.decode(String.self) {
self = .string(value)
} else if let value = try? container.decode([JSON].self) {
self = .array(value)
} else if let value = try? container.decode([String: JSON].self) {
self = .object(value)
} else if container.decodeNil() {
self = .null
} else {
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Failed to interpret as a JSON value.", underlyingError: nil))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .number(let value):
try container.encode(value)
case .boolean(let value):
try container.encode(value)
case .string(let value):
try container.encode(value)
case .array(let value):
try container.encode(value)
case .object(let value):
try container.encode(value)
case .null:
try container.encodeNil()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment