3434
3535import XCTest
3636
37- final class KeyValueDecoderTests : XCTestCase {
37+ final class KeyValueDecoderXCTests : XCTestCase {
3838
3939 func testDecodes_String( ) {
4040 let decoder = KeyValueDecoder ( )
@@ -149,7 +149,7 @@ final class KeyValueDecoderTests: XCTestCase {
149149 }
150150
151151 func testDecodesRounded_Ints( ) {
152- let decoder = KeyValueDecoder ( )
152+ var decoder = KeyValueDecoder ( )
153153 decoder. intDecodingStrategy = . rounding( rule: . toNearestOrAwayFromZero)
154154
155155 XCTAssertEqual (
@@ -247,7 +247,7 @@ final class KeyValueDecoderTests: XCTestCase {
247247 }
248248
249249 func testDecodesRounded_UInts( ) {
250- let decoder = KeyValueDecoder ( )
250+ var decoder = KeyValueDecoder ( )
251251 decoder. intDecodingStrategy = . rounding( rule: . toNearestOrAwayFromZero)
252252
253253 XCTAssertEqual (
@@ -460,7 +460,7 @@ final class KeyValueDecoderTests: XCTestCase {
460460 }
461461
462462 func testDecodes_Null( ) {
463- let decoder = KeyValueDecoder ( )
463+ var decoder = KeyValueDecoder ( )
464464 decoder. nilDecodingStrategy = . default
465465
466466 XCTAssertThrowsError (
@@ -498,7 +498,7 @@ final class KeyValueDecoderTests: XCTestCase {
498498 }
499499
500500 func testDecodes_UnkeyedOptionals( ) {
501- let decoder = KeyValueDecoder ( )
501+ var decoder = KeyValueDecoder ( )
502502
503503 decoder. nilDecodingStrategy = . removed
504504 XCTAssertEqual (
@@ -749,7 +749,7 @@ final class KeyValueDecoderTests: XCTestCase {
749749 }
750750
751751 func testDecodes_UnkeyedNil( ) {
752- let decoder = KeyValueDecoder ( )
752+ var decoder = KeyValueDecoder ( )
753753 decoder. nilDecodingStrategy = . default
754754
755755 XCTAssertEqual (
@@ -963,7 +963,7 @@ final class KeyValueDecoderTests: XCTestCase {
963963 )
964964
965965 // [10, , 20.5, 1000, -Double.infinity]
966- let decoder = KeyValueDecoder ( )
966+ var decoder = KeyValueDecoder ( )
967967 decoder. intDecodingStrategy = . clamping( roundingRule: . toNearestOrAwayFromZero)
968968 XCTAssertEqual (
969969 try decoder. decode ( [ Int8 ] . self, from: [ 10 , 20.5 , 1000 , - Double. infinity] ) ,
@@ -1037,32 +1037,39 @@ private extension KeyValueDecoder {
10371037
10381038 }
10391039
1040- static func decodeValue< K: CodingKey , T> ( from value: [ String : Any ] , keyedBy: K . Type = K . self, with closure: @escaping ( inout KeyedDecodingContainer < K > ) throws -> T ) throws -> T {
1040+ static func decodeValue< K: CodingKey , T> (
1041+ from value: [ String : Any ] ,
1042+ keyedBy: K . Type = K . self,
1043+ with closure: @escaping ( inout KeyedDecodingContainer < K >
1044+ ) throws -> T ) throws -> T {
10411045 let proxy = StubDecoder . Proxy { decoder in
10421046 var container = try decoder. container ( keyedBy: K . self)
10431047 return try closure ( & container)
10441048 }
10451049
1046- let decoder = KeyValueDecoder ( )
1047- decoder. userInfo [ . decoder] = proxy. decode ( from : )
1050+ var decoder = KeyValueDecoder ( )
1051+ decoder. userInfo [ . decoder] = proxy as any DecodingProxy
10481052 _ = try decoder. decode ( StubDecoder . self, from: value)
10491053 return proxy. result!
10501054 }
10511055
1052- static func decodeUnkeyedValue< T> ( from value: [ Any ] , with closure: @escaping ( inout any UnkeyedDecodingContainer ) throws -> T ) throws -> T {
1056+ static func decodeUnkeyedValue< T> (
1057+ from value: [ Any ] ,
1058+ with closure: @escaping ( inout any UnkeyedDecodingContainer ) throws -> T
1059+ ) throws -> T {
10531060 let proxy = StubDecoder . Proxy { decoder in
10541061 var container = try decoder. unkeyedContainer ( )
10551062 return try closure ( & container)
10561063 }
10571064
1058- let decoder = KeyValueDecoder ( )
1059- decoder. userInfo [ . decoder] = proxy. decode ( from : )
1065+ var decoder = KeyValueDecoder ( )
1066+ decoder. userInfo [ . decoder] = proxy as any DecodingProxy
10601067 _ = try decoder. decode ( StubDecoder . self, from: value)
10611068 return proxy. result!
10621069 }
10631070
10641071 static func makeJSONCompatible( ) -> KeyValueDecoder {
1065- let decoder = KeyValueDecoder ( )
1072+ var decoder = KeyValueDecoder ( )
10661073 decoder. nilDecodingStrategy = . nsNull
10671074 return decoder
10681075 }
@@ -1072,9 +1079,13 @@ private extension CodingUserInfoKey {
10721079 static let decoder = CodingUserInfoKey ( rawValue: " decoder " ) !
10731080}
10741081
1082+ private protocol DecodingProxy : Sendable {
1083+ func decode( from decoder: any Decoder ) throws
1084+ }
1085+
10751086private struct StubDecoder : Decodable {
10761087
1077- final class Proxy < T> {
1088+ final class Proxy < T> : @ unchecked Sendable , DecodingProxy {
10781089 private let closure : ( any Decoder ) throws -> T
10791090 private( set) var result : T ?
10801091
@@ -1088,8 +1099,8 @@ private struct StubDecoder: Decodable {
10881099 }
10891100
10901101 init ( from decoder: any Decoder ) throws {
1091- let closure = decoder. userInfo [ . decoder] as! ( any Decoder ) throws -> Void
1092- try closure ( decoder)
1102+ let proxy = decoder. userInfo [ . decoder] as! any DecodingProxy
1103+ try proxy . decode ( from : decoder)
10931104 }
10941105}
10951106
0 commit comments