diff --git a/CHANGELOG.md b/CHANGELOG.md index ea88f23e5b..a7e0af914a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Unreleased - [IMPROVEMENT] Increase RUM batch maximum age to 24hrs. See [#2302][] +- [IMPROVEMENT] Improve feature-to-feature communication performances. See [#2304][] # 2.27.0 / 06-05-2025 @@ -875,6 +876,7 @@ Release `2.0` introduces breaking changes. Follow the [Migration Guide](MIGRATIO [#2260]: https://github.com/DataDog/dd-sdk-ios/pull/2260 [#2268]: https://github.com/DataDog/dd-sdk-ios/pull/2268 [#2302]: https://github.com/DataDog/dd-sdk-ios/pull/2302 +[#2304]: https://github.com/DataDog/dd-sdk-ios/pull/2304 [@00fa9a]: https://github.com/00FA9A [@britton-earnin]: https://github.com/Britton-Earnin [@hengyu]: https://github.com/Hengyu diff --git a/Datadog/Datadog.xcodeproj/project.pbxproj b/Datadog/Datadog.xcodeproj/project.pbxproj index 9cf2f89753..00632dc338 100644 --- a/Datadog/Datadog.xcodeproj/project.pbxproj +++ b/Datadog/Datadog.xcodeproj/project.pbxproj @@ -157,7 +157,6 @@ 1182FA5B2DA2F827007FE71A /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9C22DA2F827007FE71A /* SwiftExtensions.swift */; }; 1182FA5C2DA2F827007FE71A /* Decompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9BE2DA2F827007FE71A /* Decompression.swift */; }; 1182FA5D2DA2F827007FE71A /* RUMFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9F92DA2F827007FE71A /* RUMFeatureMocks.swift */; }; - 1182FA5E2DA2F827007FE71A /* FeatureBaggageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9E62DA2F827007FE71A /* FeatureBaggageMock.swift */; }; 1182FA5F2DA2F827007FE71A /* DatadogContextProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9D92DA2F827007FE71A /* DatadogContextProviderMock.swift */; }; 1182FA602DA2F827007FE71A /* SRDataModelsMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182FA0A2DA2F827007FE71A /* SRDataModelsMocks.swift */; }; 1182FA612DA2F827007FE71A /* FeatureMessageMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9E72DA2F827007FE71A /* FeatureMessageMocks.swift */; }; @@ -239,7 +238,6 @@ 1182FAAF2DA2F827007FE71A /* SwiftExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9C22DA2F827007FE71A /* SwiftExtensions.swift */; }; 1182FAB02DA2F827007FE71A /* Decompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9BE2DA2F827007FE71A /* Decompression.swift */; }; 1182FAB12DA2F827007FE71A /* RUMFeatureMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9F92DA2F827007FE71A /* RUMFeatureMocks.swift */; }; - 1182FAB22DA2F827007FE71A /* FeatureBaggageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9E62DA2F827007FE71A /* FeatureBaggageMock.swift */; }; 1182FAB32DA2F827007FE71A /* DatadogContextProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9D92DA2F827007FE71A /* DatadogContextProviderMock.swift */; }; 1182FAB42DA2F827007FE71A /* SRDataModelsMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182FA0A2DA2F827007FE71A /* SRDataModelsMocks.swift */; }; 1182FAB52DA2F827007FE71A /* FeatureMessageMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1182F9E72DA2F827007FE71A /* FeatureMessageMocks.swift */; }; @@ -1021,10 +1019,6 @@ D21C26C628A3B49C005DD405 /* FeatureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21C26C428A3B49C005DD405 /* FeatureStorage.swift */; }; D21C26D128A64599005DD405 /* MessageBusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21C26D028A64599005DD405 /* MessageBusTests.swift */; }; D21C26D228A64599005DD405 /* MessageBusTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21C26D028A64599005DD405 /* MessageBusTests.swift */; }; - D2216EC02A94DE2900ADAEC8 /* FeatureBaggage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2216EBF2A94DE2800ADAEC8 /* FeatureBaggage.swift */; }; - D2216EC12A94DE2900ADAEC8 /* FeatureBaggage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2216EBF2A94DE2800ADAEC8 /* FeatureBaggage.swift */; }; - D2216EC32A96649500ADAEC8 /* FeatureBaggageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2216EC22A96632F00ADAEC8 /* FeatureBaggageTests.swift */; }; - D2216EC42A96649700ADAEC8 /* FeatureBaggageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2216EC22A96632F00ADAEC8 /* FeatureBaggageTests.swift */; }; D22442C52CA301DA002E71E4 /* UIColor+SessionReplay.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22442C42CA301DA002E71E4 /* UIColor+SessionReplay.swift */; }; D224430429E9588100274EC7 /* TelemetryReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D214DAA729E54CB4004D0AE8 /* TelemetryReceiver.swift */; }; D224430529E9588500274EC7 /* TelemetryReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D214DAA729E54CB4004D0AE8 /* TelemetryReceiver.swift */; }; @@ -1082,9 +1076,7 @@ D23039EC298D5236001A1FA3 /* LaunchTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039BE298D5235001A1FA3 /* LaunchTime.swift */; }; D23039EE298D5236001A1FA3 /* FeatureMessageReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C1298D5235001A1FA3 /* FeatureMessageReceiver.swift */; }; D23039EF298D5236001A1FA3 /* FeatureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C2298D5235001A1FA3 /* FeatureMessage.swift */; }; - D23039F0298D5236001A1FA3 /* AnyEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C4298D5235001A1FA3 /* AnyEncoder.swift */; }; D23039F1298D5236001A1FA3 /* AnyDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C5298D5235001A1FA3 /* AnyDecodable.swift */; }; - D23039F2298D5236001A1FA3 /* AnyDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C6298D5235001A1FA3 /* AnyDecoder.swift */; }; D23039F3298D5236001A1FA3 /* DynamicCodingKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C7298D5235001A1FA3 /* DynamicCodingKey.swift */; }; D23039F4298D5236001A1FA3 /* AnyCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C8298D5235001A1FA3 /* AnyCodable.swift */; }; D23039F5298D5236001A1FA3 /* AnyEncodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C9298D5235001A1FA3 /* AnyEncodable.swift */; }; @@ -1732,26 +1724,20 @@ D2DA2376298D57AA00C6C7E6 /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039B4298D5235001A1FA3 /* UserInfo.swift */; }; D2DA2377298D57AA00C6C7E6 /* URLRequestBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039D2298D5235001A1FA3 /* URLRequestBuilder.swift */; }; D2DA2378298D57AA00C6C7E6 /* Attributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039CB298D5235001A1FA3 /* Attributes.swift */; }; - D2DA2379298D57AA00C6C7E6 /* AnyDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C6298D5235001A1FA3 /* AnyDecoder.swift */; }; D2DA237A298D57AA00C6C7E6 /* FeatureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C2298D5235001A1FA3 /* FeatureMessage.swift */; }; D2DA237B298D57AA00C6C7E6 /* DateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039B7298D5235001A1FA3 /* DateProvider.swift */; }; D2DA237C298D57AA00C6C7E6 /* DatadogCoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039B1298D5235001A1FA3 /* DatadogCoreProtocol.swift */; }; D2DA237D298D57AA00C6C7E6 /* DataCompression.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039D4298D5235001A1FA3 /* DataCompression.swift */; }; - D2DA237E298D57AA00C6C7E6 /* AnyEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23039C4298D5235001A1FA3 /* AnyEncoder.swift */; }; D2DA23A1298D58F400C6C7E6 /* ReadWriteLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2395298D58F300C6C7E6 /* ReadWriteLockTests.swift */; }; D2DA23A3298D58F400C6C7E6 /* AnyEncodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2398298D58F300C6C7E6 /* AnyEncodableTests.swift */; }; D2DA23A4298D58F400C6C7E6 /* AnyCodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2399298D58F300C6C7E6 /* AnyCodableTests.swift */; }; - D2DA23A5298D58F400C6C7E6 /* AnyDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239A298D58F300C6C7E6 /* AnyDecodableTests.swift */; }; - D2DA23A6298D58F400C6C7E6 /* AnyCoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239B298D58F300C6C7E6 /* AnyCoderTests.swift */; }; D2DA23A7298D58F400C6C7E6 /* AppStateHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239D298D58F300C6C7E6 /* AppStateHistoryTests.swift */; }; D2DA23A8298D58F400C6C7E6 /* DeviceInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239E298D58F300C6C7E6 /* DeviceInfoTests.swift */; }; D2DA23AA298D58F400C6C7E6 /* FeatureMessageReceiverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA23A0298D58F400C6C7E6 /* FeatureMessageReceiverTests.swift */; }; D2DA23B1298D59DC00C6C7E6 /* AnyEncodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2398298D58F300C6C7E6 /* AnyEncodableTests.swift */; }; D2DA23B2298D59DC00C6C7E6 /* AppStateHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239D298D58F300C6C7E6 /* AppStateHistoryTests.swift */; }; - D2DA23B3298D59DC00C6C7E6 /* AnyDecodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239A298D58F300C6C7E6 /* AnyDecodableTests.swift */; }; D2DA23B4298D59DC00C6C7E6 /* AnyCodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2399298D58F300C6C7E6 /* AnyCodableTests.swift */; }; D2DA23B5298D59DC00C6C7E6 /* ReadWriteLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA2395298D58F300C6C7E6 /* ReadWriteLockTests.swift */; }; - D2DA23B6298D59DC00C6C7E6 /* AnyCoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239B298D58F300C6C7E6 /* AnyCoderTests.swift */; }; D2DA23B8298D59DC00C6C7E6 /* FeatureMessageReceiverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA23A0298D58F400C6C7E6 /* FeatureMessageReceiverTests.swift */; }; D2DA23BA298D59DC00C6C7E6 /* DeviceInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2DA239E298D58F300C6C7E6 /* DeviceInfoTests.swift */; }; D2DA23C5298D59F300C6C7E6 /* TestUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D257958B298ABB83008A1BE5 /* TestUtilities.framework */; }; @@ -2337,7 +2323,6 @@ 1182F9E32DA2F827007FE71A /* DateProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateProvider.swift; sourceTree = ""; }; 1182F9E42DA2F827007FE71A /* DDErrorMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DDErrorMocks.swift; sourceTree = ""; }; 1182F9E52DA2F827007FE71A /* EventMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMocks.swift; sourceTree = ""; }; - 1182F9E62DA2F827007FE71A /* FeatureBaggageMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureBaggageMock.swift; sourceTree = ""; }; 1182F9E72DA2F827007FE71A /* FeatureMessageMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureMessageMocks.swift; sourceTree = ""; }; 1182F9E82DA2F827007FE71A /* FeatureMessageReceiverMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureMessageReceiverMock.swift; sourceTree = ""; }; 1182F9E92DA2F827007FE71A /* FeatureRegistrationCoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureRegistrationCoreMock.swift; sourceTree = ""; }; @@ -3056,8 +3041,6 @@ D21C26D028A64599005DD405 /* MessageBusTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBusTests.swift; sourceTree = ""; }; D21C26EA28AFA11E005DD405 /* LogMessageReceiverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogMessageReceiverTests.swift; sourceTree = ""; }; D21C26ED28AFB65B005DD405 /* ErrorMessageReceiverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMessageReceiverTests.swift; sourceTree = ""; }; - D2216EBF2A94DE2800ADAEC8 /* FeatureBaggage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureBaggage.swift; sourceTree = ""; }; - D2216EC22A96632F00ADAEC8 /* FeatureBaggageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureBaggageTests.swift; sourceTree = ""; }; D22442C42CA301DA002E71E4 /* UIColor+SessionReplay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+SessionReplay.swift"; sourceTree = ""; }; D224430C29E95D6600274EC7 /* CrashReportReceiverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CrashReportReceiverTests.swift; sourceTree = ""; }; D22789352D64A0D3007E9DB0 /* UploadQualityMetric.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadQualityMetric.swift; sourceTree = ""; }; @@ -3083,9 +3066,7 @@ D23039BE298D5235001A1FA3 /* LaunchTime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchTime.swift; sourceTree = ""; }; D23039C1298D5235001A1FA3 /* FeatureMessageReceiver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureMessageReceiver.swift; sourceTree = ""; }; D23039C2298D5235001A1FA3 /* FeatureMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureMessage.swift; sourceTree = ""; }; - D23039C4298D5235001A1FA3 /* AnyEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyEncoder.swift; sourceTree = ""; }; D23039C5298D5235001A1FA3 /* AnyDecodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyDecodable.swift; sourceTree = ""; }; - D23039C6298D5235001A1FA3 /* AnyDecoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyDecoder.swift; sourceTree = ""; }; D23039C7298D5235001A1FA3 /* DynamicCodingKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicCodingKey.swift; sourceTree = ""; }; D23039C8298D5235001A1FA3 /* AnyCodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyCodable.swift; sourceTree = ""; }; D23039C9298D5235001A1FA3 /* AnyEncodable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyEncodable.swift; sourceTree = ""; }; @@ -3248,8 +3229,6 @@ D2DA2395298D58F300C6C7E6 /* ReadWriteLockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadWriteLockTests.swift; sourceTree = ""; }; D2DA2398298D58F300C6C7E6 /* AnyEncodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyEncodableTests.swift; sourceTree = ""; }; D2DA2399298D58F300C6C7E6 /* AnyCodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyCodableTests.swift; sourceTree = ""; }; - D2DA239A298D58F300C6C7E6 /* AnyDecodableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyDecodableTests.swift; sourceTree = ""; }; - D2DA239B298D58F300C6C7E6 /* AnyCoderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyCoderTests.swift; sourceTree = ""; }; D2DA239D298D58F300C6C7E6 /* AppStateHistoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppStateHistoryTests.swift; sourceTree = ""; }; D2DA239E298D58F300C6C7E6 /* DeviceInfoTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceInfoTests.swift; sourceTree = ""; }; D2DA23A0298D58F400C6C7E6 /* FeatureMessageReceiverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureMessageReceiverTests.swift; sourceTree = ""; }; @@ -3751,7 +3730,6 @@ 1182F9E32DA2F827007FE71A /* DateProvider.swift */, 1182F9E42DA2F827007FE71A /* DDErrorMocks.swift */, 1182F9E52DA2F827007FE71A /* EventMocks.swift */, - 1182F9E62DA2F827007FE71A /* FeatureBaggageMock.swift */, 1182F9E72DA2F827007FE71A /* FeatureMessageMocks.swift */, 1182F9E82DA2F827007FE71A /* FeatureMessageReceiverMock.swift */, 1182F9E92DA2F827007FE71A /* FeatureRegistrationCoreMock.swift */, @@ -6184,7 +6162,6 @@ D23039BF298D5235001A1FA3 /* MessageBus */ = { isa = PBXGroup; children = ( - D2216EBF2A94DE2800ADAEC8 /* FeatureBaggage.swift */, D23039C1298D5235001A1FA3 /* FeatureMessageReceiver.swift */, D23039C2298D5235001A1FA3 /* FeatureMessage.swift */, ); @@ -6194,8 +6171,6 @@ D23039C3298D5235001A1FA3 /* Codable */ = { isa = PBXGroup; children = ( - D23039C4298D5235001A1FA3 /* AnyEncoder.swift */, - D23039C6298D5235001A1FA3 /* AnyDecoder.swift */, D23039C7298D5235001A1FA3 /* DynamicCodingKey.swift */, D23039C8298D5235001A1FA3 /* AnyCodable.swift */, D23039C9298D5235001A1FA3 /* AnyEncodable.swift */, @@ -6565,7 +6540,6 @@ D2A783D829A530DC003B03BB /* MessageBus */ = { isa = PBXGroup; children = ( - D2216EC22A96632F00ADAEC8 /* FeatureBaggageTests.swift */, D2DA23A0298D58F400C6C7E6 /* FeatureMessageReceiverTests.swift */, ); path = MessageBus; @@ -6657,8 +6631,6 @@ children = ( D2DA2398298D58F300C6C7E6 /* AnyEncodableTests.swift */, D2DA2399298D58F300C6C7E6 /* AnyCodableTests.swift */, - D2DA239A298D58F300C6C7E6 /* AnyDecodableTests.swift */, - D2DA239B298D58F300C6C7E6 /* AnyCoderTests.swift */, ); path = Codable; sourceTree = ""; @@ -8915,7 +8887,6 @@ D23039F8298D5236001A1FA3 /* InternalLogger.swift in Sources */, 6174D6132BFDF16C00EC7469 /* BundleType.swift in Sources */, D2303A01298D5236001A1FA3 /* DateFormatting.swift in Sources */, - D2216EC02A94DE2900ADAEC8 /* FeatureBaggage.swift in Sources */, D23039F1298D5236001A1FA3 /* AnyDecodable.swift in Sources */, 6167E6E22B81207200C3CA2D /* DDCrashReport.swift in Sources */, D2160CC529C0DED100FAA9A5 /* URLSessionTaskInterception.swift in Sources */, @@ -8943,7 +8914,6 @@ D23039F6298D5236001A1FA3 /* Attributes.swift in Sources */, D20731CB29A52E6000ECBF94 /* Sampler.swift in Sources */, D2EBEE2029BA160F00B15732 /* TracePropagationHeadersWriter.swift in Sources */, - D23039F2298D5236001A1FA3 /* AnyDecoder.swift in Sources */, D23039EF298D5236001A1FA3 /* FeatureMessage.swift in Sources */, D2160CA029C0DE5700FAA9A5 /* HostsSanitizer.swift in Sources */, D22F06D729DAFD500026CC3C /* FixedWidthInteger+Convenience.swift in Sources */, @@ -8957,7 +8927,6 @@ D2EA0F462C0E1AE300CB20F8 /* SessionReplayConfiguration.swift in Sources */, 6167E6F92B81E95900C3CA2D /* BinaryImage.swift in Sources */, 6174D60C2BFDDEDF00EC7469 /* SDKMetricFields.swift in Sources */, - D23039F0298D5236001A1FA3 /* AnyEncoder.swift in Sources */, D2A783D429A5309F003B03BB /* SwiftExtensions.swift in Sources */, 3C0D5DD72A543B3B00446CF9 /* Event.swift in Sources */, D2D7482B2DC1214100C61353 /* LogEventAttributes.swift in Sources */, @@ -9214,7 +9183,6 @@ 1182FA5B2DA2F827007FE71A /* SwiftExtensions.swift in Sources */, 1182FA5C2DA2F827007FE71A /* Decompression.swift in Sources */, 1182FA5D2DA2F827007FE71A /* RUMFeatureMocks.swift in Sources */, - 1182FA5E2DA2F827007FE71A /* FeatureBaggageMock.swift in Sources */, 1182FA5F2DA2F827007FE71A /* DatadogContextProviderMock.swift in Sources */, 1182FA602DA2F827007FE71A /* SRDataModelsMocks.swift in Sources */, 1182FA612DA2F827007FE71A /* FeatureMessageMocks.swift in Sources */, @@ -9304,7 +9272,6 @@ 1182FAAF2DA2F827007FE71A /* SwiftExtensions.swift in Sources */, 1182FAB02DA2F827007FE71A /* Decompression.swift in Sources */, 1182FAB12DA2F827007FE71A /* RUMFeatureMocks.swift in Sources */, - 1182FAB22DA2F827007FE71A /* FeatureBaggageMock.swift in Sources */, 1182FAB32DA2F827007FE71A /* DatadogContextProviderMock.swift in Sources */, 1182FAB42DA2F827007FE71A /* SRDataModelsMocks.swift in Sources */, 1182FAB52DA2F827007FE71A /* FeatureMessageMocks.swift in Sources */, @@ -9993,7 +9960,6 @@ D2D9A9DA2DBFD360005DB31D /* CrashContext.swift in Sources */, 6174D6142BFDF16C00EC7469 /* BundleType.swift in Sources */, D2DA236F298D57AA00C6C7E6 /* DateFormatting.swift in Sources */, - D2216EC12A94DE2900ADAEC8 /* FeatureBaggage.swift in Sources */, D2DA2370298D57AA00C6C7E6 /* AnyDecodable.swift in Sources */, 6167E6E32B81207200C3CA2D /* DDCrashReport.swift in Sources */, D2160CC629C0DED100FAA9A5 /* URLSessionTaskInterception.swift in Sources */, @@ -10022,7 +9988,6 @@ 96155A3E2D7F01250029034E /* CustomDump.swift in Sources */, D20731CC29A52E6000ECBF94 /* Sampler.swift in Sources */, D2EBEE2E29BA161100B15732 /* TracePropagationHeadersWriter.swift in Sources */, - D2DA2379298D57AA00C6C7E6 /* AnyDecoder.swift in Sources */, D2DA237A298D57AA00C6C7E6 /* FeatureMessage.swift in Sources */, D2160CA129C0DE5700FAA9A5 /* HostsSanitizer.swift in Sources */, D22F06D829DAFD500026CC3C /* FixedWidthInteger+Convenience.swift in Sources */, @@ -10036,7 +10001,6 @@ B3E46CAF2D91B40000BABF66 /* NetworkContext.swift in Sources */, 6167E6FA2B81E95900C3CA2D /* BinaryImage.swift in Sources */, 6174D60D2BFDDEDF00EC7469 /* SDKMetricFields.swift in Sources */, - D2DA237E298D57AA00C6C7E6 /* AnyEncoder.swift in Sources */, D2A783D529A530A0003B03BB /* SwiftExtensions.swift in Sources */, 3C0D5DD82A543B3B00446CF9 /* Event.swift in Sources */, 3CBDE68B2AA0C47300F6A7B6 /* URLSessionTask+Tracking.swift in Sources */, @@ -10067,7 +10031,6 @@ D28ABFD72CECDE6B00623F27 /* URLSessionInterceptorTests.swift in Sources */, D2EBEE4329BA168200B15732 /* TraceIDGeneratorTests.swift in Sources */, D2DA23A7298D58F400C6C7E6 /* AppStateHistoryTests.swift in Sources */, - D2DA23A5298D58F400C6C7E6 /* AnyDecodableTests.swift in Sources */, D2EBEE3D29BA163E00B15732 /* W3CHTTPHeadersWriterTests.swift in Sources */, D2DA23A4298D58F400C6C7E6 /* AnyCodableTests.swift in Sources */, D2160CDE29C0DF6700FAA9A5 /* URLSessionTaskInterceptionTests.swift in Sources */, @@ -10079,10 +10042,8 @@ D284C7402C2059F3005142CC /* ObjcExceptionTests.swift in Sources */, D2C5D5282B83FD5300B63F36 /* WebViewMessageTests.swift in Sources */, D20731CD29A52E8700ECBF94 /* SamplerTests.swift in Sources */, - D2DA23A6298D58F400C6C7E6 /* AnyCoderTests.swift in Sources */, D2EBEE3E29BA163E00B15732 /* W3CHTTPHeadersReaderTests.swift in Sources */, D2160CE929C0E00200FAA9A5 /* MethodSwizzlerTests.swift in Sources */, - D2216EC32A96649500ADAEC8 /* FeatureBaggageTests.swift in Sources */, D2160CDC29C0DF6700FAA9A5 /* HostsSanitizerTests.swift in Sources */, 615192CD2BD6948B0005A782 /* HTTPHeadersWriterTests.swift in Sources */, 6156A9072BF75A7C00DF66C3 /* ImmutableRequestTests.swift in Sources */, @@ -10121,7 +10082,6 @@ D28ABFD62CECDE6B00623F27 /* URLSessionInterceptorTests.swift in Sources */, D2EBEE4529BA168400B15732 /* TraceIDGeneratorTests.swift in Sources */, D2DA23B2298D59DC00C6C7E6 /* AppStateHistoryTests.swift in Sources */, - D2DA23B3298D59DC00C6C7E6 /* AnyDecodableTests.swift in Sources */, D2EBEE4129BA163F00B15732 /* W3CHTTPHeadersWriterTests.swift in Sources */, D2DA23B4298D59DC00C6C7E6 /* AnyCodableTests.swift in Sources */, D2160CDF29C0DF6700FAA9A5 /* URLSessionTaskInterceptionTests.swift in Sources */, @@ -10133,9 +10093,7 @@ D2C5D5292B83FD5400B63F36 /* WebViewMessageTests.swift in Sources */, D20731CE29A52E8700ECBF94 /* SamplerTests.swift in Sources */, D2160CEA29C0E00200FAA9A5 /* MethodSwizzlerTests.swift in Sources */, - D2DA23B6298D59DC00C6C7E6 /* AnyCoderTests.swift in Sources */, D2EBEE4229BA163F00B15732 /* W3CHTTPHeadersReaderTests.swift in Sources */, - D2216EC42A96649700ADAEC8 /* FeatureBaggageTests.swift in Sources */, D2160CDD29C0DF6700FAA9A5 /* HostsSanitizerTests.swift in Sources */, 615192CE2BD6948B0005A782 /* HTTPHeadersWriterTests.swift in Sources */, 6156A9082BF75A7C00DF66C3 /* ImmutableRequestTests.swift in Sources */, diff --git a/DatadogCore/Sources/Core/DatadogCore.swift b/DatadogCore/Sources/Core/DatadogCore.swift index 2d8fe768af..fc87dc451c 100644 --- a/DatadogCore/Sources/Core/DatadogCore.swift +++ b/DatadogCore/Sources/Core/DatadogCore.swift @@ -309,10 +309,6 @@ extension DatadogCore: DatadogCoreProtocol { return CoreFeatureScope(in: self) } - func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - contextProvider.write { $0.baggages[key] = baggage() } - } - func set(context: @escaping () -> Context?) where Context: AdditionalContext { contextProvider.write { $0.set(additionalContext: context()) } } @@ -382,10 +378,6 @@ internal class CoreFeatureScope: @unchecked Sendable, FeatureScope wher core?.send(message: message, else: fallback) } - func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - core?.set(baggage: baggage, forKey: key) - } - func set(context: @escaping () -> Context?) where Context: AdditionalContext { core?.set(context: context) } @@ -496,7 +488,6 @@ extension DatadogCore: Flushable { // follow our design choices around SDK core's threading. // Reset baggages that need not be persisted across flushes. - set(baggage: nil, forKey: LaunchReport.key) removeContext(ofType: LaunchReport.self) let features = features.values.compactMap { $0 as? Flushable } diff --git a/DatadogCore/Tests/Datadog/DatadogCore/DatadogCoreTests.swift b/DatadogCore/Tests/Datadog/DatadogCore/DatadogCoreTests.swift index 0a9ba8d0f7..2f6f9a7772 100644 --- a/DatadogCore/Tests/Datadog/DatadogCore/DatadogCoreTests.swift +++ b/DatadogCore/Tests/Datadog/DatadogCore/DatadogCoreTests.swift @@ -191,7 +191,7 @@ class DatadogCoreTests: XCTestCase { XCTAssertEqual(requestBuilderSpy.requestParameters.count, 1, "It should send only one request") } - func testWhenFeatureBaggageIsUpdated_thenNewValueIsImmediatellyAvailable() throws { + func testWhenFeatureAdditionalContextIsUpdated_thenNewValueIsImmediatellyAvailable() throws { // Given let core = DatadogCore( directory: temporaryCoreDirectory, @@ -212,29 +212,33 @@ class DatadogCoreTests: XCTestCase { let scope = core.scope(for: FeatureMock.self) // When + struct ContextMock: AdditionalContext { + static let key = "key" + let value: String + } let key = "key" let expectation1 = self.expectation(description: "retrieve context") let expectation2 = self.expectation(description: "retrieve context and event writer") expectation1.expectedFulfillmentCount = 2 expectation2.expectedFulfillmentCount = 2 - core.set(baggage: "baggage 1", forKey: key) + core.set(context: ContextMock(value: "value 1")) scope.context { context in - XCTAssertEqual(try! context.baggages[key]!.decode(type: String.self), "baggage 1") + XCTAssertEqual(context.additionalContext(ofType: ContextMock.self)?.value, "value 1") expectation1.fulfill() } scope.eventWriteContext { context, _ in - XCTAssertEqual(try! context.baggages[key]!.decode(type: String.self), "baggage 1") + XCTAssertEqual(context.additionalContext(ofType: ContextMock.self)?.value, "value 1") expectation2.fulfill() } - core.set(baggage: "baggage 2", forKey: key) + core.set(context: ContextMock(value: "value 1")) scope.context { context in - XCTAssertEqual(try! context.baggages[key]!.decode(type: String.self), "baggage 2") + XCTAssertEqual(context.additionalContext(ofType: ContextMock.self)?.value, "value 1") expectation1.fulfill() } scope.eventWriteContext { context, _ in - XCTAssertEqual(try! context.baggages[key]!.decode(type: String.self), "baggage 2") + XCTAssertEqual(context.additionalContext(ofType: ContextMock.self)?.value, "value 1") expectation2.fulfill() } diff --git a/DatadogCore/Tests/Datadog/RUM/TelemetryReceiverTests.swift b/DatadogCore/Tests/Datadog/RUM/TelemetryReceiverTests.swift index 5ea380150f..889b87e8f0 100644 --- a/DatadogCore/Tests/Datadog/RUM/TelemetryReceiverTests.swift +++ b/DatadogCore/Tests/Datadog/RUM/TelemetryReceiverTests.swift @@ -31,17 +31,14 @@ class TelemetryReceiverTests: XCTestCase { { core.telemetry.debug(id: .mockRandom(), message: "telemetry debug") }, { core.telemetry.error(id: .mockRandom(), message: "telemetry error", kind: "error.kind", stack: "error.stack") }, { core.telemetry.configuration(batchSize: .mockRandom()) }, - { - core.set( - baggage: [ - RUMContextAttributes.IDs.applicationID: String.mockRandom(), - RUMContextAttributes.IDs.sessionID: String.mockRandom(), - RUMContextAttributes.IDs.viewID: String.mockRandom(), - RUMContextAttributes.IDs.userActionID: String.mockRandom() - ], - forKey: "rum" + { core.set( + context: RUMCoreContext( + applicationID: .mockRandom(), + sessionID: .mockRandom(), + viewID: .mockRandom(), + userActionID: .mockRandom() ) - } + ) } ], iterations: 50 ) diff --git a/DatadogInternal/Sources/Codable/AnyDecodable.swift b/DatadogInternal/Sources/Codable/AnyDecodable.swift index ef851e58f9..6365f5e0e3 100644 --- a/DatadogInternal/Sources/Codable/AnyDecodable.swift +++ b/DatadogInternal/Sources/Codable/AnyDecodable.swift @@ -93,8 +93,6 @@ extension _AnyDecodable { self.init(double) } else if let string = try? container.decode(String.self) { self.init(string) - } else if let passthrough = container.passthrough() { - self.init(passthrough) } else if let array = try? container.decode([AnyDecodable].self) { self.init(array.map { $0.value }) } else if let dictionary = try? container.decode([String: AnyDecodable].self) { diff --git a/DatadogInternal/Sources/Codable/AnyDecoder.swift b/DatadogInternal/Sources/Codable/AnyDecoder.swift deleted file mode 100644 index 1204fdd3a2..0000000000 --- a/DatadogInternal/Sources/Codable/AnyDecoder.swift +++ /dev/null @@ -1,874 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import Foundation - -/// An object that decodes instances of a `Any` type. -/// -/// The example below shows how to decode an instance of a simple `GroceryProduct` -/// type from a `Any` object. The type adopts `Codable` so that it's decodable using a -/// `AnyDecoder` instance. -/// -/// struct GroceryProduct: Codable { -/// var name: String -/// var points: Int -/// var description: String? -/// } -/// -/// let dictionary: [String: Any] = [ -/// "name": "Durian", -/// "points": 600, -/// "description": "A fruit with a distinctive scent." -/// ] -/// -/// let decoder = AnyDecoder() -/// let product = try decoder.decode(GroceryProduct.self, from: dictionary) -/// -/// print(product.name) // Prints "Durian" -/// -open class AnyDecoder { - /// Initializes `self`. - public init() { } - - /// Decodes a top-level any value to the given type. - /// - /// - parameter type: The type of the value to decode. - /// - parameter object: The object to decode from. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.dataCorrupted` if values requested from the payload are corrupted, or if the given data is not valid JSON. - /// - throws: An error if any value throws an error during decoding. - open func decode(_ type: T.Type = T.self, from any: Any?) throws -> T where T: Decodable { - // swiftlint:disable:previous function_default_parameter_at_end - let container = _AnyDecoder.SingleValueContainer(any) - return try container.decode(T.self) - } -} - -// swiftlint:enable closing_brace_whitespace -// MARK: - Internal Decoder -private class _AnyDecoder: Decoder { - /// The path of coding keys taken to get to this point in decoding. - let codingPath: [CodingKey] - - /// The source value. - let value: Any? - - /// Any contextual information set by the user for decoding. - let userInfo: [CodingUserInfoKey: Any] = [:] - - init(_ value: Any?, path: [CodingKey] = []) { - self.value = value - codingPath = path - } - - /// Returns the data stored in this decoder as represented in a container - /// keyed by the given key type. - /// - /// - parameter type: The key type to use for the container. - /// - returns: A keyed decoding container view into this decoder. - /// - throws: `DecodingError.typeMismatch` if the encountered stored value is - /// not a keyed container. - func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { - let container = try KeyedContainer(value, path: codingPath) - return KeyedDecodingContainer(container) - } - - /// Returns the data stored in this decoder as represented in a container - /// appropriate for holding values with no keys. - /// - /// - returns: An unkeyed container view into this decoder. - /// - throws: `DecodingError.typeMismatch` if the encountered stored value is - /// not an unkeyed container. - func unkeyedContainer() throws -> UnkeyedDecodingContainer { - try UnkeyedContainer(value, path: codingPath) - } - - /// Returns the data stored in this decoder as represented in a container - /// appropriate for holding a single primitive value. - /// - /// - returns: A single value container view into this decoder. - /// - throws: `DecodingError.typeMismatch` if the encountered stored value is - /// not a single value container. - func singleValueContainer() throws -> SingleValueDecodingContainer { - SingleValueContainer(value, path: codingPath) - } - - /// A type that provides a view into an encoder's storage and is used to hold - /// the encoded properties of an encodable type in a keyed manner. - struct KeyedContainer: KeyedDecodingContainerProtocol where Key: CodingKey { - /// The path of coding keys taken to get to this point in encoding. - let codingPath: [CodingKey] - - /// The source dictionary. - let dict: [String: Any?] - - init(_ any: Any?, path: [CodingKey] = []) throws { - guard let dict = any as? [String: Any?] else { - let context = DecodingError.Context( - codingPath: path, - debugDescription: "Invalid conversion of '\(String(describing: any))' to Dictionary." - ) - - throw DecodingError.typeMismatch([String: Any?].self, context) - } - - self.dict = dict - self.codingPath = path - } - - /// All the keys the `Decoder` has for this container. - /// - /// Different keyed containers from the same `Decoder` may return different - /// keys here; it is possible to encode with multiple key types which are - /// not convertible to one another. This should report all keys present - /// which are convertible to the requested type. - var allKeys: [Key] { - dict.keys.compactMap { Key(stringValue: $0) } - } - - /// Returns a Boolean value indicating whether the decoder contains a value - /// associated with the given key. - /// - /// The value associated with `key` may be a null value as appropriate for - /// the data format. - /// - /// - parameter key: The key to search for. - /// - returns: Whether the `Decoder` has an entry for the given key. - func contains(_ key: Key) -> Bool { - dict[key.stringValue] != nil - } - - func value(forKey key: Key) throws -> Any? { - if let value = dict[key.stringValue] { - return value - } - - let context = DecodingError.Context( - codingPath: codingPath + [key], - debugDescription: "No value associated with key \(key.stringValue)." - ) - - throw DecodingError.keyNotFound(key, context) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decodeNil(forKey key: Key) throws -> Bool { - try nestedSingleValueContainer(forKey: key).decodeNil() - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: String.Type, forKey key: Key) throws -> String { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Double.Type, forKey key: Key) throws -> Double { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Float.Type, forKey key: Key) throws -> Float { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Int.Type, forKey key: Key) throws -> Int { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Decodes a value of the given type for the given key. - /// - /// - parameter type: The type of value to decode. - /// - parameter key: The key that the decoded value is associated with. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - func decode(_ type: T.Type, forKey key: Key) throws -> T where T: Decodable { - try nestedSingleValueContainer(forKey: key).decode(type) - } - - /// Returns the data stored for the given key as represented in a container - /// keyed by the given key type. - /// - /// - parameter type: The key type to use for the container. - /// - parameter key: The key that the nested container is associated with. - /// - returns: A keyed decoding container view into `self`. - func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { - let container = try KeyedContainer(value(forKey: key), path: codingPath + [key]) - return KeyedDecodingContainer(container) - } - - /// Returns the data stored for the given key as represented in an unkeyed - /// container. - /// - /// - parameter key: The key that the nested container is associated with. - /// - returns: An unkeyed decoding container view into `self`. - func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { - try UnkeyedContainer(value(forKey: key), path: codingPath + [key]) - } - - /// Returns the data stored for the given key as represented in an single value - /// container. - /// - /// - parameter key: The key that the nested container is associated with. - /// - returns: An single value decoding container view into `self`. - func nestedSingleValueContainer(forKey key: Key) throws -> SingleValueDecodingContainer { - try SingleValueContainer(value(forKey: key), path: codingPath + [key]) - } - - /// Returns a `Decoder` instance for decoding `super` from the container - /// associated with the default `super` key. - /// - /// Equivalent to calling `superDecoder(forKey:)` with - /// `Key(stringValue: "super", intValue: 0)`. - /// - /// - returns: A new `Decoder` to pass to `super.init(from:)`. - func superDecoder() throws -> Decoder { - _AnyDecoder(dict, path: codingPath) - } - - /// Returns a `Decoder` instance for decoding `super` from the container - /// associated with the given key. - /// - /// - parameter key: The key to decode `super` for. - /// - returns: A new `Decoder` to pass to `super.init(from:)`. - func superDecoder(forKey key: Key) throws -> Decoder { - try _AnyDecoder(value(forKey: key), path: codingPath + [key]) - } - } - - /// A type that provides a view into a decoder's storage and is used to hold - /// the encoded properties of a decodable type sequentially, without keys. - struct UnkeyedContainer: UnkeyedDecodingContainer { - /// The path of coding keys taken to get to this point in decoding. - let codingPath: [CodingKey] - - /// The number of elements contained within this container. - /// - /// If the number of elements is unknown, the value is `nil`. - var count: Int? { array.count } - - /// A Boolean value indicating whether there are no more elements left to be - /// decoded in the container. - var isAtEnd: Bool { currentIndex >= array.count } - - /// The current decoding index of the container (i.e. the index of the next - /// element to be decoded.) Incremented after every successful decode call. - private(set) var currentIndex: Int = 0 - - /// The source array. - private let array: [Any?] - - init(_ any: Any?, path: [CodingKey] = []) throws { - guard let array = any as? [Any?] else { - let context = DecodingError.Context( - codingPath: path, - debugDescription: "Invalid conversion of '\(String(describing: any))' to Array." - ) - - throw DecodingError.typeMismatch([Any?].self, context) - } - - self.array = array - self.codingPath = path - } - - /// Decodes a null value. - /// - /// If the value is not null, does not increment currentIndex. - /// - /// - returns: Whether the encountered value was null. - mutating func decodeNil() throws -> Bool { - if try nestedSingleValueContainer().decodeNil() { - return true - } - - currentIndex -= 1 - return false - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Bool.Type) throws -> Bool { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: String.Type) throws -> String { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Double.Type) throws -> Double { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Float.Type) throws -> Float { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Int.Type) throws -> Int { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Int8.Type) throws -> Int8 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Int16.Type) throws -> Int16 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Int32.Type) throws -> Int32 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: Int64.Type) throws -> Int64 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: UInt.Type) throws -> UInt { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: UInt8.Type) throws -> UInt8 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: UInt16.Type) throws -> UInt16 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: UInt32.Type) throws -> UInt32 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: UInt64.Type) throws -> UInt64 { - try nestedSingleValueContainer().decode(type) - } - - /// Decodes a value of the given type. - /// - /// - parameter type: The type of value to decode. - /// - returns: A value of the requested type, if present for the given key - /// and convertible to the requested type. - mutating func decode(_ type: T.Type) throws -> T where T: Decodable { - try nestedSingleValueContainer().decode(type) - } - - private mutating func next() throws -> Any? { - defer { currentIndex += 1 } - - if isAtEnd { - let context = DecodingError.Context( - codingPath: codingPath, - debugDescription: "Unkeyed container is at end." - ) - - throw DecodingError.valueNotFound(Any.self, context) - } - - return array[currentIndex] - } - - /// Decodes a nested container keyed by the given type. - /// - /// - parameter type: The key type to use for the container. - /// - returns: A keyed decoding container view into `self`. - mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { - let container = try KeyedContainer(next(), path: codingPath) - return KeyedDecodingContainer(container) - } - - /// Decodes an unkeyed nested container. - /// - /// - returns: An unkeyed decoding container view into `self`. - mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { - try UnkeyedContainer(next(), path: codingPath) - } - - /// Decodes an single value nested container. - /// - /// - returns: An unkeyed decoding container view into `self`. - mutating func nestedSingleValueContainer() throws -> SingleValueDecodingContainer { - try SingleValueContainer(next(), path: codingPath) - } - - /// Decodes a nested container and returns a `Decoder` instance for decoding - /// `super` from that container. - /// - /// - returns: A new `Decoder` to pass to `super.init(from:)`. - mutating func superDecoder() throws -> Decoder { - _AnyDecoder(array, path: codingPath) - } - } - - /// A container that can support the storage and direct decoding of a single - /// nonkeyed value. - struct SingleValueContainer: SingleValueDecodingContainer { - /// The path of coding keys taken to get to this point in encoding. - let codingPath: [CodingKey] - - let value: Any? - - init(_ value: Any?, path: [CodingKey] = []) { - self.value = value - self.codingPath = path - } - - /// Decodes a null value. - /// - /// - returns: Whether the encountered value was null. - func decodeNil() -> Bool { - value == nil - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Bool.Type) throws -> Bool { - guard let value = value as? Bool else { - throw DecodingError.typeMismatch(type, in: self) - } - return value - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: String.Type) throws -> String { - guard let value = value as? String else { - throw DecodingError.typeMismatch(type, in: self) - } - return value - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Double.Type) throws -> Double { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Float.Type) throws -> Float { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Int.Type) throws -> Int { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Int8.Type) throws -> Int8 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Int16.Type) throws -> Int16 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Int32.Type) throws -> Int32 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: Int64.Type) throws -> Int64 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: UInt.Type) throws -> UInt { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: UInt8.Type) throws -> UInt8 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: UInt16.Type) throws -> UInt16 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: UInt32.Type) throws -> UInt32 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: UInt64.Type) throws -> UInt64 { - try value(as: type) - } - - /// Decodes a single value of the given type. - /// - /// - parameter type: The type to decode as. - /// - returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - func decode(_ type: T.Type) throws -> T where T: Decodable { - if let value = value as? T { - return value - } - - let decoder = _AnyDecoder(value, path: codingPath) - return try T(from: decoder) - } - - /// Converts value to any `BinaryInteger`. - /// - /// - Parameter type: The `BinaryInteger` to convert as. - /// - Returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - private func value(as type: T.Type) throws -> T where T: BinaryInteger { - var value: T? - switch self.value { - case let source as T: return source - case let source as Int: value = T(exactly: source) - case let source as Int8: value = T(exactly: source) - case let source as Int16: value = T(exactly: source) - case let source as Int32: value = T(exactly: source) - case let source as Int64: value = T(exactly: source) - case let source as UInt: value = T(exactly: source) - case let source as UInt8: value = T(exactly: source) - case let source as UInt16: value = T(exactly: source) - case let source as UInt32: value = T(exactly: source) - case let source as UInt64: value = T(exactly: source) - default: break - } - - guard let value = value else { - throw DecodingError.typeMismatch(type, in: self) - } - - return value - } - - /// Converts value to any `BinaryFloatingPoint`. - /// - /// - Parameter type: The `BinaryFloatingPoint` to convert as. - /// - Returns: A value of the requested type. - /// - throws: `DecodingError.typeMismatch` if the value conversion - /// fails. - private func value(as type: T.Type) throws -> T where T: BinaryFloatingPoint { - if let source = value as? T { - return source - } - - if let source = value as? Double { - return T(source) - } - - if let source = value as? Float { - return T(source) - } - - if let source = try? value(as: Int.self) { - return T(source) - } - - throw DecodingError.typeMismatch(type, in: self) - } - } -} - -private extension DecodingError { - /// Returns a new `.typeMismatch` error using a constructed coding path and - /// the given container. - /// - /// The coding path for the returned error is the given container's coding - /// path. - /// - /// - param container: The container in which the corrupted data was - /// accessed. - /// - param debugDescription: A description of the error to aid in debugging. - /// - /// - Returns: A new `.typeMismatch` error with the given information. - static func typeMismatch(_ type: Any.Type, in container: _AnyDecoder.SingleValueContainer) -> DecodingError { - let context = DecodingError.Context( - codingPath: container.codingPath, - debugDescription: "Invalid conversion of '\(String(describing: container.value))' to \(type)." - ) - - return .typeMismatch(type, context) - } -} - -extension SingleValueDecodingContainer { - /// Decodes a passthrough value of the given type. - /// - /// This method can succeed only when using `AnyDecoder`. - /// - /// - returns: A passthrough value if any. - /// - throws: `DecodingError.typeMismatch` if the value was not passthrough. - func passthrough() -> PassthroughAnyCodable? { - guard let container = self as? _AnyDecoder.SingleValueContainer else { - return nil - } - - return container.value as? PassthroughAnyCodable - } -} diff --git a/DatadogInternal/Sources/Codable/AnyEncoder.swift b/DatadogInternal/Sources/Codable/AnyEncoder.swift deleted file mode 100644 index 8cb0e61e18..0000000000 --- a/DatadogInternal/Sources/Codable/AnyEncoder.swift +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import Foundation - -/// An object that encodes instances of an `Encodable` type as `Any?`. -/// -/// The example below shows how to encode an instance of a simple `GroceryProduct` -/// type to `Any` object. The type adopts `Codable` so that it's encodable as `Any` -/// using a `AnyEncoder` instance. -/// -/// struct GroceryProduct: Codable { -/// var name: String -/// var points: Int -/// var description: String? -/// } -/// -/// let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.") -/// -/// let encoder = AnyEncoder() -/// -/// let object = try encoder.encode(pear) -/// print(object as! NSDictionary) -/// -/// /* Prints: -/// { -/// description = "A ripe pear."; -/// name = Pear; -/// points = 250; -/// } -/// */ -open class AnyEncoder { - /// Initializes `self`. - public init() { } - - /// Encodes the given top-level value and returns its Any representation. - /// - /// Depending on the value and its `Encodable` implementation the returned - /// encoded value can be `Any`, `[Any?]`, `[String: Any?]`, or `nil`. - /// - /// - parameter value: The value to encode. - /// - returns: An `Any` object containing the value. - /// - throws: An error if any value throws an error during encoding. - open func encode(_ value: T) throws -> Any? where T: Encodable { - let encoder = _AnyEncoder() - try value.encode(to: encoder) - return encoder.any - } -} - -/// A type that can encode values into a native format for external -/// representation. -private class _AnyEncoder: Encoder { - typealias AnyEncodingStorage = (Any?) -> Void - - /// The path of coding keys taken to get to this point in encoding. - let codingPath: [CodingKey] - - /// Any contextual information set by the user for encoding. - let userInfo: [CodingUserInfoKey: Any] = [:] - - /// The encoded value. - var any: Any? - - init(path: [CodingKey] = []) { - codingPath = path - } - - /// Returns an encoding container appropriate for holding multiple values - /// keyed by the given key type. - /// - /// You must use only one kind of top-level encoding container. This method - /// must not be called after a call to `unkeyedContainer()` or after - /// encoding a value through a call to `singleValueContainer()` - /// - /// - parameter type: The key type to use for the container. - /// - returns: A new keyed encoding container. - func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { - let container = KeyedContainer( - store: { self.any = $0 }, - dictionary: any as? [String: Any?], - path: codingPath - ) - self.any = container.dictionary - return KeyedEncodingContainer(container) - } - - /// Returns an encoding container appropriate for holding multiple unkeyed - /// values. - /// - /// You must use only one kind of top-level encoding container. This method - /// must not be called after a call to `container(keyedBy:)` or after - /// encoding a value through a call to `singleValueContainer()` - /// - /// - returns: A new empty unkeyed container. - func unkeyedContainer() -> UnkeyedEncodingContainer { - let container = UnkeyedContainer( - store: { self.any = $0 }, - array: any as? [Any?], - path: codingPath - ) - self.any = container.array - return container - } - - /// Returns an encoding container appropriate for holding a single primitive - /// value. - /// - /// You must use only one kind of top-level encoding container. This method - /// must not be called after a call to `unkeyedContainer()` or - /// `container(keyedBy:)`, or after encoding a value through a call to - /// `singleValueContainer()` - /// - /// - returns: A new empty single value container. - func singleValueContainer() -> SingleValueEncodingContainer { - SingleValueContainer( - store: { self.any = $0 }, - path: codingPath - ) - } - - /// A concrete container that provides a view into an encoder's storage, making - /// the encoded properties of an encodable type accessible by keys. - class KeyedContainer: KeyedEncodingContainerProtocol where Key: CodingKey { - /// The path of coding keys taken to get to this point in encoding. - var codingPath: [CodingKey] - - /// The dictionary of encoded value. - var dictionary: [String: Any?] - - /// The storage closure to call with encoded value. - let store: AnyEncodingStorage - - /// Creates a keyed container for encoding an `Encodable` object to - /// a dictionary of `[String: Any?]`. - /// - /// - Parameters: - /// - store: The storage closure to call with encoded value. - /// - dictionary: An existing dictionary of any. - /// - path: The path of coding keys taken to get to this point in encoding. - init( - store: @escaping AnyEncodingStorage, - dictionary: [String: Any?]? = nil, - path: [CodingKey] = [] - ) { - self.store = store - self.dictionary = dictionary ?? [:] - self.codingPath = path - } - - /// Encodes a null value for the given key. - /// - /// - parameter key: The key to associate the value with. - func encodeNil(forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encodeNil() - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Bool, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: String, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Double, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Float, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Int, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Int8, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Int16, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Int32, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: Int64, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: UInt, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: UInt8, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: UInt16, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: UInt32, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: UInt64, forKey key: Key) throws { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Encodes the given value for the given key. - /// - /// - parameter value: The value to encode. - /// - parameter key: The key to associate the value with. - func encode(_ value: T, forKey key: Key) throws where T: Encodable { - try nestedSingleValueContainer(forKey: key).encode(value) - } - - /// Stores a keyed encoding container for the given key and returns it. - /// - /// - parameter keyType: The key type to use for the container. - /// - parameter key: The key to encode the container for. - /// - returns: A new keyed encoding container. - func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer where NestedKey: CodingKey { - let container = KeyedContainer( - store: { self.set($0, forKey: key) }, - path: codingPath + [key] - ) - return KeyedEncodingContainer(container) - } - - /// Stores an unkeyed encoding container for the given key and returns it. - /// - /// - parameter key: The key to encode the container for. - /// - returns: A new unkeyed encoding container. - func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { - UnkeyedContainer( - store: { self.set($0, forKey: key) }, - path: codingPath + [key] - ) - } - - /// Stores an single value encoding container for the given key and returns it. - /// - /// - parameter key: The key to encode the container for. - /// - returns: A new unkeyed encoding container. - func nestedSingleValueContainer(forKey key: Key) -> SingleValueContainer { - SingleValueContainer( - store: { self.set($0, forKey: key) }, - path: codingPath + [key] - ) - } - - /// Set the encoded value at the given key. - /// - /// - Parameters: - /// - any: The encoded value. - /// - key: The key to encode the value for. - private func set(_ any: Any?, forKey key: Key) { - dictionary[key.stringValue] = any - store(dictionary) - } - - /// Stores a new nested container for the default `super` key and returns a - /// new encoder instance for encoding `super` into that container. - /// - /// Equivalent to calling `superEncoder(forKey:)` with - /// `Key(stringValue: "super", intValue: 0)`. - /// - /// - returns: A new encoder to pass to `super.encode(to:)`. - func superEncoder() -> Encoder { - _AnyEncoder(path: codingPath) - } - - /// Stores a new nested container for the given key and returns a new encoder - /// instance for encoding `super` into that container. - /// - /// - parameter key: The key to encode `super` for. - /// - returns: A new encoder to pass to `super.encode(to:)`. - func superEncoder(forKey key: Key) -> Encoder { - _AnyEncoder(path: codingPath + [key]) - } - } - - /// A type that provides a view into an encoder's storage and is used to hold - /// the encoded properties of an encodable type sequentially, without keys. - class UnkeyedContainer: UnkeyedEncodingContainer { - /// The path of coding keys taken to get to this point in encoding. - let codingPath: [CodingKey] - - /// The number of elements encoded into the container. - var count: Int { array.count } - - /// The array of encoded value. - var array: [Any?] - - /// The storage closure to call with encoded value. - let store: AnyEncodingStorage - - /// Creates a unkeyed container for encoding an `Encodable` object to - /// an array of `[Any?]`. - /// - /// - Parameters: - /// - store: The storage closure to call with encoded value. - /// - array: An existing array of any. - /// - path: The path of coding keys taken to get to this point in encoding. - init( - store: @escaping AnyEncodingStorage, - array: [Any?]? = nil, - path: [CodingKey] = [] - ) { - self.store = store - self.array = array ?? [] - self.codingPath = path - } - - /// Encodes a null value. - func encodeNil() throws { - try nestedSingleValueContainer().encodeNil() - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Bool) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: String) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Double) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Float) throws { - try nestedSingleValueContainer().encode(value) - } - - func encode(_ value: Int) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int8) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int16) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int32) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int64) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt8) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt16) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt32) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt64) throws { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes the given value. - /// - /// - parameter value: The value to encode. - func encode(_ value: T) throws where T: Encodable { - try nestedSingleValueContainer().encode(value) - } - - /// Encodes a nested container keyed by the given type and returns it. - /// - /// - parameter keyType: The key type to use for the container. - /// - returns: A new keyed encoding container. - func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer where NestedKey: CodingKey { - let container = KeyedContainer(store: append, path: codingPath) - return KeyedEncodingContainer(container) - } - - /// Encodes an unkeyed encoding container and returns it. - /// - /// - returns: A new unkeyed encoding container. - func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { - UnkeyedContainer(store: append, path: codingPath) - } - - /// Encodes an single value encoding container and returns it. - /// - /// - returns: A new unkeyed encoding container. - func nestedSingleValueContainer() -> SingleValueContainer { - SingleValueContainer(store: append, path: codingPath) - } - - /// Encodes a nested container and returns an `Encoder` instance for encoding - /// `super` into that container. - /// - /// - returns: A new encoder to pass to `super.encode(to:)`. - func superEncoder() -> Encoder { - _AnyEncoder(path: codingPath) - } - - private func append(_ any: Any?) { - array.append(any) - store(array) - } - } - - /// A container that can support the storage and direct encoding of a single - /// non-keyed value. - struct SingleValueContainer: SingleValueEncodingContainer { - /// The path of coding keys taken to get to this point in encoding. - let codingPath: [CodingKey] - - /// The storage closure to call with encoded value. - let store: AnyEncodingStorage - - /// Creates a single value container for encoding an `Encodable` object to - /// `Any?`. - /// - /// - Parameters: - /// - store: The storage closure to call with encoded value. - /// - path: The path of coding keys taken to get to this point in encoding. - init( - store: @escaping AnyEncodingStorage, - path: [CodingKey] = [] - ) { - self.store = store - self.codingPath = path - } - - /// Encodes a null value. - func encodeNil() throws { - store(nil) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Bool) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: String) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Double) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Float) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int8) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int16) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int32) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: Int64) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt8) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt16) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt32) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: UInt64) throws { - store(value) - } - - /// Encodes a single value of the given type. - /// - /// - parameter value: The value to encode. - func encode(_ value: T) throws where T: Encodable { - if value is PassthroughAnyCodable { - store(value) - } else { - let encoder = _AnyEncoder(path: codingPath) - try value.encode(to: encoder) - store(encoder.any) - } - } - } -} - -/// A passthrough object will skip encoding when using the ``AnyEncoder``. -/// The object will be stored as-is in the returned `Any?` container. -/// -/// Making an `Encodable` as passthrough allow to bypass encoding when the type is -/// known by multiple parties. -/// -/// When decoding an object using the ``AnyDecoder``, the decoder will -/// attempt to cast the object to the expected type, a `DecodingError.typeMismatch` -/// error is raised in case of failure. -public protocol PassthroughAnyCodable { } - -extension URL: PassthroughAnyCodable { } -extension Date: PassthroughAnyCodable { } -extension UUID: PassthroughAnyCodable { } -extension Data: PassthroughAnyCodable { } diff --git a/DatadogInternal/Sources/Context/AppState.swift b/DatadogInternal/Sources/Context/AppState.swift index 271d257eab..d56f840aae 100644 --- a/DatadogInternal/Sources/Context/AppState.swift +++ b/DatadogInternal/Sources/Context/AppState.swift @@ -16,7 +16,7 @@ public protocol AppStateProvider: Sendable { } /// Application state. -public enum AppState: Codable, PassthroughAnyCodable { +public enum AppState: Codable { /// The app is running in the foreground and currently receiving events. case active /// The app is running in the foreground but is not receiving events. @@ -39,7 +39,7 @@ public enum AppState: Codable, PassthroughAnyCodable { } /// A data structure to represent recorded app states in a given period of time -public struct AppStateHistory: Codable, Equatable, PassthroughAnyCodable { +public struct AppStateHistory: Codable, Equatable { /// Snapshot of the app state at `date` public struct Snapshot: Codable, Equatable { /// The app state at this `date`. diff --git a/DatadogInternal/Sources/Context/BatteryStatus.swift b/DatadogInternal/Sources/Context/BatteryStatus.swift index a26e4592de..cb22f59ee4 100644 --- a/DatadogInternal/Sources/Context/BatteryStatus.swift +++ b/DatadogInternal/Sources/Context/BatteryStatus.swift @@ -7,7 +7,7 @@ import Foundation /// Describe the battery state for mobile devices. -public struct BatteryStatus: Codable, Equatable, PassthroughAnyCodable { +public struct BatteryStatus: Codable, Equatable { public enum State: Codable { case unknown case unplugged diff --git a/DatadogInternal/Sources/Context/CarrierInfo.swift b/DatadogInternal/Sources/Context/CarrierInfo.swift index 9e6164f7f0..0e5dbfb48f 100644 --- a/DatadogInternal/Sources/Context/CarrierInfo.swift +++ b/DatadogInternal/Sources/Context/CarrierInfo.swift @@ -7,7 +7,7 @@ import Foundation /// Carrier details specific to cellular radio access. -public struct CarrierInfo: Codable, Equatable, PassthroughAnyCodable { +public struct CarrierInfo: Codable, Equatable { // swiftlint:disable identifier_name public enum RadioAccessTechnology: String, Codable, CaseIterable { case GPRS diff --git a/DatadogInternal/Sources/Context/DatadogContext.swift b/DatadogInternal/Sources/Context/DatadogContext.swift index 22eba8d87d..607f2a7f49 100644 --- a/DatadogInternal/Sources/Context/DatadogContext.swift +++ b/DatadogInternal/Sources/Context/DatadogContext.swift @@ -110,10 +110,6 @@ public struct DatadogContext { /// Additional context that can set from `core` instance. private var additionalContext: [String: AdditionalContext] = [:] - /// Type-less context baggages. - @available(*, deprecated, renamed: "additionalContext", message: "`FeatureBaggage` is deprecated in favor of strongly typed `additionalContext`.") - public var baggages: [String: FeatureBaggage] = [:] - // swiftlint:disable function_default_parameter_at_end public init( site: DatadogSite, @@ -142,8 +138,7 @@ public struct DatadogContext { carrierInfo: CarrierInfo? = nil, batteryStatus: BatteryStatus? = nil, isLowPowerModeEnabled: Bool = false, - additionalContext: [String: AdditionalContext] = [:], - baggages: [String: FeatureBaggage] = [:] + additionalContext: [String: AdditionalContext] = [:] ) { self.site = site self.clientToken = clientToken @@ -172,7 +167,6 @@ public struct DatadogContext { self.batteryStatus = batteryStatus self.isLowPowerModeEnabled = isLowPowerModeEnabled self.additionalContext = additionalContext - self.baggages = baggages } // swiftlint:enable function_default_parameter_at_end } diff --git a/DatadogInternal/Sources/Context/DeviceInfo.swift b/DatadogInternal/Sources/Context/DeviceInfo.swift index 9dd865b880..912f520353 100644 --- a/DatadogInternal/Sources/Context/DeviceInfo.swift +++ b/DatadogInternal/Sources/Context/DeviceInfo.swift @@ -7,9 +7,9 @@ import Foundation /// Describes current device information. -public struct DeviceInfo: Codable, Equatable, PassthroughAnyCodable { +public struct DeviceInfo: Codable, Equatable { /// Represents the type of device. - public enum DeviceType: Codable, Equatable, PassthroughAnyCodable { + public enum DeviceType: Codable, Equatable { case iPhone case iPod case iPad diff --git a/DatadogInternal/Sources/Context/LaunchTime.swift b/DatadogInternal/Sources/Context/LaunchTime.swift index 069441fd73..8bc0252a95 100644 --- a/DatadogInternal/Sources/Context/LaunchTime.swift +++ b/DatadogInternal/Sources/Context/LaunchTime.swift @@ -7,7 +7,7 @@ import Foundation /// Provides the application launch time. -public struct LaunchTime: Codable, Equatable, PassthroughAnyCodable { +public struct LaunchTime: Codable, Equatable { /// The app process launch duration (in seconds) measured as the time from process start time /// to receiving `UIApplication.didBecomeActiveNotification` notification. /// diff --git a/DatadogInternal/Sources/Context/NetworkConnectionInfo.swift b/DatadogInternal/Sources/Context/NetworkConnectionInfo.swift index 1f2bb55b91..3da45ddcd8 100644 --- a/DatadogInternal/Sources/Context/NetworkConnectionInfo.swift +++ b/DatadogInternal/Sources/Context/NetworkConnectionInfo.swift @@ -7,7 +7,7 @@ import Foundation /// Network connection details. -public struct NetworkConnectionInfo: Codable, Equatable, PassthroughAnyCodable { +public struct NetworkConnectionInfo: Codable, Equatable { /// Tells if network is reachable. public enum Reachability: String, Codable, CaseIterable { /// The network is reachable. diff --git a/DatadogInternal/Sources/Context/TrackingConsent.swift b/DatadogInternal/Sources/Context/TrackingConsent.swift index a9c5aff8ad..ed168e61c0 100644 --- a/DatadogInternal/Sources/Context/TrackingConsent.swift +++ b/DatadogInternal/Sources/Context/TrackingConsent.swift @@ -10,7 +10,7 @@ import Foundation /// /// This value should be used to grant the permission for Datadog SDK to store data collected in /// Logging, Tracing or RUM and upload it to Datadog servers. -public enum TrackingConsent: Codable, PassthroughAnyCodable { +public enum TrackingConsent: Codable { /// The permission to persist and send data to the Datadog servers was granted. /// Any previously stored pending data will be marked as ready for sent. case granted diff --git a/DatadogInternal/Sources/Context/UserInfo.swift b/DatadogInternal/Sources/Context/UserInfo.swift index d638b9a9cc..d0e783029a 100644 --- a/DatadogInternal/Sources/Context/UserInfo.swift +++ b/DatadogInternal/Sources/Context/UserInfo.swift @@ -6,7 +6,7 @@ import Foundation -public struct UserInfo: Codable, PassthroughAnyCodable { +public struct UserInfo: Codable { /// User anonymous ID, if configured. public var anonymousId: String? /// User ID, if any. diff --git a/DatadogInternal/Sources/DatadogCoreProtocol.swift b/DatadogInternal/Sources/DatadogCoreProtocol.swift index 611a89493a..34a971e7c5 100644 --- a/DatadogInternal/Sources/DatadogCoreProtocol.swift +++ b/DatadogInternal/Sources/DatadogCoreProtocol.swift @@ -11,7 +11,7 @@ import Foundation /// /// Any reference to `DatadogCoreProtocol` must be captured as `weak` within a Feature. This is to avoid /// retain cycle of core holding the Feature and vice-versa. -public protocol DatadogCoreProtocol: AnyObject, MessageSending, AdditionalContextSharing, BaggageSharing, Storage { +public protocol DatadogCoreProtocol: AnyObject, MessageSending, AdditionalContextSharing, Storage { // Remove `DatadogCoreProtocol` conformance to `MessageSending` and `BaggageSharing` once // all features are migrated to depend on `FeatureScope` interface. @@ -87,40 +87,6 @@ extension MessageSending { } } -@available(*, deprecated, message: "FeatureBaggage has performance implications and will be removed.") -public protocol BaggageSharing { - /// Sets given baggage for a given Feature for sharing data through `DatadogContext`. - /// - /// This method provides a passive communication chanel between Features of the Core. - /// For an active Feature-to-Feature communication, please use the `send(message:)` - /// method. - /// - /// Setting baggages will update the Core Context that is shared across Features. - /// In the following examples, the Feature `foo` will set an value and a second - /// Feature `bar` will read it through the event write context. - /// - /// // Foo.swift - /// core.set(baggage: { .init("value") }, forKey: "key") - /// - /// // Bar.swift - /// core.scope(for: "bar").eventWriteContext { context, writer in - /// if let baggage = context.baggages["key"] { - /// do { - /// // Try decoding context to expected type: - /// let value: String = try baggage.decode() - /// // If success, handle the `value`. - /// } catch { - /// // Otherwise, handle the error (e.g. consider sending as telemetry). - /// } - /// } - /// } - /// - /// - Parameters: - /// - baggage: The Feature's baggage to set. - /// - key: The baggage's key. - func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) -} - public protocol AdditionalContextSharing { /// Sets additional context for sharing data through `DatadogContext`. /// @@ -201,108 +167,6 @@ extension AdditionalContextSharing { } } -@available(*, deprecated, message: "FeatureBaggage has performance implications and will be removed.") -extension BaggageSharing { - /// Sets given baggage for a given Feature for sharing data through `DatadogContext`. - /// - /// This method provides a passive communication chanel between Features of the Core. - /// For an active Feature-to-Feature communication, please use the `send(message:)` - /// method. - /// - /// Setting baggages will update the Core Context that is shared across Features. - /// In the following examples, the Feature `foo` will set an value and a second - /// Feature `bar` will read it through the event write context. - /// - /// // Foo.swift - /// core.set(baggage: FeatureBaggage("value"), forKey: "key") - /// - /// // Bar.swift - /// core.scope(for: "bar").eventWriteContext { context, writer in - /// if let baggage = context.baggages["key"] { - /// try { - /// // Try decoding context to expected type: - /// let value: String = try baggage.decode() - /// // If success, handle the `value`. - /// } catch { - /// // Otherwise, handle the error (e.g. consider sending as telemetry). - /// } - /// } - /// } - /// - /// - Parameters: - /// - baggage: The Feature's baggage to set. - /// - label: The baggage's label. - public func set(baggage: FeatureBaggage?, forKey key: String) { - self.set(baggage: { baggage }, forKey: key) - } - - /// Sets given baggage for a given Feature for sharing data through `DatadogContext`. - /// - /// This method provides a passive communication chanel between Features of the Core. - /// For an active Feature-to-Feature communication, please use the `send(message:)` - /// method. - /// - /// Setting baggages will update the Core Context that is shared across Features. - /// In the following examples, the Feature `foo` will set an value and a second - /// Feature `bar` will read it through the event write context. - /// - /// // Foo.swift - /// core.set(baggage: "value", forKey: "key") - /// - /// // Bar.swift - /// core.scope(for: "bar").eventWriteContext { context, writer in - /// if let baggage = context.baggages["key"] { - /// try { - /// // Try decoding context to expected type: - /// let value: String = try baggage.decode() - /// // If success, handle the `value`. - /// } catch { - /// // Otherwise, handle the error (e.g. consider sending as telemetry). - /// } - /// } - /// } - /// - /// - Parameters: - /// - baggage: The Feature's baggage to set. - /// - label: The baggage's label. - public func set(baggage: Baggage?, forKey key: String) where Baggage: Encodable { - self.set(baggage: { baggage }, forKey: key) - } - - /// Sets given baggage for a given Feature for sharing data through `DatadogContext`. - /// - /// This method provides a passive communication chanel between Features of the Core. - /// For an active Feature-to-Feature communication, please use the `send(message:)` - /// method. - /// - /// Setting baggages will update the Core Context that is shared across Features. - /// In the following examples, the Feature `foo` will set an value and a second - /// Feature `bar` will read it through the event write context. - /// - /// // Foo.swift - /// core.set(baggage: { "value" }, forKey: "key") - /// - /// // Bar.swift - /// core.scope(for: "bar").eventWriteContext { context, writer in - /// if let baggage = context.baggages["key"] { - /// try { - /// // Try decoding context to expected type: - /// let value: String = try baggage.decode() - /// // If success, handle the `value`. - /// } catch { - /// // Otherwise, handle the error (e.g. consider sending as telemetry). - /// } - /// } - /// } - /// - /// - Parameters: - /// - baggage: The Feature's baggage to set. - /// - label: The baggage's label. - public func set(baggage: @escaping () -> Baggage?, forKey key: String) where Baggage: Encodable { - self.set(baggage: { baggage().map(FeatureBaggage.init) }, forKey: key) - } -} - /// Provides ability to set or clear the anonymous identifier needed for session linking. public protocol AnonymousIdentifierManaging { /// Sets the anonymous identifier. @@ -311,7 +175,7 @@ public protocol AnonymousIdentifierManaging { } /// Feature scope provides a context and a writer to build a record event. -public protocol FeatureScope: MessageSending, AdditionalContextSharing, BaggageSharing, AnonymousIdentifierManaging, Sendable { +public protocol FeatureScope: MessageSending, AdditionalContextSharing, AnonymousIdentifierManaging, Sendable { /// Retrieve the core context and event writer. /// /// The Feature scope provides the current Datadog context and event writer for building and recording events. @@ -393,9 +257,6 @@ public class NOPDatadogCore: DatadogCoreProtocol { /// no-op public func scope(for featureType: T.Type) -> FeatureScope { NOPFeatureScope() } /// no-op - @available(*, deprecated, message: "FeatureBaggage has performance implications and will be removed.") - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { } - /// no-op public func set(context: @escaping () -> Context?) where Context: AdditionalContext { } /// no-op public func send(message: FeatureMessage, else fallback: @escaping () -> Void) { } @@ -416,9 +277,6 @@ public struct NOPFeatureScope: FeatureScope { /// no-op public func send(message: FeatureMessage, else fallback: @escaping () -> Void) { } /// no-op - @available(*, deprecated, message: "FeatureBaggage has performance implications and will be removed.") - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { } - /// no-op public func set(context: @escaping () -> Context?) where Context: AdditionalContext { } /// no-op public func set(anonymousId: String?) { } diff --git a/DatadogInternal/Sources/MessageBus/FeatureBaggage.swift b/DatadogInternal/Sources/MessageBus/FeatureBaggage.swift deleted file mode 100644 index b4627b2a93..0000000000 --- a/DatadogInternal/Sources/MessageBus/FeatureBaggage.swift +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import Foundation - -/// A `FeatureBaggage` holds any codable value. -/// -/// Values are uniquely identified by key as `String`, the value type is validated on `get` -/// either explicity, when specified, or inferred. -/// -/// ## Creates a Feature Baggage -/// Create a baggage by providing an `Encodable` value. -/// -/// The example below shows how to create a baggage from an instance of a simple `GroceryProduct`: -/// -/// struct GroceryProduct: Encodable { -/// var name: String -/// var points: Int -/// var description: String? -/// } -/// -/// let pear = GroceryProduct(name: "Pear", points: 250, description: "A ripe pear.") -/// let baggage = FeatureBaggage(pear) -/// -/// The `pear` is stored as a dictionary within the baggage: -/// -/// print(baggage.rawValue) -/// // ["description": Optional("A ripe pear."), "points": Optional(250), "name": Optional("Pear")] -/// -/// ## Accessing Value -/// The baggage value can then be decoded to any type that follow the same schema. -/// -/// The following example decodes the baggage into a new data type: -/// -/// struct CartItem: Decodable { -/// var name: String -/// var points: Int -/// } -/// -/// let item: CartItem = try baggage.decode() -/// -/// print(item) -/// // CartItem(name: "Pear", points: 250) -/// -/// A Feature Baggage does not ensure thread-safety of values that holds references, make -/// sure that any value can be accessibe from any thread. -@available(*, deprecated, message: "FeatureBaggage has performance implications and will be removed.") -public final class FeatureBaggage { - /// The raw value contained in the baggage. - @ReadWriteLock - private var rawValue: Any? - - /// The underlying encoding process. - private let _encode: () throws -> Any? - - /// Creates an instance initialized with the given encodable. - public init(_ value: Value) where Value: Encodable { - let encoder = AnyEncoder() - self._encode = { try encoder.encode(value) } - } - - /// Encodes the baggage value to `Any?` - /// - /// - Returns: The encoded baggage value. - public func encode() throws -> Any? { - // lazily encode to save from encoding - // if the value is never decoded. - if let rawValue = self.rawValue { - return rawValue - } - let rawValue = try _encode() - self.rawValue = rawValue - return rawValue - } - - /// Decodes the value stored in the baggage. - /// - /// - Parameters: - /// - type: The expected value type. - /// - Returns: The decoded baggage. - public func decode(type: Value.Type = Value.self) throws -> Value where Value: Decodable { - let decoder = AnyDecoder() - return try decoder.decode(from: encode()) - } -} diff --git a/DatadogInternal/Sources/Utils/DDError.swift b/DatadogInternal/Sources/Utils/DDError.swift index ca40d8a63f..dcd510b02c 100644 --- a/DatadogInternal/Sources/Utils/DDError.swift +++ b/DatadogInternal/Sources/Utils/DDError.swift @@ -7,7 +7,7 @@ import Foundation /// Common representation of Swift `Error` used by different features. -public struct DDError: Equatable, Codable, PassthroughAnyCodable { +public struct DDError: Equatable, Codable { /// Common error key encoding threads information in Crash Reporting. /// See "RFC - iOS Crash Reports Minimization" for more context. public static let threads = "error.threads" diff --git a/DatadogInternal/Tests/Codable/AnyCoderTests.swift b/DatadogInternal/Tests/Codable/AnyCoderTests.swift deleted file mode 100644 index 08365e19a9..0000000000 --- a/DatadogInternal/Tests/Codable/AnyCoderTests.swift +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import XCTest -import TestUtilities - -@testable import DatadogInternal - -private struct CodableObject: Codable, Equatable { - let id: UUID - let date: Date - let url: URL - let string: String - let null: String? - let integer: Int - let float: Float - let nested: Nested - let empty: Empty - let array: [Nested] - - struct Empty: Codable, Equatable { } - - struct Nested: Codable, Equatable { - let id: UUID - let string: String - } -} - -class AnyCoderTests: XCTestCase { - func testEncodingDecoding() throws { - let encoder = AnyEncoder() - let decoder = AnyDecoder() - - // Given - let expected: CodableObject = .mockRandom() - - // When - let any = try encoder.encode(expected) - let actual: CodableObject = try decoder.decode(from: any) - - // Then - XCTAssertEqual(actual, expected) - } - - func testSingleValueEncoding() throws { - let encoder = AnyEncoder() - XCTAssertTrue(try encoder.encode(true) is Bool) - XCTAssertTrue(try encoder.encode("str") is String) - XCTAssertTrue(try encoder.encode(Int(1)) is Int) - XCTAssertTrue(try encoder.encode(Int8(1)) is Int8) - XCTAssertTrue(try encoder.encode(Int16(1)) is Int16) - XCTAssertTrue(try encoder.encode(Int32(1)) is Int32) - XCTAssertTrue(try encoder.encode(Int64(1)) is Int64) - XCTAssertTrue(try encoder.encode(UInt(1)) is UInt) - XCTAssertTrue(try encoder.encode(UInt8(1)) is UInt8) - XCTAssertTrue(try encoder.encode(UInt16(1)) is UInt16) - XCTAssertTrue(try encoder.encode(UInt32(1)) is UInt32) - XCTAssertTrue(try encoder.encode(UInt64(1)) is UInt64) - XCTAssertTrue(try encoder.encode(Float(1.1)) is Float) - XCTAssertTrue(try encoder.encode(Double(1.1)) is Double) - } - - func testSingleValueDecoding() throws { - let decoder = AnyDecoder() - XCTAssertTrue(try decoder.decode(Bool.self, from: true)) - XCTAssertEqual(try decoder.decode(String.self, from: "str"), "str") - XCTAssertEqual(try decoder.decode(Int.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(Int8.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(Int16.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(Int32.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(Int64.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(UInt.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(UInt8.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(UInt16.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(UInt32.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(UInt64.self, from: 1), 1) - XCTAssertEqual(try decoder.decode(Float.self, from: Float(1)), 1) - XCTAssertEqual(try decoder.decode(Float.self, from: Double(1)), 1) - XCTAssertEqual(try decoder.decode(Float.self, from: Int(1)), 1) - XCTAssertEqual(try decoder.decode(Double.self, from: Double(1)), 1) - XCTAssertEqual(try decoder.decode(Double.self, from: Float(1)), 1) - XCTAssertEqual(try decoder.decode(Double.self, from: Int(1)), 1) - } - - func testUnkeyedEncoding() throws { - let encoder = AnyEncoder() - - struct Foo: Encodable { - func encode(to encoder: Encoder) throws { - var container1 = encoder.unkeyedContainer() - try container1.encodeNil() - try container1.encode(true) - try container1.encode("str") - try container1.encode(Int(1)) - try container1.encode(Int8(1)) - try container1.encode(Int16(1)) - try container1.encode(Int32(1)) - var container2 = encoder.unkeyedContainer() - try container2.encode(Int64(1)) - try container2.encode(UInt(1)) - try container2.encode(UInt8(1)) - try container2.encode(UInt16(1)) - try container2.encode(UInt32(1)) - try container2.encode(UInt64(1)) - try container2.encode(Float(1.1)) - try container2.encode(Double(1.1)) - var container3 = container2.nestedUnkeyedContainer() - try container3.encode("str") - var container4 = container2.nestedContainer(keyedBy: DynamicCodingKey.self) - try container4.encode("str", forKey: "str") - XCTAssertEqual(container2.count, 17) - } - } - - let array = try XCTUnwrap(try encoder.encode(Foo()) as? [Any?]) - XCTAssertNil(array[0]) - XCTAssertTrue(array[1] is Bool) - XCTAssertTrue(array[2] is String) - XCTAssertTrue(array[3] is Int) - XCTAssertTrue(array[4] is Int8) - XCTAssertTrue(array[5] is Int16) - XCTAssertTrue(array[6] is Int32) - XCTAssertTrue(array[7] is Int64) - XCTAssertTrue(array[8] is UInt) - XCTAssertTrue(array[9] is UInt8) - XCTAssertTrue(array[10] is UInt16) - XCTAssertTrue(array[11] is UInt32) - XCTAssertTrue(array[12] is UInt64) - XCTAssertTrue(array[13] is Float) - XCTAssertTrue(array[14] is Double) - XCTAssertTrue(array[15] is [String]) - XCTAssertTrue(array[16] is [String: String]) - } - - func testUnkeyedDecoding() throws { - let decoder = AnyDecoder() - - let array: [Any?] = [ - nil, - true, - "str", - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1.1, 1.1, - ["str"], - ["str": "str"], - ] - - struct Foo: Decodable { - init(from decoder: Decoder) throws { - XCTAssertThrowsError(try decoder.container(keyedBy: DynamicCodingKey.self)) - var container1 = try decoder.unkeyedContainer() - XCTAssertEqual(container1.count, 17) - XCTAssertTrue(try container1.decodeNil()) - XCTAssertTrue(try container1.decode(Bool.self)) - XCTAssertEqual(try container1.decode(String.self), "str") - XCTAssertEqual(try container1.decode(Int.self), 1) - XCTAssertEqual(try container1.decode(Int8.self), 1) - XCTAssertEqual(try container1.decode(Int16.self), 1) - XCTAssertEqual(try container1.decode(Int32.self), 1) - XCTAssertEqual(try container1.decode(Int64.self), 1) - XCTAssertEqual(try container1.decode(UInt.self), 1) - XCTAssertEqual(try container1.decode(UInt8.self), 1) - XCTAssertEqual(try container1.decode(UInt16.self), 1) - XCTAssertEqual(try container1.decode(UInt32.self), 1) - XCTAssertEqual(try container1.decode(UInt64.self), 1) - XCTAssertEqual(try container1.decode(Float.self), 1.1) - XCTAssertEqual(try container1.decode(Double.self), 1.1) - var container2 = try container1.nestedUnkeyedContainer() - XCTAssertEqual(try container2.decode(String.self), "str") - let container3 = try container1.nestedContainer(keyedBy: DynamicCodingKey.self) - XCTAssertEqual(try container3.decode(String.self, forKey: "str"), "str") - XCTAssertThrowsError(try container1.decodeNil()) - } - } - - XCTAssertNoThrow(try decoder.decode(Foo.self, from: array)) - } - - func testKeyedEncoding() throws { - let encoder = AnyEncoder() - - struct Foo: Encodable { - func encode(to encoder: Encoder) throws { - var container1 = encoder.container(keyedBy: DynamicCodingKey.self) - try container1.encodeNil(forKey: "null") - try container1.encode(true, forKey: "bool") - try container1.encode("str", forKey: "string") - try container1.encode(Int(1), forKey: "int") - try container1.encode(Int8(1), forKey: "int8") - try container1.encode(Int16(1), forKey: "int16") - try container1.encode(Int32(1), forKey: "int32") - try container1.encode(Int64(1), forKey: "int64") - var container2 = encoder.container(keyedBy: DynamicCodingKey.self) - try container2.encode(UInt(1), forKey: "uint") - try container2.encode(UInt8(1), forKey: "uint8") - try container2.encode(UInt16(1), forKey: "uint16") - try container2.encode(UInt32(1), forKey: "uint32") - try container2.encode(UInt64(1), forKey: "uint64") - try container2.encode(Float(1.1), forKey: "float") - try container2.encode(Double(1.1), forKey: "double") - var container3 = container2.nestedUnkeyedContainer(forKey: "array") - try container3.encode("str") - var container4 = container2.nestedContainer(keyedBy: DynamicCodingKey.self, forKey: "nested") - try container4.encode("str", forKey: "str") - } - } - - let dictionary = try XCTUnwrap(try encoder.encode(Foo()) as? [String: Any?]) - XCTAssertNil(try XCTUnwrap(dictionary["null"])) - XCTAssertTrue(dictionary["bool"] is Bool) - XCTAssertTrue(dictionary["string"] is String) - XCTAssertTrue(dictionary["int"] is Int) - XCTAssertTrue(dictionary["int8"] is Int8) - XCTAssertTrue(dictionary["int16"] is Int16) - XCTAssertTrue(dictionary["int32"] is Int32) - XCTAssertTrue(dictionary["int64"] is Int64) - XCTAssertTrue(dictionary["uint"] is UInt) - XCTAssertTrue(dictionary["uint8"] is UInt8) - XCTAssertTrue(dictionary["uint16"] is UInt16) - XCTAssertTrue(dictionary["uint32"] is UInt32) - XCTAssertTrue(dictionary["uint64"] is UInt64) - XCTAssertTrue(dictionary["float"] is Float) - XCTAssertTrue(dictionary["double"] is Double) - XCTAssertTrue(dictionary["array"] is [String]) - XCTAssertTrue(dictionary["nested"] is [String: String]) - } - - func testKeyedDecoding() throws { - let decoder = AnyDecoder() - - let dictionary: [String: Any?] = [ - "null": nil, - "bool": true, - "string": "str", - "integer": 1, - "floating": 1.1, - "array": ["str"], - "nested": ["str": "str"], - ] - - struct Foo: Decodable { - init(from decoder: Decoder) throws { - XCTAssertThrowsError(try decoder.unkeyedContainer()) - let container1 = try decoder.container(keyedBy: DynamicCodingKey.self) - XCTAssertEqual(container1.allKeys.count, 7) - XCTAssertTrue(try container1.decodeNil(forKey: "null")) - XCTAssertTrue(try container1.decode(Bool.self, forKey: "bool")) - XCTAssertEqual(try container1.decode(String.self, forKey: "string"), "str") - XCTAssertEqual(try container1.decode(Int.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(Int8.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(Int16.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(Int32.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(Int64.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(UInt.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(UInt8.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(UInt16.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(UInt32.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(UInt64.self, forKey: "integer"), 1) - XCTAssertEqual(try container1.decode(Float.self, forKey: "floating"), 1.1) - XCTAssertEqual(try container1.decode(Double.self, forKey: "floating"), 1.1) - var container2 = try container1.nestedUnkeyedContainer(forKey: "array") - XCTAssertEqual(try container2.decode(String.self), "str") - let container3 = try container1.nestedContainer(keyedBy: DynamicCodingKey.self, forKey: "nested") - XCTAssertEqual(try container3.decode(String.self, forKey: "str"), "str") - XCTAssertThrowsError(try container1.decodeNil(forKey: "unkown")) - } - } - - XCTAssertNoThrow(try decoder.decode(Foo.self, from: dictionary)) - } -} - -extension CodableObject: RandomMockable { - static func mockRandom() -> Self { - .init( - id: .mockRandom(), - date: .mockRandom(), - url: .mockRandom(), - string: .mockRandom(), - null: nil, - integer: .mockRandom(), - float: .mockRandom(), - nested: .mockRandom(), - empty: .init(), - array: .mockRandom() - ) - } -} - -extension CodableObject.Nested: RandomMockable { - fileprivate static func mockRandom() -> Self { - .init(id: .mockRandom(), string: .mockRandom()) - } -} diff --git a/DatadogInternal/Tests/Codable/AnyDecodableTests.swift b/DatadogInternal/Tests/Codable/AnyDecodableTests.swift deleted file mode 100644 index f1adc43eae..0000000000 --- a/DatadogInternal/Tests/Codable/AnyDecodableTests.swift +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - * - * This file includes software developed by Flight School, https://flight.school/ and altered by Datadog. - * Use of this source code is governed by MIT license: - * - * Copyright 2018 Read Evaluate Press, LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -import XCTest -import DatadogInternal - -class AnyDecodableTests: XCTestCase { - func testJSONDecoding() throws { - let json = """ - { - "boolean": true, - "integer": 42, - "double": 3.141592653589793, - "string": "string", - "array": [1, 2, 3], - "nested": { - "a": "alpha", - "b": "bravo", - "c": "charlie" - }, - "null": null - } - """.data(using: .utf8)! - - let decoder = JSONDecoder() - let dictionary = try decoder.decode([String: AnyDecodable].self, from: json) - - XCTAssertEqual(dictionary["boolean"]?.value as? Bool, true) - XCTAssertEqual(dictionary["integer"]?.value as? Int, 42) - XCTAssertEqual(dictionary["double"]?.value as! Double, 3.141592653589793, accuracy: 0.001) - XCTAssertEqual(dictionary["string"]?.value as? String, "string") - XCTAssertEqual(dictionary["array"]?.value as? [Int], [1, 2, 3]) - XCTAssertEqual(dictionary["nested"]?.value as? [String: String], ["a": "alpha", "b": "bravo", "c": "charlie"]) - XCTAssertEqual(dictionary["null"]?.value as? NSNull, NSNull()) - } - - func testAnyDecoding() throws { - class Passthrough: PassthroughAnyCodable { - init() {} - } - - let passthrough = Passthrough() - - let any: [String: Any?] = [ - "boolean": true, - "integer": 42, - "double": 3.141592653589793, - "string": "string", - "array": [1, 2, 3], - "nested": [ - "a": "alpha", - "b": "bravo", - "c": "charlie" - ], - "null": nil, - "uuid": UUID(), - "url": URL(string: "https://test.com"), - "passthrough": passthrough - ] - - let decoder = AnyDecoder() - let dictionary = try decoder.decode([String: AnyDecodable].self, from: any) - - XCTAssertEqual(dictionary["boolean"]?.value as? Bool, true) - XCTAssertEqual(dictionary["integer"]?.value as? Int, 42) - XCTAssertEqual(dictionary["double"]?.value as! Double, 3.141592653589793, accuracy: 0.001) - XCTAssertEqual(dictionary["string"]?.value as? String, "string") - XCTAssertEqual(dictionary["array"]?.value as? [Int], [1, 2, 3]) - XCTAssertEqual(dictionary["nested"]?.value as? [String: String], ["a": "alpha", "b": "bravo", "c": "charlie"]) - XCTAssert(dictionary["uuid"]?.value is UUID) - XCTAssertEqual(dictionary["url"]?.value as? URL, URL(string: "https://test.com")) - XCTAssert(dictionary["passthrough"]?.value as? Passthrough === passthrough) - } - - func testAnyDecodingFailue() throws { - class NotPassthrough { - init() {} - } - - let passthrough = NotPassthrough() - - let any: [String: Any?] = [ - "passthrough": passthrough - ] - - let decoder = AnyDecoder() - XCTAssertThrowsError(try decoder.decode(AnyDecodable.self, from: any)) { error in - guard case DecodingError.dataCorrupted(let context) = error else { - return XCTFail("Unexpected error: \(error)") - } - - XCTAssertEqual(context.debugDescription, "AnyDecodable value cannot be decoded") - } - } -} diff --git a/DatadogInternal/Tests/DatadogCoreProtocolTests.swift b/DatadogInternal/Tests/DatadogCoreProtocolTests.swift index c9da8c9e2d..01de92c5ae 100644 --- a/DatadogInternal/Tests/DatadogCoreProtocolTests.swift +++ b/DatadogInternal/Tests/DatadogCoreProtocolTests.swift @@ -24,36 +24,6 @@ class DatadogCoreProtocolTests: XCTestCase { ) } - func testSetBaggageExtension() throws { - // Given - let core = PassthroughCoreMock() - - // Then - core.set(baggage: FeatureBaggage("value"), forKey: "test") - XCTAssertEqual( - try core.context.baggages["test"]?.decode(), "value", "DatadogCoreProtocol.set(baggage:) should forward baggage" - ) - - core.set(baggage: nil, forKey: "test") - XCTAssertNil(core.context.baggages["test"], "DatadogCoreProtocol.set(baggage:) should forward baggage" ) - - core.set(baggage: { "value" }, forKey: "test") - XCTAssertEqual( - try core.context.baggages["test"]?.decode(), "value", "DatadogCoreProtocol.set(baggage:) should forward baggage" - ) - - core.set(baggage: { nil as String? }, forKey: "test") - XCTAssertNil(core.context.baggages["test"], "DatadogCoreProtocol.set(baggage:) should forward baggage" ) - - core.set(baggage: "value", forKey: "test") - XCTAssertEqual( - try core.context.baggages["test"]?.decode(), "value", "DatadogCoreProtocol.set(baggage:) should forward baggage" - ) - - core.set(baggage: nil as String?, forKey: "test") - XCTAssertNil(core.context.baggages["test"], "DatadogCoreProtocol.set(baggage:) should forward baggage" ) - } - func testAdditionalContextExtension() throws { // Given let core = PassthroughCoreMock() diff --git a/DatadogInternal/Tests/MessageBus/FeatureBaggageTests.swift b/DatadogInternal/Tests/MessageBus/FeatureBaggageTests.swift deleted file mode 100644 index 9fa42a5d47..0000000000 --- a/DatadogInternal/Tests/MessageBus/FeatureBaggageTests.swift +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import XCTest -import TestUtilities -@testable import DatadogInternal - -class FeatureBaggageTests: XCTestCase { - struct GroceryProduct: Encodable, RandomMockable { - var name: String - var points: Int - var description: String - - static func mockRandom() -> Self { - .init( - name: .mockRandom(), - points: .mockRandom(), - description: .mockRandom() - ) - } - } - - struct CartItem: Decodable { - var name: String - var points: Int - var code: String? - } - - func testEncodeDecode() throws { - let pear = GroceryProduct.mockRandom() - let baggage = FeatureBaggage(pear) - let item: CartItem = try baggage.decode() - - XCTAssertEqual(pear.name, item.name) - XCTAssertEqual(pear.points, item.points) - XCTAssertNil(item.code) - } - - func testEncodingFailure() throws { - struct FaultyEncodable: Encodable { - func encode(to encoder: Encoder) throws { - throw EncodingError.invalidValue( - self, - .init(codingPath: [], debugDescription: "FaultyEncodable") - ) - } - } - - let faulty = FaultyEncodable() - let baggage = FeatureBaggage(faulty) - XCTAssertThrowsError(try baggage.decode(type: CartItem.self)) { - XCTAssert($0 is EncodingError) - } - } - - func testDecodingFailure() throws { - struct FaultyDecodable: Decodable { - init(from decoder: Decoder) throws { - throw DecodingError.valueNotFound( - FaultyDecodable.self, - .init(codingPath: [], debugDescription: "FaultyDecodable") - ) - } - } - - let pear = GroceryProduct.mockRandom() - let baggage = FeatureBaggage(pear) - XCTAssertThrowsError(try baggage.decode(type: FaultyDecodable.self)) { error in - XCTAssert(error is DecodingError) - } - } - - func testThreadSafety() { - let pear = GroceryProduct.mockRandom() - let baggage = FeatureBaggage(pear) - // swiftlint:disable opening_brace - callConcurrently( - closures: [ - { _ = try? baggage.encode() }, - { _ = try? baggage.decode(type: CartItem.self) } - ], - iterations: 100 - ) - // swiftlint:enable opening_brace - } -} diff --git a/DatadogRUM/Tests/Integrations/SessionReplayDependencyTests.swift b/DatadogRUM/Tests/Integrations/SessionReplayDependencyTests.swift index 72d031c68c..53addbe7d3 100644 --- a/DatadogRUM/Tests/Integrations/SessionReplayDependencyTests.swift +++ b/DatadogRUM/Tests/Integrations/SessionReplayDependencyTests.swift @@ -28,7 +28,7 @@ class SessionReplayDependencyTests: XCTestCase { func testWhenSessionReplayIsNotConfigured_itReadsNoSRBaggage() { // When - let context: DatadogContext = .mockWith(baggages: [:]) + let context: DatadogContext = .mockAny() // Then XCTAssertNil(context.hasReplay) diff --git a/TestUtilities/Sources/Mocks/DatadogInternal/DatadogContextMock.swift b/TestUtilities/Sources/Mocks/DatadogInternal/DatadogContextMock.swift index 4d88be7067..1a1ba1d0b5 100644 --- a/TestUtilities/Sources/Mocks/DatadogInternal/DatadogContextMock.swift +++ b/TestUtilities/Sources/Mocks/DatadogInternal/DatadogContextMock.swift @@ -37,8 +37,7 @@ extension DatadogContext: AnyMockable, RandomMockable { carrierInfo: CarrierInfo? = .mockAny(), batteryStatus: BatteryStatus? = .mockAny(), isLowPowerModeEnabled: Bool = false, - additionalContext: [AdditionalContext] = [], - baggages: [String: FeatureBaggage] = [:] + additionalContext: [AdditionalContext] = [] ) -> DatadogContext { var context = DatadogContext( site: site, @@ -66,8 +65,7 @@ extension DatadogContext: AnyMockable, RandomMockable { networkConnectionInfo: networkConnectionInfo, carrierInfo: carrierInfo, batteryStatus: batteryStatus, - isLowPowerModeEnabled: isLowPowerModeEnabled, - baggages: baggages + isLowPowerModeEnabled: isLowPowerModeEnabled ) additionalContext.forEach { context.set(additionalContext: $0) } @@ -100,8 +98,7 @@ extension DatadogContext: AnyMockable, RandomMockable { networkConnectionInfo: .mockRandom(), carrierInfo: .mockRandom(), batteryStatus: nil, - isLowPowerModeEnabled: .mockRandom(), - baggages: .mockRandom() + isLowPowerModeEnabled: .mockRandom() ) } } diff --git a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureBaggageMock.swift b/TestUtilities/Sources/Mocks/DatadogInternal/FeatureBaggageMock.swift deleted file mode 100644 index e274e6c4ac..0000000000 --- a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureBaggageMock.swift +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. - * This product includes software developed at Datadog (https://www.datadoghq.com/). - * Copyright 2019-Present Datadog, Inc. - */ - -import Foundation -import DatadogInternal - -extension FeatureBaggage: AnyMockable, RandomMockable { - public static func mockAny() -> Self { - .init([String: String].mockAny()) - } - - public static func mockRandom() -> Self { - .init([String: String].mockRandom()) - } -} diff --git a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureRegistrationCoreMock.swift b/TestUtilities/Sources/Mocks/DatadogInternal/FeatureRegistrationCoreMock.swift index d326bfcb36..e0f519e89f 100644 --- a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureRegistrationCoreMock.swift +++ b/TestUtilities/Sources/Mocks/DatadogInternal/FeatureRegistrationCoreMock.swift @@ -51,10 +51,6 @@ public class FeatureRegistrationCoreMock: DatadogCoreProtocol { return NOPFeatureScope() } - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - // not supported - use different type of core mock if you need this - } - public func set(context: @escaping () -> Context?) where Context: AdditionalContext { // not supported - use different type of core mock if you need this } diff --git a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureScopeMock.swift b/TestUtilities/Sources/Mocks/DatadogInternal/FeatureScopeMock.swift index 0773a1efbb..b9b4536507 100644 --- a/TestUtilities/Sources/Mocks/DatadogInternal/FeatureScopeMock.swift +++ b/TestUtilities/Sources/Mocks/DatadogInternal/FeatureScopeMock.swift @@ -43,11 +43,6 @@ public final class FeatureScopeMock: FeatureScope, @unchecked Sendable { public func send(message: FeatureMessage, else fallback: @escaping () -> Void) { messages.append(message) } - - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - contextMock.baggages[key] = baggage() - } - public func set(context: @escaping () -> Context?) where Context: AdditionalContext { contextMock.set(additionalContext: context()) } diff --git a/TestUtilities/Sources/Mocks/DatadogInternal/PassthroughCoreMock.swift b/TestUtilities/Sources/Mocks/DatadogInternal/PassthroughCoreMock.swift index 6fbaa17726..524d083b2d 100644 --- a/TestUtilities/Sources/Mocks/DatadogInternal/PassthroughCoreMock.swift +++ b/TestUtilities/Sources/Mocks/DatadogInternal/PassthroughCoreMock.swift @@ -78,10 +78,6 @@ open class PassthroughCoreMock: DatadogCoreProtocol, FeatureScope, @unchecked Se self } - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - context.baggages[key] = baggage() - } - public func set(context: @escaping () -> Context?) where Context: AdditionalContext { self.context.set(additionalContext: context()) } diff --git a/TestUtilities/Sources/Proxies/DatadogCoreProxy.swift b/TestUtilities/Sources/Proxies/DatadogCoreProxy.swift index 68fc5c00af..4c5825f2e9 100644 --- a/TestUtilities/Sources/Proxies/DatadogCoreProxy.swift +++ b/TestUtilities/Sources/Proxies/DatadogCoreProxy.swift @@ -103,10 +103,6 @@ public final class DatadogCoreProxy: DatadogCoreProtocol { core.setUserInfo(id: id, name: name, email: email, extraInfo: extraInfo) } - public func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - core.set(baggage: baggage, forKey: key) - } - public func set(context: @escaping () -> Context?) where Context: AdditionalContext { core.set(context: context) } @@ -164,10 +160,6 @@ private struct FeatureScopeProxy: FeatureScope { proxy.send(message: message, else: fallback) } - func set(baggage: @escaping () -> FeatureBaggage?, forKey key: String) { - proxy.set(baggage: baggage, forKey: key) - } - func set(context: @escaping () -> Context?) where Context: AdditionalContext { proxy.set(context: context) }