Commit Graph

35 Commits

Author SHA1 Message Date
Itai Ferber
1e110b8f63 Restore decoder state after throwing on decode
Resolve SR-6408 by restoring the JSON/PlistDecoder stack if an error
is thrown after a container was pushed during encode.
2018-01-11 12:20:01 -08:00
Itai Ferber
57e356b1c4 Restore encoder state after throwing on encode
Resolve SR-6078 by restoring the JSON/PlistEncoder stack if an error
is thrown after a container was pushed during encode.
2018-01-11 12:20:01 -08:00
Maxim Moiseev
128092a7d6 Rename filterMap to compactMap 2017-12-18 09:22:41 -08:00
Max Moiseev
8ec6c45d2d Use filterMap to avoid deprecation warnings 2017-12-18 09:16:37 -08:00
Tony Parker
b87a8ea007 Add key encoding strategy to JSONEncoder 2017-11-15 16:44:28 -08:00
Itai Ferber
ae8f815f64 Use the concrete type parameter passed to JSON/plist decode 2017-11-09 13:06:00 -08:00
cpwhidden
997fe01809 [stdlib] Prevent type coercion from Bool to numerical types when decoding JSON and plist
JSONEncoder and PropertyListEncoder both use NSNumber to box Bool values.  An encoded Bool can be coerced to any numerical type during decoding because (false as NSNumber).intValue == 0.  As a remedy, all of the unbox(_:as:) methods of _JSONDecoder and _PlistDecoder for numerical types include a check that the value is not identical to either kCFBooleanTrue or kCFBooleanFalse, and throw a DecodingError._typeMismatch(at:expectation:) if this check fails.
2017-09-12 15:31:04 -05:00
Itai Ferber
ee39ff7f2f Allow top-level Codable strategy/type interception
At the top level, JSONEncoder/PropertyListEncoder (and the decoders) directly encoded values into an encoder instead of following the logic to box the values (and thus dispatch based on the type, potentially intercepting representations or applying strategies). This led to top-level values having a different representation than similar values throughout a payload.
2017-08-24 13:31:08 -07:00
Itai Ferber
fbdcbee7a2 Remove previous hack for SR-5206
As a temporary workaround for SR-5206, certain Foundation types which had custom behavior in JSONEncoder and JSONDecoder were granted special knowledge of those types internally in order to preserve strategies on encode/decode.

This replaces that special knowledge with a more general-purpose fix that works for all types and all encoders/decoders.
2017-08-02 14:11:29 -07:00
Itai Ferber
acadd6ca32 Merge pull request #10819 from itaiferber/encoders-eliminate-overlapping-exclusive-accesses
Remove overlapping exclusive accesses in encoders
2017-07-07 16:08:17 -07:00
Itai Ferber
18b523289d Remove overlapping exclusive accesses in encoders
{JSON,Plist}{Encoder,Decoder} had overlapping accesses which were supposed to be mutually exclusive in their `with(pushedKey:)` methods.

Removes those methods and the overlapping accesses.
2017-07-07 13:43:21 -07:00
Itai Ferber
9f7506f002 Allow application of JSON strategies in all cases
One of the limitations of not having conditional conformance at the
moment is that the implementation of `init(from:)` and `encode(to:)` on
types which require it is that failure to cast dependent types to
`Encodable` or `Decodable` is a runtime failure. There is no way to
statically guarantee that the wrapped type is `Encodable` or
`Decodable`.

As such, in those implementations, at best we can directly call
`(element as! Encodable).encode(to: encoder)`, or similar. However, this
encodes the element directly into an encoder, without giving the encoder
a chance to intercept the type. This is problematic for `JSONEncoder`
because it cannot apply a strategy if it doesn't get to intercept the
type.

This gives a temporary workaround for JSON strategies because of
internal Foundation knowledge.
2017-07-07 09:38:07 -07:00
Itai Ferber
e1007a2e3b Make coding paths non-optional
For the benefit of unkeyed containers, coding paths currently contain optional `CodingKey`s — unkeyed containers are allowed to report a `nil` key in a path. However, this is unhelpful for debugging purposes, or inspecting the coding path for context, since any unkeyed container simply reports `nil`, whether it’s at index 1 or 1000.

Now all containers are required to report a non-optional CodingKey for their segment of the coding path, and coding paths are now exposed as `[CodingKey]`.
2017-06-30 12:43:40 -07:00
Itai Ferber
aa91b7273d Merge pull request #10667 from itaiferber/codable-encode-decode-nil-changes
Optionality updates to Codable API
2017-06-29 13:15:25 -07:00
Itai Ferber
b40c0bd3db Merge pull request #10685 from itaiferber/codingerror-bridging-and-conveniences
EncodingError/DecodingError bridging fixes and conveniences
2017-06-29 10:05:35 -07:00
Itai Ferber
cf0ebc195d Expose underlying serialization errors
If JSONSerialization or PropertyListSerialization throw errors during encoding or decoding, the error should be exposed as an EncodingError or DecodingError
2017-06-28 15:10:19 -07:00
Itai Ferber
850b21f50d JSONEncoder data encoding strategy tweaks
* Add deferredToData strategy on encode and decode
* Rename base64{Encode,Decode} to base64 (missed this in previous fixes)
* Add unit test to confirm behavior
2017-06-28 14:17:23 -07:00
Itai Ferber
baca811820 Ensure values are decodable 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
2017-06-28 11:23:22 -07:00
Itai Ferber
692a893e16 Allow superDecoder to wrap null values
* Update {JSON,PropertyList}Decoder to allow superDecoder()s to wrap
  null value so current implementations of collections can decode
  contained objects from nil
2017-06-28 10:10:21 -07:00
Itai Ferber
bf1d2a745e Accessibility cleanup in {JSON,Plist}Encoder
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).
2017-06-28 10:10:21 -07:00
Itai Ferber
f20d4425e5 Update JSONEncoder with proposed nil changes
* Add encodeNil/decodeNil variants on keyed and unkeyed containers
* Give implementations of decode() variants instead of decodeIfPresent()
2017-06-28 10:10:21 -07:00
Ian Partridge
399caebf11 JSONEncoder: Typo in documentation of encode<T>(T) 2017-06-27 10:18:08 +01:00
Itai Ferber
da27019800 Merge pull request #10539 from itaiferber/foundation-json-decimal
Encode Decimal as a numeric value in JSON
2017-06-23 15:41:51 -07:00
Itai Ferber
07d396b712 Encode Decimal as a numeric value in JSON
Allow JSONEncoder/JSONDecoder to intercept Decimal values so they get
a numeric representation in JSON (instead of their default keyed
implementation).
2017-06-23 13:02:13 -07:00
Itai Ferber
184efb085c Allow classes to share an Encoder with superclass
On encode, we previously treated every container request as a push;
instead, we should allow the same container type to be requested
multiple times so a class can pass its Encoder directly to its
superclass if it needs to.
2017-06-22 15:45:02 -07:00
Mishal Shah
c5ff1f2cac Update master to build with Xcode 9 beta 1, OS X 10.13, iOS 11, tvOS 11, and watchOS 4 SDKs. 2017-06-14 16:20:35 -07:00
Itai Ferber
48d183e62a Allow SingleValueContainers to decode collections
SingleValueDecondingContainers in JSON and Plist previously held the
assertion that attempting to decode an array or dictionary from them
was a type mismatch (since those represented unkeyed and keyed
containers, respectively). This assertion is no longer true, though,
since encode<T : Encodable>(_:) and decode<T : Decodable>(_:) allow
you to do just that.

This lifts the assertion and adds unit tests to both implementations to
ensure this works. (Addresses https://bugs.swift.org/browse/SR-5089)
2017-06-14 11:14:20 -07:00
Itai Ferber
d16297dad5 Introduces changes to Codable stdlib API
* Adds conformance of Optional to Codable
* encode(...) arguments are no longer Optional; Optional values go
  through generic version
* encodeIfPresent added to KeyedEncodingContainerProtocol to mirror
  decodeIfPresent
* JSONEncoder and PropertyListEncoder updated to reflect these changes
2017-05-22 09:29:36 -07:00
Itai Ferber
012ea9373b Add Codable conformance to common Foundation types
Add conformances + unit tests for

* CGFloat
* AffineTransform
* Calendar
* CharacterSet
* DateComponents
* DateInterval
* Decimal
* IndexPath
* IndexSet
* Locale
* Measurement
* NSRange
* PersonNameComponents
* TimeZone
* URL
* UUID

along with some unit tests for each.
2017-05-18 07:56:03 -07:00
Michael Ilseman
75c476b984 Revert "Add Codable conformance to common Foundation types"
This reverts commit dee889f4d0.
2017-05-17 11:56:31 -07:00
Itai Ferber
dee889f4d0 Add Codable conformance to common Foundation types
Add conformances + unit tests for
* CGFloat
* AffineTransform
* Calendar
* CharacterSet
* DateComponents
* DateInterval
* Decimal
* IndexPath
* IndexSet
* Locale
* Measurement
* NSRange
* PersonNameComponents
* TimeZone
* URL
* UUID

along with some unit tests for each.
2017-05-16 16:57:46 -07:00
Itai Ferber
3a9d888972 Fix JSON+plist codingPaths for nested values
codingPath more often than not actually needs to be copied, not just
referenced. This makes a big difference for nested containers and
subobjects, which were getting the wrong codingPath values when asking
for them.

This also adds unit tests for JSONEncoder and PropertyListEncoder to
confirm expected behavior.
2017-05-11 17:02:46 -07:00
Itai Ferber
3a6dbebba0 Fix container assertion in referencing encoders 2017-05-03 13:12:54 -07:00
Itai Ferber
813d756573 Referencing encoders should use parent codingPath 2017-05-03 09:49:10 -07:00
Itai Ferber
2ce58c1eb3 Add JSON and property list encoders and decoders
* Integrate {JSON,PropertyList}{Encoder,Decoder} types to facilitate
  encoding types in JSON and property list formats
* Adds Foundation-specific extensions to allow errors exposed from the
  stdlib to bridge to NSErrors
2017-04-28 23:38:25 -07:00