|
6 | 6 | // |
7 | 7 |
|
8 | 8 | import Foundation |
9 | | -#if canImport(Half) |
10 | | -import Half |
11 | | -#endif |
12 | 9 |
|
13 | 10 | #if canImport(Combine) |
14 | 11 | import Combine |
@@ -288,34 +285,34 @@ internal class __CBORDecoder: Decoder, SingleValueDecodingContainer { |
288 | 285 | } |
289 | 286 |
|
290 | 287 | fileprivate func decode<T: Decodable>(_ value: Any, as type: T.Type) throws -> T { |
291 | | - let result: T |
292 | | - |
293 | 288 | // swiftlint:disable force_cast |
294 | 289 | if type == Data.self, let value = value as? CBORDecodedData { |
295 | | - result = value.decodedDataValue() as! T |
296 | | - } else if type == String.self, let value = value as? CBORDecodedString { |
297 | | - result = try value.decodedStringValue() as! T |
298 | | - } else if type == CBOR.NegativeUInt64.self { |
299 | | - result = try decode(value, as: CBOR.NegativeUInt64.self) as! T |
300 | | - } else if type == CBOR.Undefined.self { |
| 290 | + return value.decodedDataValue() as! T |
| 291 | + } |
| 292 | + if type == String.self, let value = value as? CBORDecodedString { |
| 293 | + return try value.decodedStringValue() as! T |
| 294 | + } |
| 295 | + if type == CBOR.NegativeUInt64.self { |
| 296 | + return try decode(value, as: CBOR.NegativeUInt64.self) as! T |
| 297 | + } |
| 298 | + if type == CBOR.Undefined.self { |
301 | 299 | guard let decodedValue = value as? T else { |
302 | 300 | throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value) |
303 | 301 | } |
304 | 302 |
|
305 | | - result = decodedValue |
306 | | - } else if let decodedValue = value as? T { |
307 | | - result = decodedValue |
308 | | - } else if type == Half.self { |
309 | | - result = try decodeFloatingPoint(value, as: Half.self) as! T |
310 | | - } else { |
311 | | - storage.push(container: value) |
312 | | - defer { storage.popContainer() } |
313 | | - |
314 | | - result = try type.init(from: self) |
| 303 | + return decodedValue |
| 304 | + } |
| 305 | + if let decodedValue = value as? T { |
| 306 | + return decodedValue |
| 307 | + } |
| 308 | + if type == Float16.self { |
| 309 | + return try decodeFloatingPoint(value, as: Float16.self) as! T |
315 | 310 | } |
316 | | - // swiftlint:enable force_cast |
317 | 311 |
|
318 | | - return result |
| 312 | + storage.push(container: value) |
| 313 | + defer { storage.popContainer() } |
| 314 | + // swiftlint:enable force_cast |
| 315 | + return try type.init(from: self) |
319 | 316 | } |
320 | 317 |
|
321 | 318 | // |
@@ -380,54 +377,39 @@ internal class __CBORDecoder: Decoder, SingleValueDecodingContainer { |
380 | 377 | } |
381 | 378 |
|
382 | 379 | fileprivate func decodeFloatingPoint<T>(_ value: Any, as type: T.Type) throws -> T where T: BinaryFloatingPoint { |
383 | | - let floatingPoint: T |
384 | | - if let half = value as? Half { |
385 | | - if half.isNaN { |
386 | | - if half.isSignalingNaN { |
387 | | - floatingPoint = .signalingNaN |
388 | | - } else { |
389 | | - floatingPoint = .nan |
390 | | - } |
391 | | - } else { |
392 | | - guard let value = T(exactly: half) else { |
393 | | - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(half)> does not fit in \(type).")) |
394 | | - } |
395 | | - |
396 | | - floatingPoint = value |
| 380 | + if let half = value as? Float16 { |
| 381 | + guard !half.isNaN else { |
| 382 | + return half.isSignalingNaN ? .signalingNaN : .nan |
397 | 383 | } |
398 | | - } else if let float = value as? Float { |
399 | | - if float.isNaN { |
400 | | - if float.isSignalingNaN { |
401 | | - floatingPoint = .signalingNaN |
402 | | - } else { |
403 | | - floatingPoint = .nan |
404 | | - } |
405 | | - } else { |
406 | | - guard let value = T(exactly: float) else { |
407 | | - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(float)> does not fit in \(type).")) |
408 | | - } |
409 | | - |
410 | | - floatingPoint = value |
| 384 | + guard let value = T(exactly: half) else { |
| 385 | + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(half)> does not fit in \(type).")) |
411 | 386 | } |
412 | | - } else if let double = value as? Double { |
413 | | - if double.isNaN { |
414 | | - if double.isSignalingNaN { |
415 | | - floatingPoint = .signalingNaN |
416 | | - } else { |
417 | | - floatingPoint = .nan |
418 | | - } |
419 | | - } else { |
420 | | - guard let value = T(exactly: double) else { |
421 | | - throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(double)> does not fit in \(type).")) |
422 | | - } |
423 | 387 |
|
424 | | - floatingPoint = value |
| 388 | + return value |
| 389 | + } |
| 390 | + |
| 391 | + if let float = value as? Float { |
| 392 | + guard !float.isNaN else { |
| 393 | + return float.isSignalingNaN ? .signalingNaN : .nan |
425 | 394 | } |
426 | | - } else { |
427 | | - throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value) |
| 395 | + guard let value = T(exactly: float) else { |
| 396 | + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(float)> does not fit in \(type).")) |
| 397 | + } |
| 398 | + |
| 399 | + return value |
428 | 400 | } |
| 401 | + if let double = value as? Double { |
| 402 | + guard !double.isNaN else { |
| 403 | + return double.isSignalingNaN ? .signalingNaN : .nan |
| 404 | + } |
| 405 | + guard let value = T(exactly: double) else { |
| 406 | + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(double)> does not fit in \(type).")) |
| 407 | + } |
429 | 408 |
|
430 | | - return floatingPoint |
| 409 | + return value |
| 410 | + |
| 411 | + } |
| 412 | + throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value) |
431 | 413 | } |
432 | 414 |
|
433 | 415 | fileprivate func decode(_ value: Any, as type: CBOR.NegativeUInt64.Type) throws -> CBOR.NegativeUInt64 { |
|
0 commit comments