I have an error due to my usage of protocols and generic that I don't understand. Any help appreciated.
Context:
I'm writing code to decode a JSON doc whose format can differ based on a version field.
Example
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": ...,
or
"$schema": "http://json-schema.org/2020_12/schema#",
"$defs": ...,
I wrote a protocol and two struct to support the two dialects.
protocol JSONSchemaDialect {
func codingKeys() -> CodingKey.Type
}
struct JSONSchemaDialect_2020_12: JSONSchemaDialect {
// standard coding keys
enum CodingKeys: String, CodingKey {
case description = "$defs"
}
func codingKeys() -> CodingKey.Type {
return CodingKeys.self
}
}
typealias JSONSchemaDialect_2019_09 = JSONSchemaDialect_2020_12
struct JSONSchemaDialect_Draft4: JSONSchemaDialect {
// Draft4 coding keys
enum CodingKeys: String, CodingKey {
case description = "definitions"
}
func codingKeys() -> CodingKey.Type {
return CodingKeys.self
}
}
and then I have a generic function to decode either schema.
private func decodeDescription<T: JSONSchemaDialect>(from decoder: any Decoder, for dialect: T) throws -> [String: JSONUnionType] {
// Cannot convert value of type 'any CodingKey.Type' to expected argument type 'Key.Type'
// Generic parameter 'Key' could not be inferred
let container = try decoder.container(keyedBy: dialect.codingKeys())
return try container.decodeIfPresent([String: JSONUnionType].self, forKey: .definitions)
}
How can I implement this in a generic way ?