Last active
December 20, 2020 23:10
-
-
Save philipyoungg/9f1329f76bf6d6966b1f6f2b0fcf103d to your computer and use it in GitHub Desktop.
Parse JSON into safe struct
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
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