diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/ResilientDecoding.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/ResilientDecoding.xcscheme
index b4c5b51..33eb1be 100644
--- a/.swiftpm/xcode/xcshareddata/xcschemes/ResilientDecoding.xcscheme
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/ResilientDecoding.xcscheme
@@ -41,10 +41,21 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ onlyGenerateCoverageForSpecifiedTargets = "YES">
+
+
+
+
+ skipped = "NO"
+ parallelizable = "YES">
(novelValue: T) {
+ public init(novelValue: T) {
self.novelValue = novelValue
}
diff --git a/Sources/ResilientDecoding/Resilient.swift b/Sources/ResilientDecoding/Resilient.swift
index 71bfbd1..0b63e2f 100644
--- a/Sources/ResilientDecoding/Resilient.swift
+++ b/Sources/ResilientDecoding/Resilient.swift
@@ -6,7 +6,7 @@ import Foundation
// MARK: - Resilient
@propertyWrapper
-public struct Resilient: Decodable {
+public struct Resilient: Decodable, Sendable {
/**
If this initializer is called it is likely because a property was marked as `Resilient` despite the underlying type not supporting resilient decoding. For instance, a developer may write `@Resilient var numberOfThings: Int`, but since `Int` doesn't provide a mechanism for recovering from a decoding failure (like `Array`s and `Optional`s do) wrapping the property in `Resilient` does nothing.
@@ -77,7 +77,7 @@ public struct Resilient: Decodable {
/**
The outcome of decoding a `Resilient` type
*/
-public enum ResilientDecodingOutcome {
+public enum ResilientDecodingOutcome: Sendable {
/**
A value was decoded successfully
*/
diff --git a/Sources/ResilientDecoding/ResilientArray+DecodingOutcome.swift b/Sources/ResilientDecoding/ResilientArray+DecodingOutcome.swift
index 460dbd9..77e3000 100644
--- a/Sources/ResilientDecoding/ResilientArray+DecodingOutcome.swift
+++ b/Sources/ResilientDecoding/ResilientArray+DecodingOutcome.swift
@@ -5,18 +5,18 @@ import Foundation
extension Resilient {
- init(_ results: [Result]) where Value == [T] {
+ init(_ results: [Result]) where Value == [T] {
self.init(results, transform: { $0 })
}
- init(_ results: [Result]) where Value == [T]? {
+ init(_ results: [Result]) where Value == [T]? {
self.init(results, transform: { $0 })
}
/**
- parameter transform: While the two lines above both say `{ $0 }` they are actually different because the first one is of type `([T]) -> [T]` and the second is of type `([T]) -> [T]?`.
*/
- private init(_ results: [Result], transform: ([T]) -> Value) {
+ private init(_ results: [Result], transform: ([T]) -> Value) {
let elements = results.compactMap { try? $0.get() }
let value = transform(elements)
if elements.count == results.count {
@@ -41,7 +41,7 @@ extension ResilientDecodingOutcome {
/**
A type representing some number of errors encountered while decoding an array
*/
- public struct ArrayDecodingError: Error {
+ public struct ArrayDecodingError: Error {
public let results: [Result]
public var errors: [Error] {
results.compactMap { result in
diff --git a/Sources/ResilientDecoding/ResilientArray.swift b/Sources/ResilientDecoding/ResilientArray.swift
index a72507e..9ba7e49 100644
--- a/Sources/ResilientDecoding/ResilientArray.swift
+++ b/Sources/ResilientDecoding/ResilientArray.swift
@@ -22,7 +22,7 @@ extension KeyedDecodingContainer {
/**
Decodes a `Resilient` array, omitting elements as errors are encountered.
*/
- public func decode(_ type: Resilient<[Element]>.Type, forKey key: Key) throws -> Resilient<[Element]>
+ public func decode(_ type: Resilient<[Element]>.Type, forKey key: Key) throws -> Resilient<[Element]>
where
Element: Decodable
{
@@ -32,7 +32,7 @@ extension KeyedDecodingContainer {
/**
Decodes an optional `Resilient` array. A missing key or `nil` value will silently set the property to `nil`.
*/
- public func decode(_ type: Resilient<[Element]?>.Type, forKey key: Key) throws -> Resilient<[Element]?> {
+ public func decode(_ type: Resilient<[Element]?>.Type, forKey key: Key) throws -> Resilient<[Element]?> {
resilientlyDecode(valueForKey: key, fallback: nil) { $0.resilientlyDecodeArray().map { $0 } }
}
@@ -40,7 +40,7 @@ extension KeyedDecodingContainer {
extension Decoder {
- func resilientlyDecodeArray() -> Resilient<[Element]>
+ func resilientlyDecodeArray() -> Resilient<[Element]>
{
resilientlyDecodeArray(of: Element.self, transform: { $0 })
}
@@ -48,7 +48,7 @@ extension Decoder {
/**
We can't just use `map` because the transform needs to happen _before_ we wrap the value in `Resilient` so that that the element type of `ArrayDecodingError` is correct.
*/
- func resilientlyDecodeArray(
+ func resilientlyDecodeArray(
of intermediateElementType: IntermediateElement.Type,
transform: (IntermediateElement) -> Element) -> Resilient<[Element]>
{
@@ -83,11 +83,11 @@ extension Decoder {
For the following cases, the user probably meant to use `[T]` as the property type.
*/
extension KeyedDecodingContainer {
- public func decode(_ type: Resilient<[T?]>.Type, forKey key: Key) throws -> Resilient<[T?]> {
+ public func decode(_ type: Resilient<[T?]>.Type, forKey key: Key) throws -> Resilient<[T?]> {
assertionFailure()
return try decode(Resilient<[T]>.self, forKey: key).map { $0 }
}
- public func decode(_ type: Resilient<[T?]?>.Type, forKey key: Key) throws -> Resilient<[T?]?> {
+ public func decode(_ type: Resilient<[T?]?>.Type, forKey key: Key) throws -> Resilient<[T?]?> {
assertionFailure()
return try decode(Resilient<[T]>.self, forKey: key).map { $0 }
}
diff --git a/Sources/ResilientDecoding/ResilientDictionary+DecodingOutcome.swift b/Sources/ResilientDecoding/ResilientDictionary+DecodingOutcome.swift
index de63011..495950e 100644
--- a/Sources/ResilientDecoding/ResilientDictionary+DecodingOutcome.swift
+++ b/Sources/ResilientDecoding/ResilientDictionary+DecodingOutcome.swift
@@ -5,18 +5,18 @@ import Foundation
extension Resilient {
- init(_ results: [String: Result]) where Value == [String: T] {
+ init(_ results: [String: Result]) where Value == [String: T] {
self.init(results, transform: { $0 })
}
- init(_ results: [String: Result]) where Value == [String: T]? {
+ init(_ results: [String: Result]) where Value == [String: T]? {
self.init(results, transform: { $0 })
}
/**
- parameter transform: While the two lines above both say `{ $0 }` they are actually different because the first one is of type `([String: T]) -> [String: T]` and the second is of type `([String: T]) -> [String: T]?`.
*/
- private init(_ results: [String: Result], transform: ([String: T]) -> Value) {
+ private init(_ results: [String: Result], transform: ([String: T]) -> Value) {
let dictionary = results.compactMapValues { try? $0.get() }
let value = transform(dictionary)
if dictionary.count == results.count {
@@ -41,7 +41,7 @@ extension ResilientDecodingOutcome {
/**
A type representing some number of errors encountered while decoding a dictionary
*/
- public struct DictionaryDecodingError: Error {
+ public struct DictionaryDecodingError: Error {
public let results: [String: Result]
public var errors: [Error] {
/// It is currently impossible to have both a `topLevelError` and `results` at the same time, but this code is simpler than having an `enum` nested in this type.
diff --git a/Sources/ResilientDecoding/ResilientDictionary.swift b/Sources/ResilientDecoding/ResilientDictionary.swift
index 28b91ea..bd700e3 100644
--- a/Sources/ResilientDecoding/ResilientDictionary.swift
+++ b/Sources/ResilientDecoding/ResilientDictionary.swift
@@ -20,7 +20,7 @@ extension KeyedDecodingContainer {
/**
Decodes a `Resilient` dictionary, omitting values as errors are encountered.
*/
- public func decode(_ type: Resilient<[String: Value]>.Type, forKey key: Key) throws -> Resilient<[String: Value]>
+ public func decode(_ type: Resilient<[String: Value]>.Type, forKey key: Key) throws -> Resilient<[String: Value]>
{
resilientlyDecode(valueForKey: key, fallback: [:]) { $0.resilientlyDecodeDictionary() }
}
@@ -28,7 +28,7 @@ extension KeyedDecodingContainer {
/**
Decodes an optional `Resilient` dictionary. If the field is missing or the value is `nil` the decoded property will also be `nil`.
*/
- public func decode(_ type: Resilient<[String: Value]?>.Type, forKey key: Key) throws -> Resilient<[String: Value]?> {
+ public func decode(_ type: Resilient<[String: Value]?>.Type, forKey key: Key) throws -> Resilient<[String: Value]?> {
resilientlyDecode(valueForKey: key, fallback: nil) { $0.resilientlyDecodeDictionary().map { $0 } }
}
@@ -36,7 +36,7 @@ extension KeyedDecodingContainer {
extension Decoder {
- func resilientlyDecodeDictionary() -> Resilient<[String: Value]>
+ func resilientlyDecodeDictionary() -> Resilient<[String: Value]>
{
resilientlyDecodeDictionary(of: Value.self, transform: { $0 })
}
@@ -44,7 +44,7 @@ extension Decoder {
/**
We can't just use `map` because the transform needs to happen _before_ we wrap the value in `Resilient` so that that the value type of `DictionaryDecodingError` is correct.
*/
- func resilientlyDecodeDictionary(
+ func resilientlyDecodeDictionary(
of intermediateValueType: IntermediateValue.Type,
transform: (IntermediateValue) -> Value) -> Resilient<[String: Value]>
{
@@ -86,11 +86,11 @@ private struct DecodingResultContainer: Decodable {
For the following cases, the user probably meant to use `[String: T]` as the property type.
*/
extension KeyedDecodingContainer {
- public func decode(_ type: Resilient<[String: T?]>.Type, forKey key: Key) throws -> Resilient<[T?]> {
+ public func decode(_ type: Resilient<[String: T?]>.Type, forKey key: Key) throws -> Resilient<[T?]> {
assertionFailure()
return try decode(Resilient<[T]>.self, forKey: key).map { $0 }
}
- public func decode(_ type: Resilient<[String: T?]?>.Type, forKey key: Key) throws -> Resilient<[T?]?> {
+ public func decode(_ type: Resilient<[String: T?]?>.Type, forKey key: Key) throws -> Resilient<[T?]?> {
assertionFailure()
return try decode(Resilient<[T]>.self, forKey: key).map { $0 }
}
diff --git a/Sources/ResilientDecoding/ResilientRawRepresentable.swift b/Sources/ResilientDecoding/ResilientRawRepresentable.swift
index dfc62a9..4f2b398 100644
--- a/Sources/ResilientDecoding/ResilientRawRepresentable.swift
+++ b/Sources/ResilientDecoding/ResilientRawRepresentable.swift
@@ -16,7 +16,7 @@ import Foundation
```
then any struct with a `Resilient` property with that type (for instance `@Resilient var myEnum: MyEnum`) will be set to `.unknown` in the event of a decoding failure.
*/
-public protocol ResilientRawRepresentable: Decodable, RawRepresentable where RawValue: Decodable {
+public protocol ResilientRawRepresentable: Decodable, Sendable, RawRepresentable where RawValue: Decodable & Sendable {
associatedtype DecodingFallback
diff --git a/Tests/ResilientDecodingTests/BugTests.swift b/Tests/ResilientDecodingTests/BugTests.swift
index 74493f8..281742d 100644
--- a/Tests/ResilientDecodingTests/BugTests.swift
+++ b/Tests/ResilientDecodingTests/BugTests.swift
@@ -20,7 +20,7 @@ final class BugTests: XCTestCase {
let rawValue: URL
static var isFrozen: Bool { true }
}
- struct Mock: Decodable {
+ struct Mock: Decodable, Sendable {
@Resilient var optional: URL?
@Resilient var array: [URL]
@Resilient var dictionary: [String: URL]
diff --git a/Tests/ResilientDecodingTests/ResilientArrayTests.swift b/Tests/ResilientDecodingTests/ResilientArrayTests.swift
index 4847146..f176bec 100644
--- a/Tests/ResilientDecodingTests/ResilientArrayTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientArrayTests.swift
@@ -4,7 +4,7 @@
import ResilientDecoding
import XCTest
-private struct ResilientArrayWrapper: Decodable {
+private struct ResilientArrayWrapper: Decodable, Sendable {
@Resilient var resilientArray: [Int]
@Resilient var optionalResilientArray: [Int]?
}
diff --git a/Tests/ResilientDecodingTests/ResilientDecodingErrorReporterTests.swift b/Tests/ResilientDecodingTests/ResilientDecodingErrorReporterTests.swift
index 2153916..8751e64 100644
--- a/Tests/ResilientDecodingTests/ResilientDecodingErrorReporterTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientDecodingErrorReporterTests.swift
@@ -4,7 +4,7 @@
import ResilientDecoding
import XCTest
-private struct ResilientArrayWrapper: Decodable {
+private struct ResilientArrayWrapper: Decodable, Sendable {
@Resilient var resilientArray: [Int]
@Resilient var resilientEnum: ResilientEnum?
}
diff --git a/Tests/ResilientDecodingTests/ResilientDictionaryTests.swift b/Tests/ResilientDecodingTests/ResilientDictionaryTests.swift
index 876d656..65a7f57 100644
--- a/Tests/ResilientDecodingTests/ResilientDictionaryTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientDictionaryTests.swift
@@ -10,7 +10,7 @@ import ResilientDecoding
#endif
import XCTest
-private struct ResilientDictionaryWrapper: Decodable {
+private struct ResilientDictionaryWrapper: Decodable, Sendable {
@Resilient var resilientDictionary: [String: Int]
@Resilient var optionalResilientDictionary: [String: Int]?
}
diff --git a/Tests/ResilientDecodingTests/ResilientOptionalTests.swift b/Tests/ResilientDecodingTests/ResilientOptionalTests.swift
index 121a69a..e1be44d 100644
--- a/Tests/ResilientDecodingTests/ResilientOptionalTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientOptionalTests.swift
@@ -4,7 +4,7 @@
import ResilientDecoding
import XCTest
-private struct ResilientOptionalWrapper: Decodable {
+private struct ResilientOptionalWrapper: Decodable, Sendable {
@Resilient var resilientOptional: Int?
}
diff --git a/Tests/ResilientDecodingTests/ResilientRawRepresentableArrayTests.swift b/Tests/ResilientDecodingTests/ResilientRawRepresentableArrayTests.swift
index a867817..70d7541 100644
--- a/Tests/ResilientDecodingTests/ResilientRawRepresentableArrayTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientRawRepresentableArrayTests.swift
@@ -4,7 +4,7 @@
import ResilientDecoding
import XCTest
-private struct ResilientRawRepresentableArrayWrapper: Decodable {
+private struct ResilientRawRepresentableArrayWrapper: Decodable, Sendable {
@Resilient var resilientArray: [ResilientEnum]
@Resilient var optionalResilientArray: [ResilientEnum]?
@Resilient var resilientArrayOfFrozenType: [ResilientFrozenEnum]
diff --git a/Tests/ResilientDecodingTests/ResilientRawRepresentableDictionaryTests.swift b/Tests/ResilientDecodingTests/ResilientRawRepresentableDictionaryTests.swift
index e28f500..a94c3c6 100644
--- a/Tests/ResilientDecodingTests/ResilientRawRepresentableDictionaryTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientRawRepresentableDictionaryTests.swift
@@ -4,7 +4,7 @@
import ResilientDecoding
import XCTest
-private struct ResilientRawRepresentableDictionaryWrapper: Decodable {
+private struct ResilientRawRepresentableDictionaryWrapper: Decodable, Sendable {
@Resilient var resilientDictionary: [String: ResilientEnum]
@Resilient var optionalResilientDictionary: [String: ResilientEnum]?
@Resilient var resilientDictionaryOfFrozenType: [String: ResilientFrozenEnum]
diff --git a/Tests/ResilientDecodingTests/ResilientRawRepresentableTests.swift b/Tests/ResilientDecodingTests/ResilientRawRepresentableTests.swift
index 0665f2f..8f12030 100644
--- a/Tests/ResilientDecodingTests/ResilientRawRepresentableTests.swift
+++ b/Tests/ResilientDecodingTests/ResilientRawRepresentableTests.swift
@@ -4,7 +4,7 @@
import XCTest
import ResilientDecoding
-private struct ResilientRawRepresentableEnumWrapper: Decodable {
+private struct ResilientRawRepresentableEnumWrapper: Decodable, Sendable {
@Resilient var resilientEnumWithFallback: ResilientEnumWithFallback
@Resilient var resilientFrozenEnumWithFallback: ResilientFrozenEnumWithFallback
@Resilient var optionalResilientEnum: ResilientEnum?