swift-foundation icon indicating copy to clipboard operation
swift-foundation copied to clipboard

Fix `JSONEncoder` key conversion for `CodingKeyRepresentable` dictionary keys

Open ShivaHuang opened this issue 2 months ago • 3 comments

Summary

Fixes an issue where JSONEncoder incorrectly applied key encoding strategies (like .convertToSnakeCase) to dictionary keys that implement CodingKeyRepresentable, when these keys should preserve their semantic meaning and remain unchanged.

Problem

When encoding dictionaries with CodingKeyRepresentable keys (e.g., custom enum or struct keys), JSONEncoder was treating them as regular coding key values and applying key conversion strategies. This caused keys like "leaveMeAlone" to be transformed to "leave_me_alone" even when the key itself represents a semantic identifier that should remain unchanged.

Solution

  • Expands the existing _JSONStringDictionaryEncodableMarker protocol to cover any CodingKeyRepresentable-keyed dictionaries, not just String-keyed ones.
  • Renames the protocol to _JSONCodingKeyRepresentableDictionaryEncodableMarker to reflect its broader scope.
  • Updates the encoding logic to convert CodingKeyRepresentable keys directly to their string representation without applying encoding transformations.

Test Plan

Added test case encodingDictionaryCodingKeyRepresentableKeyConversionUntouched() that verifies:

  • Dictionary with CodingKeyRepresentable keys preserves original key names.
  • Key encoding strategies like .convertToSnakeCase are not applied to the dictionary keys.
  • The fix works with custom structs implementing CodingKeyRepresentable.

Checklist

  • [x] Added test coverage for the fix
  • [x] All existing tests pass
  • [x] Code follows Swift Foundation conventions
  • [x] Changes are backward compatible

This change ensures that dictionaries with semantic keys maintain their intended structure while still allowing key encoding strategies to work correctly for object properties during regular encoding.

ShivaHuang avatar Sep 27 '25 06:09 ShivaHuang

@swift-ci please test

itingliu avatar Oct 16 '25 23:10 itingliu

Hi @itingliu, I rebased the PR and seems the CI work needs to be run again, can you help?

ShivaHuang avatar Oct 17 '25 03:10 ShivaHuang

Would anyone be able to lend a hand with running the test and reviewing this?

ShivaHuang avatar Nov 08 '25 02:11 ShivaHuang