diff --git a/Sources/Encoder/DictionaryComponentEncoder.swift b/Sources/Encoder/DictionaryComponentEncoder.swift index f9198e8..5866acb 100644 --- a/Sources/Encoder/DictionaryComponentEncoder.swift +++ b/Sources/Encoder/DictionaryComponentEncoder.swift @@ -208,6 +208,9 @@ extension DictionaryComponentEncoder { case let url as URL: return try encodeURL(url, at: codingPath) + case _ where self.options.nestedEncodingStrategy == .skip: + return .value(nil) + default: return try encodeNonPrimitiveValue(value, at: codingPath) } diff --git a/Sources/Encoder/DictionaryEncoder.swift b/Sources/Encoder/DictionaryEncoder.swift index d424b99..2430135 100644 --- a/Sources/Encoder/DictionaryEncoder.swift +++ b/Sources/Encoder/DictionaryEncoder.swift @@ -32,6 +32,11 @@ public final class DictionaryEncoder: Sendable { set { optionsMutex.withLock { $0.keyEncodingStrategy = newValue } } } + public var nestedEncodingStrategy: DictionaryNestedEncodingStrategy { + get { optionsMutex.withLock { $0.nestedEncodingStrategy } } + set { optionsMutex.withLock { $0.nestedEncodingStrategy = newValue } } + } + public var userInfo: [CodingUserInfoKey: Sendable] { get { userInfoMutex.withLock { $0 } } set { userInfoMutex.withLock { $0 = newValue } } @@ -45,6 +50,7 @@ public final class DictionaryEncoder: Sendable { nonConformingFloatEncodingStrategy: DictionaryNonConformingFloatEncodingStrategy = .throw, nilEncodingStrategy: DictionaryNilEncodingStrategy = .useNil, keyEncodingStrategy: DictionaryKeyEncodingStrategy = .useDefaultKeys, + nestedEncodingStrategy: DictionaryNestedEncodingStrategy = .encode, userInfo: [CodingUserInfoKey: Sendable] = [:] ) { let options = DictionaryEncodingOptions( @@ -52,7 +58,8 @@ public final class DictionaryEncoder: Sendable { dataEncodingStrategy: dataEncodingStrategy, nonConformingFloatEncodingStrategy: nonConformingFloatEncodingStrategy, nilEncodingStrategy: nilEncodingStrategy, - keyEncodingStrategy: keyEncodingStrategy + keyEncodingStrategy: keyEncodingStrategy, + nestedEncodingStrategy: nestedEncodingStrategy ) self.optionsMutex = Mutex(value: options) diff --git a/Sources/Encoder/Options/DictionaryEncodingOptions.swift b/Sources/Encoder/Options/DictionaryEncodingOptions.swift index 6878ada..f369236 100644 --- a/Sources/Encoder/Options/DictionaryEncodingOptions.swift +++ b/Sources/Encoder/Options/DictionaryEncodingOptions.swift @@ -9,4 +9,5 @@ internal struct DictionaryEncodingOptions { internal var nonConformingFloatEncodingStrategy: DictionaryNonConformingFloatEncodingStrategy internal var nilEncodingStrategy: DictionaryNilEncodingStrategy internal var keyEncodingStrategy: DictionaryKeyEncodingStrategy + internal var nestedEncodingStrategy: DictionaryNestedEncodingStrategy } diff --git a/Sources/Encoder/Options/DictionaryNestedEncodingStrategy.swift b/Sources/Encoder/Options/DictionaryNestedEncodingStrategy.swift new file mode 100644 index 0000000..da0a299 --- /dev/null +++ b/Sources/Encoder/Options/DictionaryNestedEncodingStrategy.swift @@ -0,0 +1,9 @@ +import Foundation + +public enum DictionaryNestedEncodingStrategy: Sendable { + + // MARK: - Enumeration Cases + + case encode + case skip +} diff --git a/Tests/Encoder/DictionaryEncoderStrategiesTests.swift b/Tests/Encoder/DictionaryEncoderStrategiesTests.swift index 6f0b642..9625944 100644 --- a/Tests/Encoder/DictionaryEncoderStrategiesTests.swift +++ b/Tests/Encoder/DictionaryEncoderStrategiesTests.swift @@ -219,6 +219,25 @@ final class DictionaryEncoderStrategiesTests: XCTestCase, DictionaryEncoderTesti assertEncoderSucceeds(encoding: EncodableStruct()) } + // MARK: - + + func testThatEncoderSucceedsWhenSkippingNestedContainers() { + struct EncodableStruct: Encodable { + var test: String = "1" + var dict: [String: Int] = ["a": 1] + var array: [String] = ["b"] + } + + encoder.nestedEncodingStrategy = .skip + + assertEncoderSucceeds( + encoding: EncodableStruct(), + expecting: [ + "test": "1" + ]) + } + + // MARK: - XCTestCase override func setUp() {