Skip to content

Instantly share code, notes, and snippets.

@jarrodldavis
Created September 26, 2019 04:38
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarrodldavis/8c9e7e6e487991279c2df2d452baaf16 to your computer and use it in GitHub Desktop.
Save jarrodldavis/8c9e7e6e487991279c2df2d452baaf16 to your computer and use it in GitHub Desktop.
A Swift property wrapper for encoding and decoding `RawRepresentable` enums as their raw values in `Dictionary` instances as keys
@propertyWrapper
struct RawKeyedCodableDictionary<Key, Value>: Codable where Key: Hashable & RawRepresentable, Key.RawValue: Codable & Hashable, Value: Codable {
var wrappedValue: [Key: Value]
init() {
wrappedValue = [:]
}
init(wrappedValue: [Key: Value]) {
self.wrappedValue = wrappedValue
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawKeyedDictionary = try container.decode([Key.RawValue: Value].self)
wrappedValue = [:]
for (rawKey, value) in rawKeyedDictionary {
guard let key = Key(rawValue: rawKey) else {
throw DecodingError.dataCorruptedError(
in: container, debugDescription: "Invalid key: cannot initalize \(Key.self) from invalid \(Key.RawValue.self) value \(rawKey)")
}
wrappedValue[key] = value
}
}
func encode(to encoder: Encoder) throws {
let rawKeyedDictionary = Dictionary(uniqueKeysWithValues: wrappedValue.map { ($0.rawValue, $1) })
var container = encoder.singleValueContainer()
try container.encode(rawKeyedDictionary)
}
}
@snoozemoose
Copy link

This looks really great, will try it during the course of the day! Thanks also for opening my eyes to @propertyWrapper and a bunch of other new @'s in Swift 5.1 that I found when reading up on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment