this repo has no description
at main 78 lines 2.8 kB view raw
1// 2// NonConformingFloatDecodingStrategy.swift 3// URLQueryItemCoder 4// 5// Created by Kyle Hughes on 4/10/23. 6// 7 8/// The strategy to use for non-conforming floating-point values (IEEE 754 infinity and NaN). 9public enum NonConformingFloatDecodingStrategy { 10 /// Decode the values from the given representation strings. 11 case convertToString(positiveInfinity: String, negativeInfinity: String, nan: String) 12 13 /// Throw upon encountering non-conforming values. 14 /// 15 /// This is the default strategy. 16 case `throw` 17 18 // MARK: Public Static Interface 19 20 /// The default decoding strategy. 21 /// 22 /// Equals `.throw`. 23 public static let `default`: Self = .throw 24 25 // MARK: Internal Instance Interface 26 27 internal func decode<Number, PrimitiveValue>( 28 insideOf lowLevelDecoder: LowLevelDecoder<PrimitiveValue> 29 ) throws -> Number where Number: LosslessStringConvertible & FloatingPoint { 30 let singleValueContainer = try lowLevelDecoder.container.expectedSingleValueContainer( 31 at: lowLevelDecoder.codingPath 32 ) 33 let stringValue = try singleValueContainer.decode(String.self) 34 35 switch self { 36 case let .convertToString(positiveInfinity, negativeInfinity, nan): 37 switch stringValue { 38 case nan: 39 return .nan 40 case negativeInfinity: 41 return -.infinity 42 case positiveInfinity: 43 return .infinity 44 default: 45 guard let doubleValue = Number(stringValue) else { 46 throw DecodingError.dataCorrupted( 47 DecodingError.Context( 48 codingPath: singleValueContainer.codingPath, 49 debugDescription: "\(Number.self) unable to be decoded from string." 50 ) 51 ) 52 } 53 54 return doubleValue 55 } 56 case .throw: 57 guard let doubleValue = Number(stringValue) else { 58 throw DecodingError.dataCorrupted( 59 DecodingError.Context( 60 codingPath: singleValueContainer.codingPath, 61 debugDescription: "\(Number.self) unable to be decoded from string." 62 ) 63 ) 64 } 65 66 guard doubleValue.isFinite else { 67 throw DecodingError.dataCorrupted( 68 DecodingError.Context( 69 codingPath: singleValueContainer.codingPath, 70 debugDescription: "Parsed floating point number does not fit in \(Number.self)." 71 ) 72 ) 73 } 74 75 return doubleValue 76 } 77 } 78}