Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
swift-urlqueryitem-coder Sources URLQueryItemCoder Decoder Generic Implementation DecodingContainer+SingleValue.swift
13 kB · 340 lines
Swift
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341//// DecodingContainer+SingleValue.swift// URLQueryItemCoder//// Created by Kyle Hughes on 2/21/23.//
import Foundation
extension DecodingContainer { /// A decoding container that holds a single primitive value. /// /// **As Keyed Value Container…** /// /// Only used for leaf node keyed containers that have no children (e.g. all nil properties). We can't detect that /// they are actually keyed containers when building our decoding representation because we don't have type /// information. The internal decoder system will know to ask for an keyed container and we will return this. /// /// **As Unkeyed Value Container…** /// /// Only used for leaf node unkeyed containers that have no children. We can't detect that they are actually unkeyed /// containers when building our decoding representation because we don't have type information. The internal /// decoder system will know to ask for an unkeyed container and we will return this. internal final class SingleValue { internal let codingPath: [any CodingKey] internal let configuration: DecodingStrategies internal private(set) var value: PrimitiveValue? // MARK: Internal Initialization internal init(codingPath: [any CodingKey], configuration: DecodingStrategies) { self.codingPath = codingPath self.configuration = configuration value = nil } // MARK: Internal Instance Interface internal func store(_ value: PrimitiveValue?) { precondition( self.value == nil, "A value was already stored in the single value container." ) self.value = value } // MARK: Private Instance Interface
private func nextCodingPath(appending key: any CodingKey) -> [any CodingKey] { var nextCodingPath = codingPath nextCodingPath.append(key) return nextCodingPath } private func unwrapPrimitiveValue<Target>(for target: Target.Type) throws -> PrimitiveValue { guard let value else { throw DecodingError.valueNotFound(target, .foundNilInsteadOfPrimitiveValue(at: codingPath)) } return value } }}
// MARK: - SingleValueDecodingContainer Extension
extension DecodingContainer.SingleValue: SingleValueDecodingContainer { // MARK: Internal Instance Interface internal func decode(_ type: Bool.Type) throws -> Bool { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: String.Type) throws -> String { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: Double.Type) throws -> Double { let lowLevelDecoder = LowLevelDecoder(container: .singleValue(self)) return try configuration.nonConformingFloatStrategy.decode(insideOf: lowLevelDecoder) } internal func decode(_ type: Float.Type) throws -> Float { let lowLevelDecoder = LowLevelDecoder(container: .singleValue(self)) return try configuration.nonConformingFloatStrategy.decode(insideOf: lowLevelDecoder) } internal func decode(_ type: Int.Type) throws -> Int { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: Int8.Type) throws -> Int8 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: Int16.Type) throws -> Int16 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: Int32.Type) throws -> Int32 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: Int64.Type) throws -> Int64 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: UInt.Type) throws -> UInt { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: UInt8.Type) throws -> UInt8 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: UInt16.Type) throws -> UInt16 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: UInt32.Type) throws -> UInt32 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode(_ type: UInt64.Type) throws -> UInt64 { let primitiveValue = try unwrapPrimitiveValue(for: type) guard let decodedValue = primitiveValue.decode(type) else { throw DecodingError.typeMismatch(type, .primitiveValueMismatch(at: codingPath, for: type)) } return decodedValue } internal func decode<Target>(_ type: Target.Type) throws -> Target where Target: Decodable { let lowLevelDecoder = LowLevelDecoder(container: .singleValue(self)) return try lowLevelDecoder.decodeWithSpecialTreatment(as: type) } internal func decodeNil() -> Bool { value == nil }}
// MARK: - KeyedDecodingContainerProtocol Extension
extension DecodingContainer.SingleValue: KeyedDecodingContainerProtocol { // MARK: Internal Instance Interface internal var allKeys: [StringCodingKey] { [] } internal func contains(_ key: StringCodingKey) -> Bool { false } internal func decode(_ type: Bool.Type, forKey key: StringCodingKey) throws -> Bool { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: String.Type, forKey key: StringCodingKey) throws -> String { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Double.Type, forKey key: StringCodingKey) throws -> Double { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Float.Type, forKey key: StringCodingKey) throws -> Float { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Int.Type, forKey key: StringCodingKey) throws -> Int { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Int8.Type, forKey key: StringCodingKey) throws -> Int8 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Int16.Type, forKey key: StringCodingKey) throws -> Int16 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Int32.Type, forKey key: StringCodingKey) throws -> Int32 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: Int64.Type, forKey key: StringCodingKey) throws -> Int64 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: UInt.Type, forKey key: StringCodingKey) throws -> UInt { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: UInt8.Type, forKey key: StringCodingKey) throws -> UInt8 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: UInt16.Type, forKey key: StringCodingKey) throws -> UInt16 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: UInt32.Type, forKey key: StringCodingKey) throws -> UInt32 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode(_ type: UInt64.Type, forKey key: StringCodingKey) throws -> UInt64 { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decode<T>(_ type: T.Type, forKey key: StringCodingKey) throws -> T where T : Decodable { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func decodeNil(forKey key: StringCodingKey) throws -> Bool { true } internal func nestedContainer<NestedKey>( keyedBy type: NestedKey.Type, forKey key: StringCodingKey ) throws -> KeyedDecodingContainer<NestedKey> where NestedKey : CodingKey { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func nestedUnkeyedContainer(forKey key: StringCodingKey) throws -> UnkeyedDecodingContainer { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func superDecoder() throws -> Decoder { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func superDecoder(forKey key: StringCodingKey) throws -> Decoder { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) }}
// MARK: - UnkeyedDecodingContainer Extension
extension DecodingContainer.SingleValue: UnkeyedDecodingContainer { // MARK: Internal Instance Interface internal var count: Int? { value == nil ? 0 : 1 } internal var isAtEnd: Bool { true } internal var currentIndex: Int { 0 } internal func nestedContainer<NestedKey>( keyedBy type: NestedKey.Type ) throws -> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) } internal func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { throw DecodingError.dataCorrupted(.singleValueContainerCanOnlyActAsEmptyKeyedContainer(at: codingPath)) }}