Skip to content

Instantly share code, notes, and snippets.

@marksands
Created September 11, 2020 15:53
Show Gist options
  • Save marksands/243cc6963aa4cf23a4d12ecc2b51f44a to your computer and use it in GitHub Desktop.
Save marksands/243cc6963aa4cf23a4d12ecc2b51f44a to your computer and use it in GitHub Desktop.
An Optional DateValue for BetterCodable, by duplicating existing types :P
public protocol OptionalDateValueCodableStrategy {
associatedtype RawValue: Codable
static func decode(_ value: RawValue?) throws -> Date?
static func encode(_ date: Date?) -> RawValue?
}
@propertyWrapper
public struct OptionalDateValue<Formatter: OptionalDateValueCodableStrategy>: Codable {
private let value: Formatter.RawValue?
public var wrappedValue: Date?
public init(wrappedValue: Date?) {
self.wrappedValue = wrappedValue
self.value = Formatter.encode(wrappedValue)
}
public init(from decoder: Decoder) throws {
self.value = try? Formatter.RawValue(from: decoder)
self.wrappedValue = try? Formatter.decode(value)
}
public func encode(to encoder: Encoder) throws {
try value.encode(to: encoder)
}
}
public struct OptionalTimestampStrategy: OptionalDateValueCodableStrategy {
public static func decode(_ value: TimeInterval?) throws -> Date? {
return value.map { Date(timeIntervalSince1970: $0) }
}
public static func encode(_ date: Date?) -> TimeInterval? {
return date?.timeIntervalSince1970
}
}
struct Fixture: Codable {
@OptionalDateValue<OptionalTimestampStrategy> var timestamp: Date?
}
func testDecodingTimestamp() {
let jsonData = #"{"timestamp": 851042397.0}"#.data(using: .utf8)!
let fixture = try! JSONDecoder().decode(Fixture.self, from: jsonData)
assert(fixture.timestamp == Date(timeIntervalSince1970: 851042397))
assert(fixture.timestamp?.timeIntervalSince1970 == 851042397)
}
func testDecodingNil() {
let jsonData = #"{"timestamp": null}"#.data(using: .utf8)!
let fixture = try! JSONDecoder().decode(Fixture.self, from: jsonData)
assert(fixture.timestamp == nil)
}
testDecodingTimestamp()
testDecodingNil()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment