Avatar
@dynamicMemberLookup enum JSON: ExpressibleByDictionaryLiteral, ExpressibleByArrayLiteral, ExpressibleByStringLiteral, ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral, ExpressibleByBooleanLiteral, ExpressibleByNilLiteral, CustomStringConvertible { case object([String: JSON]) case array([JSON]) case string(String) case number(Double) case boolean(Bool) case null init(dictionaryLiteral elements: (String, JSON)...) { self = .object([String: JSON](elements) { a, b in a }) } init(arrayLiteral elements: JSON...) { self = .array(elements) } init(stringLiteral value: String) { self = .string(value) } init(integerLiteral value: Int) { self = .number(Double(value)) } init(floatLiteral value: Double) { self = .number(value) } init(booleanLiteral value: Bool) { self = .boolean(value) } init(nilLiteral: ()) { self = .null } subscript(index: Int) -> JSON { guard case .array(let elements) = self else { preconditionFailure() } return elements[index] } subscript<Key: StringProtocol>(key: Key) -> JSON { guard case .object(let members) = self else { preconditionFailure() } return members[String(key)] ?? .null } subscript(dynamicMember key: String) -> JSON { self[key] } var description: String { switch self { case .object(let members): return members.description case .array(let elements): return elements.description case .string(let value): return value case .number(let value): return value.description case .boolean(let value): return value.description case .null: return "null" } } } // [2, 3.0, "ABC", null] // { "x": 2, "y": { "z": true }} } let a: JSON = [2, 3.0, "ABC", nil] let b: JSON = ["x": 2, "y": ["z": true]] print(a[0]) print(a) print(b["y"]["z"]) print(b.y.z)
👍🏻 8
swift 2