Currently you can only use String
s and Int
s as keys for a Dictionary
if you wish to be able to encode and decode the dictionary from / to a keyed container.
Any other codable key types will encode and decode the dictionary into an unkeyed container.
This eliminates a few use cases for serializing Dictionaries
into JSON dictionaries when the keys are RawRepresentable
as either String
or Int
.
For instance you could wish to use a String backed enum as keys in your Dictionary:
enum MyKey: String, Codable {
case one
case two
}
let dict: [MyKey: String] = [.one: "first", .two: "second"]
Encoding the above to JSON using the JSONEncoder
makes this into an array of the four values ["one", "first", "two", "second"] instead of a dictionary/object/map.
Another use case is using something like 'tagged' (GitHub - pointfreeco/swift-tagged: đˇ A wrapper type for safer, expressive code.) in order to add type safety to String
based identifiers (and more) in your code base.
Using Tagged
you can get a wrapper around a String
that is Codable
and RawRepresentable
and has the advantage that it is type safe. For instance you can model the following:
struct User {
typealias Identifier = Tagged<User, String>
var id: Identifier
var name: String
}
let userMap: [User.Identifier: User]
But now userMap
will be serialized as an array instead of a dictionary.
I have looked at stdlib/public/core/Codable.swift.gyb
to try and see if I could extend the Dictionary
conformance to Encodable
and Decodable
to be able to use RawRepresentable
keys where the RawValue
is either String
or Int
.
Unfortunatly I have failed to implement this since RawRepresenable
can only be used as a generic constraint and you cannot add multiple conformances to Encodable
(there cannot be more than one conformance, even with different conditional bounds).
Does anyone have any idea how to implement a change to the stdlib in order to enable the use of RawRepresentable
keys?
And do anyone have any thoughts about whether this change would be ok. If someone already expects array serialization, then the dictionary behavior will be unexpected.