Skip to content

Instantly share code, notes, and snippets.

@philipyoungg
Last active December 20, 2020 23:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save philipyoungg/9f1329f76bf6d6966b1f6f2b0fcf103d to your computer and use it in GitHub Desktop.
Save philipyoungg/9f1329f76bf6d6966b1f6f2b0fcf103d to your computer and use it in GitHub Desktop.
Parse JSON into safe struct
enum ObjectId {
case Session(SessionType)
case SessionStatus(SessionStatusType)
}
enum SessionType {
case SessionAdd(SessionAddPayload)
case SessionEdit(SessionEditPayload)
}
struct SessionAddPayload: Codable {
var id: String
}
struct SessionEditPayload: Codable {
var id: String
}
enum SessionStatusType {
case StartSession(StartSessionPayload)
}
struct StartSessionPayload: Codable {
var id: String
var name: String
var startDate: Date
}
struct Event: Codable {
var localEventId: String
var originEventId: String
var data: ObjectId
}
extension Event {
private enum CodingKeys: String, CodingKey {
case objectId, eventType, data, localEventId, originEventId
}
private enum ObjectEnum: String, Codable {
case SESSION, SESSION_STATUS
}
private enum EventType: String, Codable {
case ADD_SESSION, EDIT_SESSION
case START_SESSION
}
init(from decoder: Decoder) throws {
let c = try! decoder.container(keyedBy: CodingKeys.self)
let objectId = try! c.decode(ObjectEnum.self, forKey: .objectId)
let eventType = try! c.decode(EventType.self, forKey: .eventType)
self.localEventId = try! c.decode(String.self, forKey: .localEventId)
self.originEventId = try! c.decode(String.self, forKey: .originEventId)
switch objectId {
case .SESSION:
switch eventType {
case .ADD_SESSION:
let payload = try c.decode(SessionAddPayload.self, forKey: .data)
self.data = ObjectId.Session(.SessionAdd(payload))
case .EDIT_SESSION:
let payload = try c.decode(SessionEditPayload.self, forKey: .data)
self.data = ObjectId.Session(.SessionEdit(payload))
default:
throw preconditionFailure("OFF PUTTING!")
}
case .SESSION_STATUS:
switch eventType {
case .START_SESSION:
let payload = try c.decode(StartSessionPayload.self, forKey: .data)
self.data = ObjectId.SessionStatus(.StartSession(payload))
default:
throw preconditionFailure("OFF PUTTING!")
}
}
}
func encode(to encoder: Encoder) throws {
var c = encoder.container(keyedBy: CodingKeys.self)
try! c.encode(localEventId, forKey: .localEventId)
try! c.encode(originEventId, forKey: .originEventId)
switch data {
case .Session(let type):
switch type {
case .SessionAdd(let payload):
try! c.encode(EventType.ADD_SESSION, forKey: .eventType)
try! c.encode(payload, forKey: .data)
case .SessionEdit(let payload):
try! c.encode(EventType.EDIT_SESSION, forKey: .eventType)
try! c.encode(payload, forKey: .data)
}
case .SessionStatus(let type):
switch type {
case .StartSession(let payload):
try! c.encode(EventType.START_SESSION, forKey: .eventType)
try! c.encode(payload, forKey: .data)
}
}
}
}
// JSON Decoding Test
let decoder = JSONDecoder()
let json = Data("""
[
{"objectId": "SESSION", "eventType": "ADD_SESSION", "data": {"id": "20"}, "originEventId": "20", "localEventId": "20"},
{"objectId": "SESSION", "eventType": "EDIT_SESSION", "data": {"id": "20"}, "originEventId": "20", "localEventId": "20"},
{"objectId": "SESSION_STATUS", "eventType": "START_SESSION", "data": {"id": "200", "name": "Precondition", "startDate": 630198202}, "originEventId": "20", "localEventId": "20"}
]
""".utf8)
if let decoded = try? decoder.decode([Event].self, from: json) {
print(decoded)
}
// JSON Encoding Test
let encoder = JSONEncoder()
let events: [Event] = [
Event(localEventId: "200", originEventId: "200", data: .Session(.SessionAdd(SessionAddPayload(id: "20")))),
Event(localEventId: "200", originEventId: "200", data: .Session(.SessionEdit(SessionEditPayload(id: "20")))),
Event(localEventId: "200", originEventId: "200", data: .SessionStatus(.StartSession(.init(id: "300", name: "Henlo", startDate: Date()))))
]
if let encoded = try? encoder.encode(events) {
print(String(data: encoded, encoding: .utf8)!)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment