@@ -1266,35 +1266,80 @@ extension JSONDecoderImpl {
12661266 return bool
12671267 }
12681268
1269+ func decodeIfPresent( _ type: Bool . Type , forKey key: K ) throws -> Bool ? {
1270+ guard let value = getValueIfPresent ( forKey: key) else {
1271+ return nil
1272+ }
1273+ switch value {
1274+ case . null: return nil
1275+ case . bool( let result) : return result
1276+ default : throw createTypeMismatchError ( type: type, forKey: key, value: value)
1277+ }
1278+ }
1279+
12691280 func decode( _ type: String . Type , forKey key: K ) throws -> String {
12701281 let value = try getValue ( forKey: key)
12711282 return try impl. unwrapString ( from: value, for: self . codingPathNode, key)
12721283 }
12731284
1285+ func decodeIfPresent( _ type: String . Type , forKey key: K ) throws -> String ? {
1286+ guard let value = getValueIfPresent ( forKey: key) else {
1287+ return nil
1288+ }
1289+ switch value {
1290+ case . null: return nil
1291+ default : return try impl. unwrapString ( from: value, for: self . codingPathNode, key)
1292+ }
1293+ }
1294+
12741295 func decode( _: Double . Type , forKey key: K ) throws -> Double {
12751296 try decodeFloatingPoint ( key: key)
12761297 }
12771298
1299+ func decodeIfPresent( _: Double . Type , forKey key: K ) throws -> Double ? {
1300+ try decodeFloatingPointIfPresent ( key: key)
1301+ }
1302+
12781303 func decode( _: Float . Type , forKey key: K ) throws -> Float {
12791304 try decodeFloatingPoint ( key: key)
12801305 }
12811306
1307+ func decodeIfPresent( _: Float . Type , forKey key: K ) throws -> Float ? {
1308+ try decodeFloatingPointIfPresent ( key: key)
1309+ }
1310+
12821311 func decode( _: Int . Type , forKey key: K ) throws -> Int {
12831312 try decodeFixedWidthInteger ( key: key)
12841313 }
12851314
1315+ func decodeIfPresent( _: Int . Type , forKey key: K ) throws -> Int ? {
1316+ try decodeFixedWidthIntegerIfPresent ( key: key)
1317+ }
1318+
12861319 func decode( _: Int8 . Type , forKey key: K ) throws -> Int8 {
12871320 try decodeFixedWidthInteger ( key: key)
12881321 }
12891322
1323+ func decodeIfPresent( _: Int8 . Type , forKey key: K ) throws -> Int8 ? {
1324+ try decodeFixedWidthIntegerIfPresent ( key: key)
1325+ }
1326+
12901327 func decode( _: Int16 . Type , forKey key: K ) throws -> Int16 {
12911328 try decodeFixedWidthInteger ( key: key)
12921329 }
12931330
1331+ func decodeIfPresent( _: Int16 . Type , forKey key: K ) throws -> Int16 ? {
1332+ try decodeFixedWidthIntegerIfPresent ( key: key)
1333+ }
1334+
12941335 func decode( _: Int32 . Type , forKey key: K ) throws -> Int32 {
12951336 try decodeFixedWidthInteger ( key: key)
12961337 }
12971338
1339+ func decodeIfPresent( _: Int32 . Type , forKey key: K ) throws -> Int32 ? {
1340+ try decodeFixedWidthIntegerIfPresent ( key: key)
1341+ }
1342+
12981343 func decode( _: Int64 . Type , forKey key: K ) throws -> Int64 {
12991344 try decodeFixedWidthInteger ( key: key)
13001345 }
@@ -1304,22 +1349,42 @@ extension JSONDecoderImpl {
13041349 try decodeFixedWidthInteger ( key: key)
13051350 }
13061351
1352+ func decodeIfPresent( _: Int64 . Type , forKey key: K ) throws -> Int64 ? {
1353+ try decodeFixedWidthIntegerIfPresent ( key: key)
1354+ }
1355+
13071356 func decode( _: UInt . Type , forKey key: K ) throws -> UInt {
13081357 try decodeFixedWidthInteger ( key: key)
13091358 }
13101359
1360+ func decodeIfPresent( _: UInt . Type , forKey key: K ) throws -> UInt ? {
1361+ try decodeFixedWidthIntegerIfPresent ( key: key)
1362+ }
1363+
13111364 func decode( _: UInt8 . Type , forKey key: K ) throws -> UInt8 {
13121365 try decodeFixedWidthInteger ( key: key)
13131366 }
13141367
1368+ func decodeIfPresent( _: UInt8 . Type , forKey key: K ) throws -> UInt8 ? {
1369+ try decodeFixedWidthIntegerIfPresent ( key: key)
1370+ }
1371+
13151372 func decode( _: UInt16 . Type , forKey key: K ) throws -> UInt16 {
13161373 try decodeFixedWidthInteger ( key: key)
13171374 }
13181375
1376+ func decodeIfPresent( _: UInt16 . Type , forKey key: K ) throws -> UInt16 ? {
1377+ try decodeFixedWidthIntegerIfPresent ( key: key)
1378+ }
1379+
13191380 func decode( _: UInt32 . Type , forKey key: K ) throws -> UInt32 {
13201381 try decodeFixedWidthInteger ( key: key)
13211382 }
13221383
1384+ func decodeIfPresent( _: UInt32 . Type , forKey key: K ) throws -> UInt32 ? {
1385+ try decodeFixedWidthIntegerIfPresent ( key: key)
1386+ }
1387+
13231388 func decode( _: UInt64 . Type , forKey key: K ) throws -> UInt64 {
13241389 try decodeFixedWidthInteger ( key: key)
13251390 }
@@ -1329,10 +1394,24 @@ extension JSONDecoderImpl {
13291394 try decodeFixedWidthInteger ( key: key)
13301395 }
13311396
1397+ func decodeIfPresent( _: UInt64 . Type , forKey key: K ) throws -> UInt64 ? {
1398+ try decodeFixedWidthIntegerIfPresent ( key: key)
1399+ }
1400+
13321401 func decode< T: Decodable > ( _ type: T . Type , forKey key: K ) throws -> T {
13331402 try self . impl. unwrap ( try getValue ( forKey: key) , as: type, for: codingPathNode, key)
13341403 }
13351404
1405+ func decodeIfPresent< T: Decodable > ( _ type: T . Type , forKey key: K ) throws -> T ? {
1406+ guard let value = getValueIfPresent ( forKey: key) else {
1407+ return nil
1408+ }
1409+ switch value {
1410+ case . null: return nil
1411+ default : return try self . impl. unwrap ( value, as: type, for: codingPathNode, key)
1412+ }
1413+ }
1414+
13361415 func nestedContainer< NestedKey: CodingKey > ( keyedBy type: NestedKey . Type , forKey key: K ) throws -> KeyedDecodingContainer < NestedKey > {
13371416 let value = try getValue ( forKey: key)
13381417 return try impl. with ( value: value, path: codingPathNode. appending ( key) ) {
@@ -1378,6 +1457,10 @@ extension JSONDecoderImpl {
13781457 return value
13791458 }
13801459
1460+ @inline ( __always) private func getValueIfPresent( forKey key: some CodingKey ) -> JSONMap . Value ? {
1461+ dictionary [ key. stringValue]
1462+ }
1463+
13811464 private func createTypeMismatchError( type: Any . Type , forKey key: K , value: JSONMap . Value ) -> DecodingError {
13821465 return DecodingError . typeMismatch ( type, . init(
13831466 codingPath: self . codingPathNode. path ( byAppending: key) , debugDescription: " Expected to decode \( type) but found \( value. debugDataTypeDescription) instead. "
@@ -1393,6 +1476,26 @@ extension JSONDecoderImpl {
13931476 let value = try getValue ( forKey: key)
13941477 return try self . impl. unwrapFloatingPoint ( from: value, as: T . self, for: codingPathNode, key)
13951478 }
1479+
1480+ @inline ( __always) private func decodeFixedWidthIntegerIfPresent< T: FixedWidthInteger > ( key: Self . Key ) throws -> T ? {
1481+ guard let value = getValueIfPresent ( forKey: key) else {
1482+ return nil
1483+ }
1484+ switch value {
1485+ case . null: return nil
1486+ default : return try self . impl. unwrapFixedWidthInteger ( from: value, as: T . self, for: codingPathNode, key)
1487+ }
1488+ }
1489+
1490+ @inline ( __always) private func decodeFloatingPointIfPresent< T: PrevalidatedJSONNumberBufferConvertible & BinaryFloatingPoint > ( key: K ) throws -> T ? {
1491+ guard let value = getValueIfPresent ( forKey: key) else {
1492+ return nil
1493+ }
1494+ switch value {
1495+ case . null: return nil
1496+ default : return try self . impl. unwrapFloatingPoint ( from: value, as: T . self, for: codingPathNode, key)
1497+ }
1498+ }
13961499 }
13971500}
13981501
@@ -1456,37 +1559,82 @@ extension JSONDecoderImpl {
14561559 return bool
14571560 }
14581561
1562+ mutating func decodeIfPresent( _ type: Bool . Type ) throws -> Bool ? {
1563+ let value = self . peekNextValueIfPresent ( ofType: Bool . self)
1564+ let result : Bool ? = switch value {
1565+ case nil , . null: nil
1566+ case . bool( let bool) : bool
1567+ default : throw impl. createTypeMismatchError ( type: type, for: self . currentCodingPath, value: value!)
1568+ }
1569+ advanceToNextValue ( )
1570+ return result
1571+ }
1572+
14591573 mutating func decode( _ type: String . Type ) throws -> String {
14601574 let value = try self . peekNextValue ( ofType: String . self)
14611575 let string = try impl. unwrapString ( from: value, for: codingPathNode, currentIndexKey)
14621576 advanceToNextValue ( )
14631577 return string
14641578 }
14651579
1580+ mutating func decodeIfPresent( _ type: String . Type ) throws -> String ? {
1581+ let value = self . peekNextValueIfPresent ( ofType: String . self)
1582+ let result : String ? = switch value {
1583+ case nil , . null: nil
1584+ default : try impl. unwrapString ( from: value. unsafelyUnwrapped, for: codingPathNode, currentIndexKey)
1585+ }
1586+ advanceToNextValue ( )
1587+ return result
1588+ }
1589+
14661590 mutating func decode( _: Double . Type ) throws -> Double {
14671591 try decodeFloatingPoint ( )
14681592 }
14691593
1594+ mutating func decodeIfPresent( _ type: Double . Type ) throws -> Double ? {
1595+ try decodeFloatingPointIfPresent ( )
1596+ }
1597+
14701598 mutating func decode( _: Float . Type ) throws -> Float {
14711599 try decodeFloatingPoint ( )
14721600 }
14731601
1602+ mutating func decodeIfPresent( _ type: Float . Type ) throws -> Float ? {
1603+ try decodeFloatingPointIfPresent ( )
1604+ }
1605+
14741606 mutating func decode( _: Int . Type ) throws -> Int {
14751607 try decodeFixedWidthInteger ( )
14761608 }
14771609
1610+ mutating func decodeIfPresent( _: Int . Type ) throws -> Int ? {
1611+ try decodeFixedWidthIntegerIfPresent ( )
1612+ }
1613+
14781614 mutating func decode( _: Int8 . Type ) throws -> Int8 {
14791615 try decodeFixedWidthInteger ( )
14801616 }
14811617
1618+ mutating func decodeIfPresent( _: Int8 . Type ) throws -> Int8 ? {
1619+ try decodeFixedWidthIntegerIfPresent ( )
1620+ }
1621+
14821622 mutating func decode( _: Int16 . Type ) throws -> Int16 {
14831623 try decodeFixedWidthInteger ( )
14841624 }
14851625
1626+ mutating func decodeIfPresent( _: Int16 . Type ) throws -> Int16 ? {
1627+ try decodeFixedWidthIntegerIfPresent ( )
1628+ }
1629+
14861630 mutating func decode( _: Int32 . Type ) throws -> Int32 {
14871631 try decodeFixedWidthInteger ( )
14881632 }
14891633
1634+ mutating func decodeIfPresent( _: Int32 . Type ) throws -> Int32 ? {
1635+ try decodeFixedWidthIntegerIfPresent ( )
1636+ }
1637+
14901638 mutating func decode( _: Int64 . Type ) throws -> Int64 {
14911639 try decodeFixedWidthInteger ( )
14921640 }
@@ -1496,22 +1644,42 @@ extension JSONDecoderImpl {
14961644 try decodeFixedWidthInteger ( )
14971645 }
14981646
1647+ mutating func decodeIfPresent( _: Int64 . Type ) throws -> Int64 ? {
1648+ try decodeFixedWidthIntegerIfPresent ( )
1649+ }
1650+
14991651 mutating func decode( _: UInt . Type ) throws -> UInt {
15001652 try decodeFixedWidthInteger ( )
15011653 }
15021654
1655+ mutating func decodeIfPresent( _: UInt . Type ) throws -> UInt ? {
1656+ try decodeFixedWidthIntegerIfPresent ( )
1657+ }
1658+
15031659 mutating func decode( _: UInt8 . Type ) throws -> UInt8 {
15041660 try decodeFixedWidthInteger ( )
15051661 }
15061662
1663+ mutating func decodeIfPresent( _: UInt8 . Type ) throws -> UInt8 ? {
1664+ try decodeFixedWidthIntegerIfPresent ( )
1665+ }
1666+
15071667 mutating func decode( _: UInt16 . Type ) throws -> UInt16 {
15081668 try decodeFixedWidthInteger ( )
15091669 }
15101670
1671+ mutating func decodeIfPresent( _: UInt16 . Type ) throws -> UInt16 ? {
1672+ try decodeFixedWidthIntegerIfPresent ( )
1673+ }
1674+
15111675 mutating func decode( _: UInt32 . Type ) throws -> UInt32 {
15121676 try decodeFixedWidthInteger ( )
15131677 }
15141678
1679+ mutating func decodeIfPresent( _: UInt32 . Type ) throws -> UInt32 ? {
1680+ try decodeFixedWidthIntegerIfPresent ( )
1681+ }
1682+
15151683 mutating func decode( _: UInt64 . Type ) throws -> UInt64 {
15161684 try decodeFixedWidthInteger ( )
15171685 }
@@ -1521,6 +1689,10 @@ extension JSONDecoderImpl {
15211689 try decodeFixedWidthInteger ( )
15221690 }
15231691
1692+ mutating func decodeIfPresent( _: UInt64 . Type ) throws -> UInt64 ? {
1693+ try decodeFixedWidthIntegerIfPresent ( )
1694+ }
1695+
15241696 mutating func decode< T: Decodable > ( _ type: T . Type ) throws -> T {
15251697 let value = try self . peekNextValue ( ofType: type)
15261698 let result = try impl. unwrap ( value, as: type, for: codingPathNode, currentIndexKey)
@@ -1529,6 +1701,16 @@ extension JSONDecoderImpl {
15291701 return result
15301702 }
15311703
1704+ mutating func decodeIfPresent< T: Decodable > ( _ type: T . Type ) throws -> T ? {
1705+ let value = self . peekNextValueIfPresent ( ofType: type)
1706+ let result : T ? = switch value {
1707+ case nil , . null: nil
1708+ default : try impl. unwrap ( value. unsafelyUnwrapped, as: type, for: codingPathNode, currentIndexKey)
1709+ }
1710+ advanceToNextValue ( )
1711+ return result
1712+ }
1713+
15321714 mutating func nestedContainer< NestedKey: CodingKey > ( keyedBy type: NestedKey . Type ) throws -> KeyedDecodingContainer < NestedKey > {
15331715 let value = try self . peekNextValue ( ofType: KeyedDecodingContainer< NestedKey> . self )
15341716 let container = try impl. with ( value: value, path: codingPathNode. appending ( index: currentIndex) ) {
@@ -1568,11 +1750,20 @@ extension JSONDecoderImpl {
15681750 }
15691751
15701752 @inline ( __always)
1571- private mutating func peekNextValue < T> ( ofType type: T . Type ) throws -> JSONMap . Value {
1753+ private mutating func peekNextValueIfPresent < T> ( ofType type: T . Type ) -> JSONMap . Value ? {
15721754 if let value = peekedValue {
15731755 return value
15741756 }
15751757 guard let nextValue = valueIterator. next ( ) else {
1758+ return nil
1759+ }
1760+ peekedValue = nextValue
1761+ return nextValue
1762+ }
1763+
1764+ @inline ( __always)
1765+ private mutating func peekNextValue< T> ( ofType type: T . Type ) throws -> JSONMap . Value {
1766+ guard let nextValue = peekNextValueIfPresent ( ofType: type) else {
15761767 var message = " Unkeyed container is at end. "
15771768 if T . self == UnkeyedContainer . self {
15781769 message = " Cannot get nested unkeyed container -- unkeyed container is at end. "
@@ -1590,7 +1781,6 @@ extension JSONDecoderImpl {
15901781 debugDescription: message,
15911782 underlyingError: nil ) )
15921783 }
1593- peekedValue = nextValue
15941784 return nextValue
15951785 }
15961786
@@ -1609,6 +1799,26 @@ extension JSONDecoderImpl {
16091799 advanceToNextValue ( )
16101800 return result
16111801 }
1802+
1803+ @inline ( __always) private mutating func decodeFixedWidthIntegerIfPresent< T: FixedWidthInteger > ( ) throws -> T ? {
1804+ let value = self . peekNextValueIfPresent ( ofType: T . self)
1805+ let result : T ? = switch value {
1806+ case nil , . null: nil
1807+ default : try impl. unwrapFixedWidthInteger ( from: value. unsafelyUnwrapped, as: T . self, for: codingPathNode, currentIndexKey)
1808+ }
1809+ advanceToNextValue ( )
1810+ return result
1811+ }
1812+
1813+ @inline ( __always) private mutating func decodeFloatingPointIfPresent< T: PrevalidatedJSONNumberBufferConvertible & BinaryFloatingPoint > ( ) throws -> T ? {
1814+ let value = self . peekNextValueIfPresent ( ofType: T . self)
1815+ let result : T ? = switch value {
1816+ case nil , . null: nil
1817+ default : try impl. unwrapFloatingPoint ( from: value. unsafelyUnwrapped, as: T . self, for: codingPathNode, currentIndexKey)
1818+ }
1819+ advanceToNextValue ( )
1820+ return result
1821+ }
16121822 }
16131823}
16141824
0 commit comments