struct RecordUser: Codable {
let name: JSONValue?
let age: Int
}
struct Record: Codable {
let id: String
let user: RecordUser
let price: Double?
let active: Bool
let meta: JSONValue?
let userName: JSONValue?
let class_: JSONValue?
let status: String
let source: String
enum CodingKeys: String, CodingKey {
case userName = "user-name"
case class_ = "class"
}
}
enum JSONValue: Codable {
case string(String)
case number(Double)
case bool(Bool)
case object([String: JSONValue])
case array([JSONValue])
case null
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() {
self = .null
} else if let value = try? container.decode(Bool.self) {
self = .bool(value)
} else if let value = try? container.decode(Double.self) {
self = .number(value)
} else if let value = try? container.decode(String.self) {
self = .string(value)
} else if let value = try? container.decode([String: JSONValue].self) {
self = .object(value)
} else if let value = try? container.decode([JSONValue].self) {
self = .array(value)
} else {
throw DecodingError.typeMismatch(JSONValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Unsupported JSON value"))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let value):
try container.encode(value)
case .number(let value):
try container.encode(value)
case .bool(let value):
try container.encode(value)
case .object(let value):
try container.encode(value)
case .array(let value):
try container.encode(value)
case .null:
try container.encodeNil()
}
}
}