Skip to content

Commit bf390f1

Browse files
committed
more robust platform checks
1 parent 072553a commit bf390f1

File tree

3 files changed

+51
-52
lines changed

3 files changed

+51
-52
lines changed

Sources/AWSLambdaEvents/Utils/DateWrappers.swift

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,27 @@ public struct ISO8601Coding: Decodable, Sendable {
3030
let container = try decoder.singleValueContainer()
3131
let dateString = try container.decode(String.self)
3232

33-
struct InvalidDateError: Error {}
34-
35-
do {
36-
self.wrappedValue = try Self.parseISO8601(dateString: dateString)
37-
} catch {
33+
guard let date = Self.parseISO8601(dateString: dateString) else {
3834
throw DecodingError.dataCorruptedError(
3935
in: container,
4036
debugDescription:
4137
"Expected date to be in ISO8601 date format, but `\(dateString)` is not in the correct format"
4238
)
4339
}
40+
41+
self.wrappedValue = date
4442
}
4543

46-
private static func parseISO8601(dateString: String) throws -> Date {
44+
private static func parseISO8601(dateString: String) -> Date? {
45+
#if canImport(FoundationEssentials)
4746
if #available(macOS 12.0, *) {
48-
return try Date(dateString, strategy: .iso8601)
47+
return try? Date(dateString, strategy: .iso8601)
4948
} else {
50-
#if !canImport(FoundationEssentials)
51-
guard let date = Self.dateFormatter.date(from: dateString) else {
52-
throw InvalidDateError()
53-
}
54-
return date
55-
#endif
56-
57-
fatalError("ISO8601Coding is not supported on this platform - this should never happen")
49+
return Self.dateFormatter.date(from: dateString)
5850
}
51+
#else
52+
return Self.dateFormatter.date(from: dateString)
53+
#endif
5954
}
6055

6156
#if !canImport(FoundationEssentials)
@@ -81,35 +76,35 @@ public struct ISO8601WithFractionalSecondsCoding: Decodable, Sendable {
8176
let container = try decoder.singleValueContainer()
8277
let dateString = try container.decode(String.self)
8378

84-
struct InvalidDateError: Error {}
85-
86-
do {
87-
self.wrappedValue = try Self.parseISO8601WithFractionalSeconds(dateString: dateString)
88-
} catch {
79+
guard let date = Self.parseISO8601WithFractionalSeconds(dateString: dateString) else {
8980
throw DecodingError.dataCorruptedError(
9081
in: container,
9182
debugDescription:
9283
"Expected date to be in ISO8601 date format with fractional seconds, but `\(dateString)` is not in the correct format"
9384
)
9485
}
86+
87+
self.wrappedValue = date
9588
}
9689

97-
private static func parseISO8601WithFractionalSeconds(dateString: String) throws -> Date {
90+
private static func parseISO8601WithFractionalSeconds(dateString: String) -> Date? {
91+
#if canImport(FoundationEssentials)
9892
if #available(macOS 12.0, *) {
99-
return try Date(dateString, strategy: Self.iso8601WithFractionalSeconds)
93+
return try? Date(dateString, strategy: Self.iso8601WithFractionalSeconds)
10094
} else {
101-
#if !canImport(FoundationEssentials)
102-
guard let date = Self.dateFormatter.date(from: dateString) else {
103-
throw InvalidDateError()
104-
}
105-
return date
106-
#endif
107-
108-
fatalError("ISO8601Coding is not supported on this platform - this should never happen")
95+
return Self.dateFormatter.date(from: dateString)
10996
}
97+
#else
98+
return Self.dateFormatter.date(from: dateString)
99+
#endif
110100
}
111101

112-
#if !canImport(FoundationEssentials)
102+
#if canImport(FoundationEssentials)
103+
@available(macOS 12.0, *)
104+
private static var iso8601WithFractionalSeconds: Date.ISO8601FormatStyle {
105+
Date.ISO8601FormatStyle(includingFractionalSeconds: true)
106+
}
107+
#else
113108
private static var dateFormatter: DateFormatter {
114109
let formatter = DateFormatter()
115110
formatter.locale = Locale(identifier: "en_US_POSIX")
@@ -118,11 +113,6 @@ public struct ISO8601WithFractionalSecondsCoding: Decodable, Sendable {
118113
return formatter
119114
}
120115
#endif
121-
122-
@available(macOS 12.0, *)
123-
private static var iso8601WithFractionalSeconds: Date.ISO8601FormatStyle {
124-
Date.ISO8601FormatStyle(includingFractionalSeconds: true)
125-
}
126116
}
127117

128118
@propertyWrapper
@@ -138,11 +128,15 @@ public struct RFC5322DateTimeCoding: Decodable, Sendable {
138128
let string = try container.decode(String.self)
139129

140130
do {
131+
#if canImport(FoundationEssentials)
141132
if #available(macOS 12.0, *) {
142133
self.wrappedValue = try Date(string, strategy: Self.rfc5322DateParseStrategy)
143134
} else {
144135
self.wrappedValue = try Self.rfc5322DateParseStrategy.parse(string)
145136
}
137+
#else
138+
self.wrappedValue = try Self.rfc5322DateParseStrategy.parse(string)
139+
#endif
146140
} catch {
147141
throw DecodingError.dataCorruptedError(
148142
in: container,
@@ -152,6 +146,7 @@ public struct RFC5322DateTimeCoding: Decodable, Sendable {
152146
}
153147
}
154148

155-
private static let rfc5322DateParseStrategy = RFC5322DateParseStrategy(calendar: Calendar(identifier: .gregorian))
156-
149+
private static var rfc5322DateParseStrategy: RFC5322DateParseStrategy {
150+
RFC5322DateParseStrategy(calendar: Calendar(identifier: .gregorian))
151+
}
157152
}

Sources/AWSLambdaEvents/Utils/RFC5322DateParseStrategy.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,10 @@ struct RFC5322DateParseStrategy {
178178
}
179179
}
180180

181+
#if canImport(FoundationEssentials)
181182
@available(macOS 12.0, *)
182183
extension RFC5322DateParseStrategy: ParseStrategy {}
184+
#endif
183185

184186
extension IteratorProtocol where Self.Element == UInt8 {
185187
mutating func expect(_ expected: UInt8) -> Bool {

Tests/AWSLambdaEventsTests/Utils/RFC5322DateParseStrategyTests.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ import XCTest
1717
@testable import AWSLambdaEvents
1818

1919
class RFC5322DateParseStrategyTests: XCTestCase {
20+
let strategy = RFC5322DateParseStrategy(calendar: Calendar(identifier: .gregorian))
21+
2022
func testSuccess() {
2123
let input = "Fri, 26 Jun 2020 03:04:03 -0500 (CDT)"
22-
let date = try? Date(input, strategy: RFC5322DateParseStrategy())
24+
let date = try? strategy.parse(input)
2325
XCTAssertNotNil(date)
2426
XCTAssertEqual(date?.description, "2020-06-26 08:04:03 +0000")
2527
}
@@ -40,71 +42,71 @@ class RFC5322DateParseStrategyTests: XCTestCase {
4042
]
4143

4244
for (input, expected) in dates {
43-
let date = try Date(input, strategy: RFC5322DateParseStrategy())
45+
let date = try strategy.parse(input)
4446
XCTAssertEqual(date.description, expected)
4547
}
4648
}
4749

4850
func testWithLeadingDayName() throws {
4951
let input = "Fri, 26 Jun 2020 03:04:03 -0500 (CDT)"
50-
let date = try Date(input, strategy: RFC5322DateParseStrategy())
52+
let date = try strategy.parse(input)
5153
XCTAssertEqual("2020-06-26 08:04:03 +0000", date.description)
5254
}
5355

5456
func testEmptyString() {
5557
let input = ""
56-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
58+
XCTAssertThrowsError(try strategy.parse(input))
5759
}
5860

5961
func testWithInvalidDay() {
6062
let input = "Fri, 36 Jun 2020 03:04:03 -0500 (CDT)"
61-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
63+
XCTAssertThrowsError(try strategy.parse(input))
6264
}
6365

6466
func testWithInvalidMonth() {
6567
let input = "Fri, 26 XXX 2020 03:04:03 -0500 (CDT)"
66-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
68+
XCTAssertThrowsError(try strategy.parse(input))
6769
}
6870

6971
func testWithInvalidHour() {
7072
let input = "Fri, 26 Jun 2020 48:04:03 -0500 (CDT)"
71-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
73+
XCTAssertThrowsError(try strategy.parse(input))
7274
}
7375

7476
func testWithInvalidMinute() {
7577
let input = "Fri, 26 Jun 2020 03:64:03 -0500 (CDT)"
76-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
78+
XCTAssertThrowsError(try strategy.parse(input))
7779
}
7880

7981
func testWithInvalidSecond() {
8082
let input = "Fri, 26 Jun 2020 03:04:64 -0500 (CDT)"
81-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
83+
XCTAssertThrowsError(try strategy.parse(input))
8284
}
8385

8486
func testWithGMT() throws {
8587
let input = "Fri, 26 Jun 2020 03:04:03 GMT"
86-
let date = try Date(input, strategy: RFC5322DateParseStrategy())
88+
let date = try strategy.parse(input)
8789
XCTAssertEqual("2020-06-26 03:04:03 +0000", date.description)
8890
}
8991

9092
func testWithUTC() throws {
9193
let input = "Fri, 26 Jun 2020 03:04:03 UTC"
92-
let date = try Date(input, strategy: RFC5322DateParseStrategy())
94+
let date = try strategy.parse(input)
9395
XCTAssertEqual("2020-06-26 03:04:03 +0000", date.description)
9496
}
9597

9698
func testPartialInput() {
9799
let input = "Fri, 26 Jun 20"
98-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
100+
XCTAssertThrowsError(try strategy.parse(input))
99101
}
100102

101103
func testPartialTimezone() {
102104
let input = "Fri, 26 Jun 2020 03:04:03 -05"
103-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
105+
XCTAssertThrowsError(try strategy.parse(input))
104106
}
105107

106108
func testInvalidTimezone() {
107109
let input = "Fri, 26 Jun 2020 03:04:03 -05CDT (CDT)"
108-
XCTAssertThrowsError(try Date(input, strategy: RFC5322DateParseStrategy()))
110+
XCTAssertThrowsError(try strategy.parse(input))
109111
}
110112
}

0 commit comments

Comments
 (0)