Skip to content

Instantly share code, notes, and snippets.

@mortenbekditlevsen
Last active November 24, 2021 19:31
Show Gist options
  • Save mortenbekditlevsen/7918fb98638f8a9e2b017f0fad12da0b to your computer and use it in GitHub Desktop.
Save mortenbekditlevsen/7918fb98638f8a9e2b017f0fad12da0b to your computer and use it in GitHub Desktop.
import Foundation
enum DecodeError: Error {
case err
}
struct Foo: Codable {
var a: String
}
struct Bar: Codable {
var a: String
}
struct DontTouchMyKeys: Codable {
enum Union: Codable {
case imageURL(Foo)
case fOoBAr(Bar)
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case let .fOoBAr(bar):
try container.encode(bar)
case let .imageURL(foo):
try container.encode(foo)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
switch decoder.codingPath.last?.stringValue {
case CodingKeys.imageURL.stringValue:
self = .imageURL(try container.decode(Foo.self))
case CodingKeys.fOoBAr.stringValue:
self = .fOoBAr(try container.decode(Bar.self))
default:
throw DecodeError.err
}
}
}
enum CodingKeys: String, CodingKey {
case imageURL
case fOoBAr
}
var imageURL: Foo
var fOoBAr: Bar
init(imageURL: Foo, fOoBAr: Bar) {
self.imageURL = imageURL
self.fOoBAr = fOoBAr
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
var dict: [String: Union] = [:]
dict[CodingKeys.imageURL.stringValue] = .imageURL(imageURL)
dict[CodingKeys.fOoBAr.stringValue] = .fOoBAr(fOoBAr)
try container.encode(dict)
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let dict = try container.decode([String: Union].self)
guard case let .imageURL(imageURL) = dict[CodingKeys.imageURL.rawValue] else {
throw DecodeError.err
}
self.imageURL = imageURL
guard case let .fOoBAr(fOoBAr) = dict[CodingKeys.fOoBAr.rawValue] else {
throw DecodeError.err
}
self.fOoBAr = fOoBAr
}
}
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let data = try encoder.encode(DontTouchMyKeys(imageURL: Foo(a: "foo"), fOoBAr: Bar(a: "bar")))
print(String(data: data, encoding: .utf8)!)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decoded = try decoder.decode(DontTouchMyKeys.self, from: data)
print(decoded)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment