Skip to content

Optionality updates to Codable API #10667

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

itaiferber
Copy link
Contributor

What's in this pull request?
As laid out in a proposed update to SE-0166 and SE-0167, there are optionality updates that we wanted to introduce to the Codable API. This implements the remainder of those updates which had not yet been implemented:

  • encodeNil(forKey:) and decodeNil(forKey:) have been added to keyed containers
  • encodeNil() and decodeNil() have been added to unkeyed containers
  • The default implementation of decode(...) in terms of decodeIfPresent(...) on all containers has been reversed: with decodeNil(...) in place, a default implementation of decodeIfPresent(...) is now given on all containers, and decode(...) must be implemented instead
    • These methods are now properly exposed on KeyedEncodingContainer and KeyedDecodingContainer so it should be possible to give actual implementations instead of calling into the defaults
  • Types should now be able to encode and decode from null values through single value containers

This is a long PR, but going through commit by commit should help. The first commit introduces these changes to the protocols; the second updates JSONEncoder and JSONDecoder; the third provides the same changes on PropertyListEncoder and PropertyListDecoder; etc.

This adds unit tests to confirm that decoding from null values works as expected.

Itai Ferber added 6 commits June 28, 2017 10:10
* Add encodeNil(forKey:)/encodeNil() for keyed/unkeyed encoding
  containers
* Add decodeNil(forKey:)/decodeNil() for keyed/unkeyed decoding
  containers
* Give default implementation of decodeIfPresent(forKey:)/
  decodeIfPresent(_:) on keyed/unkeyed decoding containers instead of
  decode(forKey:)/decode(_:)
* Expose all encode/decode methods on keyed encoding & decoding
  containers to allow overriding default methods (which were previously
  not forwarding)
* Add encodeNil/decodeNil variants on keyed and unkeyed containers
* Give implementations of decode() variants instead of decodeIfPresent()
* Add encodeNil/decodeNil variants on keyed and unkeyed containers
* Give implementations of decode() variants instead of decodeIfPresent()
To make it slightly easier to tell at a glance if a method is
implemented as part of API (public/open), shared implementation detail
(fileprivate), or implementation detail meaningful only to a given type
(private).
* Update {JSON,PropertyList}Decoder to allow superDecoder()s to wrap
  null value so current implementations of collections can decode
  contained objects from nil
* Eliminate null checks from unboxing in the general case (so types
  can at least attempt to decode from nil)
* Add unit tests to confirm this behavior
@itaiferber itaiferber requested a review from phausler June 28, 2017 18:30
@itaiferber
Copy link
Contributor Author

@swift-ci Please test

@itaiferber
Copy link
Contributor Author

This change will affect those who have already written Encoders/Decoders. CC @norio-nomura

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - baca811
Test requested by - @itaiferber

@itaiferber
Copy link
Contributor Author

This will need the corresponding changes made to swift-corelibs-foundation now that JSONEncoder is in there as well.

itaiferber pushed a commit to itaiferber/swift-corelibs-foundation that referenced this pull request Jun 28, 2017
Applies swift-corelibs-foundation changes to mirror
swiftlang/swift/pull/10667.
@itaiferber
Copy link
Contributor Author

swiftlang/swift-corelibs-foundation#1087
@swift-ci Please test Linux

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - baca811
Test requested by - @itaiferber

itaiferber pushed a commit to itaiferber/swift-corelibs-foundation that referenced this pull request Jun 28, 2017
Applies swift-corelibs-foundation changes to mirror
swiftlang/swift/pull/10667.
@itaiferber
Copy link
Contributor Author

Missed a Decimal fix for Linux.

@itaiferber
Copy link
Contributor Author

swiftlang/swift-corelibs-foundation#1087
@swift-ci Please test Linux

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - baca811
Test requested by - @itaiferber

itaiferber pushed a commit to itaiferber/swift-corelibs-foundation that referenced this pull request Jun 28, 2017
Applies swift-corelibs-foundation changes to mirror
swiftlang/swift/pull/10667.
@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - baca811
Test requested by - @itaiferber

itaiferber pushed a commit to itaiferber/swift-corelibs-foundation that referenced this pull request Jun 28, 2017
Applies swift-corelibs-foundation changes to mirror
swiftlang/swift/pull/10667.
@itaiferber
Copy link
Contributor Author

swiftlang/swift-corelibs-foundation#1087
@swift-ci Please test Linux

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - baca811
Test requested by - @itaiferber

itaiferber pushed a commit to itaiferber/swift-corelibs-foundation that referenced this pull request Jun 28, 2017
Applies swift-corelibs-foundation changes to mirror
swiftlang/swift/pull/10667.
@itaiferber
Copy link
Contributor Author

swiftlang/swift-corelibs-foundation#1087
@swift-ci Please test Linux

@itaiferber itaiferber requested a review from parkera June 29, 2017 20:05
Copy link
Contributor

@parkera parkera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

// EnhancedBool is a type which encodes either as a Bool or as nil.
_testEncodeFailure(of: EnhancedBool.true)
_testEncodeFailure(of: EnhancedBool.false)
_testEncodeFailure(of: EnhancedBool.fileNotFound)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 on test case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hehe, I told @phausler I was glad to finally be able to use this somewhere in real code.

@itaiferber itaiferber merged commit aa91b72 into swiftlang:master Jun 29, 2017
@itaiferber itaiferber deleted the codable-encode-decode-nil-changes branch June 29, 2017 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants