Created
July 17, 2017 19:08
-
-
Save proxpero/bf52fe5f5ed1328f5827fe3aecb3093d to your computer and use it in GitHub Desktop.
Encode and decode an enum with associated types.
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
// 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