Decodable issue when using Tagged type as key in Dictionary
marcusficner opened this issue · 1 comments
Hey @stephencelis and @mbrandonw!
I'm using Tagged in my latest project and it works great but I found the following issue and I'm not sure where the error is.
I'm trying to decode JSON into a Dictionary where the key is a tagged type like this:
let json = """
{
"data": {
"key": "value"
}
}
""".data(using: .utf8)!
struct SomeStruct: Decodable {
typealias Key = Tagged<SomeStruct, String>
let data: [Key: String]
}
Strangely I receive this error message on decoding:
typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))
When I change the type of the dictionary to [String : String]
it works as expected.
Any ideas?
Thank you in advance and keep up the great work with Pointfree.co!
As Ole Begemann pointed out here: https://oleb.net/blog/2017/12/dictionary-codable-array/
this seems to be a bug in the Codable implementation. His findings are true for Decodable as well: https://github.com/apple/swift/blob/swift-4.1-branch/stdlib/public/core/Codable.swift.gyb#L2035-L2104
EDIT: Link posts to Swift 4.1. but it's true Swift 4.2 and Swift 5.0 also
Indeed, when I change to example above to:
struct SomeStruct: Decodable {
typealias Key = Tagged<SomeStruct, String>
let data: [Key.RawValue: String]
}
decoding works fine. But so I could've used String directly :(
As a workaround I'll decode into [String : String]
and then reduce(into: [:], { result, x in result[Key(rawValue: x.key)] = x.value })