guschnwg / mega-repo

https://mega-repo.vercel.app
0 stars 0 forks source link

Fix this monstrosity #2

Closed guschnwg closed 2 months ago

guschnwg commented 5 months ago

https://github.com/guschnwg/mega-repo/blob/bbcc722d3b3834255dd2eeeaadaf271f6989a33d/Freeolingo/Freeolingo/Store.swift#L132

guschnwg commented 5 months ago
let objectOne = """
{
    "id": 1,
    "type": "object",
    "something": "else"
}
"""

let objectTwo = """
{
    "id": 2,
    "type": "person",
    "age": 1
}
"""

import Foundation

struct Object: Decodable {
    let something: String
}

struct Person: Decodable {
    let age: Int
}

enum ChallengeTypes {
    case person(Person)
    case object(Object)
}

struct Challenge: Decodable {
    let id: Int
    let type: String

    let data: ChallengeTypes?

    enum CodingKeys: String, CodingKey {
        case id
        case type
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(Int.self, forKey: .id)
        type = try container.decode(String.self, forKey: .type)

        switch type {
        case "object":
            data = .object(try decoder.singleValueContainer().decode(Object.self))
        case "person":
            data = .person(try decoder.singleValueContainer().decode(Person.self))
        default:
            data = nil
        }
    }
}

// Your JSON objects
let objectOneJSONData = objectOne.data(using: .utf8)!
let objectTwoJSONData = objectTwo.data(using: .utf8)!

// Decode JSON into Entity
do {
    let one = try JSONDecoder().decode(Challenge.self, from: objectOneJSONData)
    print("Challenge decoded: \(one)")

    let two = try JSONDecoder().decode(Challenge.self, from: objectTwoJSONData)
    print("Challenge decoded: \(two)")
} catch {
    print("Error decoding JSON: \(error)")
}

?

Challenge decoded: Challenge(id: 1, type: "object", data: Optional(main.ChallengeTypes.object(main.Object(something: "else"))))
Challenge decoded: Challenge(id: 2, type: "person", data: Optional(main.ChallengeTypes.person(main.Person(age: 1))))