import Foundation extension _CBORDecoder { final class KeyedContainer { lazy var nestedContainers: [AnyCodingKey: CBORDecodingContainer] = { guard let count = self.count else { return [:] } var nestedContainers: [AnyCodingKey: CBORDecodingContainer] = [:] let unkeyedContainer = UnkeyedContainer(data: self.data.suffix(from: self.index), codingPath: self.codingPath, userInfo: self.userInfo) unkeyedContainer.count = count * 2 var iterator = unkeyedContainer.nestedContainers.makeIterator() for _ in 0.. Bool { return self.nestedContainers.keys.contains(AnyCodingKey(key)) } func decodeNil(forKey key: Key) throws -> Bool { try checkCanDecodeValue(forKey: key) guard let singleValueContainer = self.nestedContainers[AnyCodingKey(key)] as? _CBORDecoder.SingleValueContainer else { let context = DecodingError.Context(codingPath: self.codingPath, debugDescription: "cannot decode nil for key: \(key)") throw DecodingError.typeMismatch(Any?.self, context) } return singleValueContainer.decodeNil() } func decode(_ type: T.Type, forKey key: Key) throws -> T { try checkCanDecodeValue(forKey: key) let container = self.nestedContainers[AnyCodingKey(key)]! let decoder = CodableCBORDecoder() let value = try decoder.decode(T.self, from: container.data) return value } func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { try checkCanDecodeValue(forKey: key) guard let unkeyedContainer = self.nestedContainers[AnyCodingKey(key)] as? _CBORDecoder.UnkeyedContainer else { throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "cannot decode nested container for key: \(key)") } return unkeyedContainer } func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { try checkCanDecodeValue(forKey: key) guard let keyedContainer = self.nestedContainers[AnyCodingKey(key)] as? _CBORDecoder.KeyedContainer else { throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "cannot decode nested container for key: \(key)") } return KeyedDecodingContainer(keyedContainer) } func superDecoder() throws -> Decoder { return _CBORDecoder(data: self.data) } func superDecoder(forKey key: Key) throws -> Decoder { let decoder = _CBORDecoder(data: self.data) decoder.codingPath = [key] return decoder } } extension _CBORDecoder.KeyedContainer: CBORDecodingContainer {}