Skip to content

Instantly share code, notes, and snippets.

@proxpero
Created July 17, 2017 19:08
Show Gist options
  • Save proxpero/bf52fe5f5ed1328f5827fe3aecb3093d to your computer and use it in GitHub Desktop.
Save proxpero/bf52fe5f5ed1328f5827fe3aecb3093d to your computer and use it in GitHub Desktop.
Encode and decode an enum with associated types.
// Accompanying blog post: http://127.0.0.1:4000/2017/07/11/encoding-and-decoding-custom-enums-with-associated-values-in-swift-4
// Also: https://gist.github.com/proxpero/189a723fb96bb88fac5bf9e11d6cf9e2
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
extension Barcode: Codable {
private enum CodingKeys: String, CodingKey {
case upc
case qrCode
}
enum CodingError: Error {
case decoding(String)
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
if let codes = try? values.decode(Array<Int>.self, forKey: .upc), codes.count == 4 {
self = .upc(codes[0], codes[1], codes[2], codes[3])
return
}
if let code = try? values.decode(String.self, forKey: .qrCode) {
self = .qrCode(code)
return
}
throw CodingError.decoding("Decoding Error: \(dump(values))")
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .upc(let numberSystem, let manufacturer, let product, let check):
try container.encode([numberSystem, manufacturer, product, check], forKey: .upc)
case .qrCode(let productCode):
try container.encode(productCode, forKey: .qrCode)
}
}
}
import Foundation
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let decoder = JSONDecoder()
var productBarcode: Barcode
var data: Data
var json: String
var expectation: String
var result: Barcode
productBarcode = .upc(8, 85909, 51226, 3)
data = try encoder.encode(productBarcode)
json = String.init(data: data, encoding: .utf8)!
expectation = """
{
"upc" : [
8,
85909,
51226,
3
]
}
"""
print(json)
result = try decoder.decode(Barcode.self, from: data)
//assert(result == productBarcode)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
data = try encoder.encode(productBarcode)
json = String.init(data: data, encoding: .utf8)!
expectation = """
{
"qrCode" : "ABCDEFGHIJKLMNOP"
}
"""
result = try decoder.decode(Barcode.self, from: data)
assert(json == expectation)
////assert(result == productBarcode)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment