From 933c37dd2f6916ab302deab89b67cc07e07a75cc Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Fri, 5 Sep 2025 21:26:16 +0300 Subject: [PATCH 1/3] reduce swift runtime overhead --- Sources/ReerJSON/JSONDecoderImpl.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Sources/ReerJSON/JSONDecoderImpl.swift b/Sources/ReerJSON/JSONDecoderImpl.swift index 957c3e0..d979101 100644 --- a/Sources/ReerJSON/JSONDecoderImpl.swift +++ b/Sources/ReerJSON/JSONDecoderImpl.swift @@ -168,7 +168,7 @@ final class JSONDecoderImpl: Decoder { if type == Decimal.self { return try unboxDecimal(from: value, for: codingPathNode, additionalKey) as! T } - if let dictType = type as? StringDecodableDictionary.Type { + if !options.keyDecodingStrategy.isDefault, let dictType = type as? StringDecodableDictionary.Type { return try unboxDictionary(from: value, as: dictType, for: codingPathNode, additionalKey) } @@ -1472,3 +1472,14 @@ private struct JSONUnkeyedDecodingContainer: UnkeyedDecodingContainer { return int } } + +private extension JSONDecoder.KeyDecodingStrategy { + var isDefault: Bool { + switch self { + case .useDefaultKeys: + return true + case .convertFromSnakeCase, .custom: + return false + } + } +} From 1ce7be959033b02b46dd78df547af97eb00d5009 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Fri, 5 Sep 2025 23:27:24 +0300 Subject: [PATCH 2/3] handle unknown default value --- Sources/ReerJSON/JSONDecoderImpl.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/ReerJSON/JSONDecoderImpl.swift b/Sources/ReerJSON/JSONDecoderImpl.swift index d979101..a78ad47 100644 --- a/Sources/ReerJSON/JSONDecoderImpl.swift +++ b/Sources/ReerJSON/JSONDecoderImpl.swift @@ -1480,6 +1480,8 @@ private extension JSONDecoder.KeyDecodingStrategy { return true case .convertFromSnakeCase, .custom: return false + @unknown default: + return false } } } From 7c65a6dedcf5966cc0d1e8a6010b895c2acfec34 Mon Sep 17 00:00:00 2001 From: ChrisBenua Date: Mon, 8 Sep 2025 00:17:37 +0300 Subject: [PATCH 3/3] move to utilities --- Sources/ReerJSON/JSONDecoderImpl.swift | 13 ------------- Sources/ReerJSON/Utilities.swift | 12 ++++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Sources/ReerJSON/JSONDecoderImpl.swift b/Sources/ReerJSON/JSONDecoderImpl.swift index a78ad47..f90b99d 100644 --- a/Sources/ReerJSON/JSONDecoderImpl.swift +++ b/Sources/ReerJSON/JSONDecoderImpl.swift @@ -1472,16 +1472,3 @@ private struct JSONUnkeyedDecodingContainer: UnkeyedDecodingContainer { return int } } - -private extension JSONDecoder.KeyDecodingStrategy { - var isDefault: Bool { - switch self { - case .useDefaultKeys: - return true - case .convertFromSnakeCase, .custom: - return false - @unknown default: - return false - } - } -} diff --git a/Sources/ReerJSON/Utilities.swift b/Sources/ReerJSON/Utilities.swift index 189a21a..7553bea 100644 --- a/Sources/ReerJSON/Utilities.swift +++ b/Sources/ReerJSON/Utilities.swift @@ -127,6 +127,18 @@ extension Dictionary : StringDecodableDictionary where Key == String, Value: Dec static var elementType: Decodable.Type { return Value.self } } +extension JSONDecoder.KeyDecodingStrategy { + @inline(__always) + var isDefault: Bool { + switch self { + case .useDefaultKeys: + return true + default: + return false + } + } +} + // This is a workaround for the lack of a "set value only if absent" function for Dictionary. extension Optional { mutating func _setIfNil(to value: Wrapped) {