-
Notifications
You must be signed in to change notification settings - Fork 80
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
How to deal with optional Date? #61
Comments
You can add it to your own project where you use BetterCodable. import Foundation
import BetterCodable
@propertyWrapper
public struct OptionalDateValue<Formatter: DateValueCodableStrategy> {
private let value: Formatter.RawValue?
public var wrappedValue: Date?
public init(wrappedValue: Date?) {
self.wrappedValue = wrappedValue
if let value = wrappedValue {
self.value = Formatter.encode(value)
} else {
self.value = nil
}
}
}
extension OptionalDateValue: Decodable where Formatter.RawValue: Decodable {
public init(from decoder: Decoder) throws {
self.value = try Formatter.RawValue?(from: decoder)
if let value = value {
self.wrappedValue = try Formatter.decode(value)
} else {
self.wrappedValue = nil
}
}
}
extension OptionalDateValue: Encodable where Formatter.RawValue: Encodable {
public func encode(to encoder: Encoder) throws {
try value.encode(to: encoder)
}
}
extension KeyedDecodingContainer {
func decode<T>(_ type: OptionalDateValue<T>.Type, forKey key: Self.Key) throws -> OptionalDateValue<T>
where T.RawValue: Decodable
{
try decodeIfPresent(type, forKey: key) ?? OptionalDateValue<T>(wrappedValue: nil)
}
func decodeIfPresent<T>(_ type: OptionalDateValue<T>.Type, forKey key: Self.Key) throws -> OptionalDateValue<T>
where T.RawValue == String
{
let stringOptionalValue = try decodeIfPresent(String.self, forKey: key)
guard let stringValue = stringOptionalValue else {
return .init(wrappedValue: nil)
}
let dateValue = try T.decode(stringValue)
return .init(wrappedValue: dateValue)
}
} And here are some tests: import XCTest
@testable import YOUR_PROJECT
import BetterCodable
class OptionalDateValueTests: XCTestCase {
struct TestData: Codable {
@OptionalDateValue<ISO8601WithFractionalSecondsStrategy>
var date: Date?
}
func testDecodingTimestamp() {
let jsonData = #"{"date": "1984-11-09T00:00:00.000Z"}"#.data(using: .utf8)!
do {
let data = try JSONDecoder().decode(TestData.self, from: jsonData)
print(data)
} catch {
XCTFail("shouldn't throw: \(error)")
}
}
func testDecodingNil() {
let jsonData = #"{"date": null}"#.data(using: .utf8)!
do {
let data = try JSONDecoder().decode(TestData.self, from: jsonData)
XCTAssertNil(data.date)
} catch {
XCTFail("shouldn't throw: \(error)")
}
}
func testDecodingNotPresent() {
let jsonData = #"{}"#.data(using: .utf8)!
do {
let data = try JSONDecoder().decode(TestData.self, from: jsonData)
XCTAssertNil(data.date)
} catch {
XCTFail("shouldn't throw: \(error)")
}
}
} |
I believe there is a bug. The extension OptionalDateValue: Encodable where Formatter.RawValue: Encodable {
public func encode(to encoder: Encoder) throws {
try wrappedValue.encode(to: encoder)
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tried:
@DATEvalue var cancellableUntil: Date?
This gives the error:
Property type 'Date?' does not match 'wrappedValue' type 'Date'
The text was updated successfully, but these errors were encountered: