personally, I would love to see that. Since its useful regardless, maybe a separate pitch to add a TopLevelDecoder/TopLevelEncoder to the Stdlib is in place, then if we decide TopLevelDecoder is the right place for such API, we can relate the second pitch to the TopLevelEncoder/TopLevelDecoder one.
Is this possible to implement in a generic context like TopLevelDecoder
? I imagined that JSONDecoder
would be able to do a far more efficient implementation by descending into the JSON data manually first.
If we decided here to add it to JSONDecoder
, I will help make that happen for Foundation.
One thought here: if this does get expressed in a generic way at a top-level context, I think it would be nice to spell the method as
static func decode<T: Decodable>(_ type: T.Type, from data: Data, at codingKeyPath: [CodingKey])
to allow key paths to include keys which have a delimiter in them (e.g. "my.key"
, which would otherwise be parsed as ["my", "key"]
), as well as integer keys.
It's then possible to also offer
static func decode<T: Decodable>(_ type: T.Type, from data: Data, at codingKeyPath: String, separator: String = ".")
with a default implementation which splits codingKeyPath
on the delimiter, turns each component into a CodingKey
, then calls the [CodingKey]
variant. JSONDecoder
(and others) could also override this implementation to do something even more efficient if relevant.
(The [CodingKey]
version can also made significantly easier to call using a general key type, e.g. AnyCodingKey
pitched in [Pitch] Allow coding of non-`String`/`Int` keyed `Dictionary` into a `KeyedContainer`)