Last active
November 24, 2021 19:31
-
-
Save mortenbekditlevsen/7918fb98638f8a9e2b017f0fad12da0b to your computer and use it in GitHub Desktop.
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
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