Skip to content

Commit

Permalink
Fix compilation on Linux
Browse files Browse the repository at this point in the history
swift-corelibs-foundation doesn't support `.withFractionalSeconds`.
  • Loading branch information
lilyball committed Feb 26, 2018
1 parent 8f476cb commit 05586c9
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
* Add a couple of convenience static methods to `JSON` that mimic the enum cases: `JSON.int(_:)` and `JSON.cgFloat(_:)`. These can be used when `JSON(_:)` triggers too much type complexity. Also add a `JSON(_:)` override for `CGFloat`.
* Add `JSON.Encoder.keyEncodingStrategy`. This is very similar to Swift 4.1's `JSONEncoder.keyEncodingStrategy`, although by default it won't apply to any nested values of type `JSON` or `JSONObject` (there's another option `applyKeyEncodingStrategyToJSONObject` that controls this).
* Add `JSON.Decoder.keyDecodingStrategy`. This is very similar to Swift 4.1's `JSONDecoder.keyDecodingStrategy`, although by default it won't apply to decoding any values of type `JSON` or `JSONObject` (there's another option `applyKeyDecodingStrategyToJSONObject` that controls this).
* Add `JSON.Encoder.dateEncodingStrategy`. This is very similar to `JSONEncoder.dateEncodingStrategy` except it includes another case for encoding ISO8601-formatted dates with fractional seconds.
* Add `JSON.Decoder.dateDecodingStrategy`. This is very similar to `JSONDecoder.dateDecodingStrategy` except it includes another case for decoding ISO8601-formatted dates with fractional seconds.
* Add `JSON.Encoder.dateEncodingStrategy`. This is very similar to `JSONEncoder.dateEncodingStrategy` except it includes another case for encoding ISO8601-formatted dates with fractional seconds (on Apple platforms).
* Add `JSON.Decoder.dateDecodingStrategy`. This is very similar to `JSONDecoder.dateDecodingStrategy` except it includes another case for decoding ISO8601-formatted dates with fractional seconds (on Apple platforms).

#### v3.0.2 (2018-02-21)

Expand Down
48 changes: 35 additions & 13 deletions Sources/Coders/SwiftDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,19 @@ extension _JSONDecoder: SingleValueDecodingContainer {
fatalError("ISO8601DateFormatter is not available on this platform")
}
case .iso8601WithFractionalSeconds:
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
let str = try wrapTypeMismatch(value.asJSON.getString())
guard let date = _iso8601FractionalSecondsFormatter.date(from: str) ?? _iso8601Formatter.date(from: str) else {
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Expected date string to be ISO8601-formatted.")
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
let str = try wrapTypeMismatch(value.asJSON.getString())
guard let date = _iso8601FractionalSecondsFormatter.date(from: str) ?? _iso8601Formatter.date(from: str) else {
throw DecodingError.dataCorruptedError(in: self, debugDescription: "Expected date string to be ISO8601-formatted.")
}
return date as! T
} else {
fatalError("ISO8601DateFormatter.Options.withFractionalSeconds is not available on this platform")
}
return date as! T
} else {
#else
fatalError("ISO8601DateFormatter.Options.withFractionalSeconds is not available on this platform")
}
#endif
case .formatted(let formatter):
let str = try wrapTypeMismatch(value.asJSON.getString())
guard let date = formatter.date(from: str) else {
Expand Down Expand Up @@ -775,6 +779,7 @@ extension JSON.Decoder {
@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
case iso8601

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
/// Decode the `Date` as an ISO8601-formatted string (in RFC 3339 format) with fractional
/// seconds.
///
Expand All @@ -784,6 +789,21 @@ extension JSON.Decoder {
/// strings with or without fractional seconds.
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
case iso8601WithFractionalSeconds
#else
// swift-corelibs-foundation doesn't support `.withFractionalSeconds`. We still declare the
// case though or we're in trouble trying to match it.
/// Decode the `Date` as an ISO8601-formatted string (in RFC 3339 format) with fractional
/// seconds.
///
/// This matches strings like `"1985-04-12T23:20:50.52Z"`.
///
/// - Note: If the decode fails, it will try again with `.iso8601`. This means it will match
/// strings with or without fractional seconds.
///
/// - Important: This case is not supported on non-Apple platforms.
@available(*, unavailable, message: "This case is not supported on non-Apple platforms")
case iso8601WithFractionalSeconds
#endif

/// Decode the `Date` as a string parsed by the given formatter.
case formatted(DateFormatter)
Expand Down Expand Up @@ -854,9 +874,11 @@ internal var _iso8601Formatter: ISO8601DateFormatter = {
return formatter
}()

@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
internal var _iso8601FractionalSecondsFormatter: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
return formatter
}()
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
internal var _iso8601FractionalSecondsFormatter: ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
return formatter
}()
#endif
27 changes: 22 additions & 5 deletions Sources/Coders/SwiftEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,16 @@ extension _JSONEncoder: SingleValueEncodingContainer {
fatalError("ISO8601DateFormatter is not available on this platform")
}
case .iso8601WithFractionalSeconds:
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
let str = _iso8601FractionalSecondsFormatter.string(from: date)
try encode(str)
} else {
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
if #available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
let str = _iso8601FractionalSecondsFormatter.string(from: date)
try encode(str)
} else {
fatalError("ISO8601DateFormatter.Options.withFractionalSeconds is not available on this platform")
}
#else
fatalError("ISO8601DateFormatter.Options.withFractionalSeconds is not available on this platform")
}
#endif
case .formatted(let formatter):
let str = formatter.string(from: date)
try encode(str)
Expand Down Expand Up @@ -920,12 +924,25 @@ extension JSON.Encoder {
@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
case iso8601

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
/// Encode the `Date` as an ISO8601-formatted string (in RFC 3339 format) with fractional
/// seconds.
///
/// This encodes strings like `"1985-04-12T23:20:50.523Z"`.
@available(macOS 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
case iso8601WithFractionalSeconds
#else
// swift-corelibs-foundation doesn't support `.withFractionalSeconds`. We still declare the
// case though or we're in trouble trying to match it.
/// Encode the `Date` as an ISO8601-formatted string (in RFC 3339 format) with fractional
/// seconds.
///
/// This encodes strings like `"1985-04-12T23:20:50.523Z"`.
///
/// - Important: This case is not supported on non-Apple platforms.
@available(*, unavailable, message: "This case is not supported on non-Apple platforms")
case iso8601WithFractionalSeconds
#endif

/// Encode the `Date` as a string formatted by the given formatter.
case formatted(DateFormatter)
Expand Down
2 changes: 2 additions & 0 deletions Tests/PMJSONTests/SwiftDecoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ final class SwiftDecoderTests: XCTestCase {
XCTAssertEqual(date, Date(timeIntervalSinceReferenceDate: 541317349))
}

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
func testDecodeDateISO8601FractionalSeconds() throws {
var decoder = JSON.Decoder()
Expand All @@ -408,6 +409,7 @@ final class SwiftDecoderTests: XCTestCase {
XCTAssertEqual(date, Date(timeIntervalSinceReferenceDate: 541317349))
}
}
#endif

func testDecodeDateFormatted() throws {
var decoder = JSON.Decoder()
Expand Down
2 changes: 2 additions & 0 deletions Tests/PMJSONTests/SwiftEncoderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -771,13 +771,15 @@ final class SwiftEncoderTests: XCTestCase {
XCTAssertEqual(json, "2018-02-26T05:55:49Z")
}

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)
func testEncodeDateISO8601FractionalSeconds() throws {
var encoder = JSON.Encoder()
encoder.dateEncodingStrategy = .iso8601WithFractionalSeconds
let json = try encoder.encodeAsJSON(Date(timeIntervalSinceReferenceDate: 541317349.605))
XCTAssertEqual(json, "2018-02-26T05:55:49.605Z")
}
#endif

func testEncodeDateFormatted() throws {
var encoder = JSON.Encoder()
Expand Down

0 comments on commit 05586c9

Please sign in to comment.