this repo has no description
at main 86 lines 3.2 kB view raw
1// 2// DateEncodingStrategy.swift 3// URLQueryItemCoder 4// 5// Created by Kyle Hughes on 3/6/23. 6// 7 8import Foundation 9 10/// The strategy to use for encoding `Date` values. 11public enum DateEncodingStrategy { 12 /// Encode the `Date` as a custom value encoded by the given closure. 13 /// 14 /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic 15 /// container in its place. 16 case custom((Date, Encoder) throws -> Void) 17 /// Defer to `Date` for choosing an encoding. 18 /// 19 /// This is the default strategy. 20 case deferredToDate 21 /// Encode the `Date` as a string formatted by the given formatter. 22 case formatted(DateFormatter) 23 /// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). 24 case iso8601 25 /// Encode the `Date` as UNIX millisecond timestamp (as a number). 26 case millisecondsSince1970 27 /// Encode the `Date` as a UNIX timestamp (as a number). 28 case secondsSince1970 29 30 // MARK: Public Static Interface 31 32 /// The default encoding strategy. 33 /// 34 /// Equals `.deferredToDate`. 35 public static let `default`: DateEncodingStrategy = .deferredToDate 36 37 // MARK: Internal Instance Interface 38 39 internal func encode( 40 _ date: Date, 41 at codingPath: [any CodingKey], 42 using configuration: EncodingStrategies 43 ) throws -> EncodingContainer { 44 switch self { 45 case let .custom(closure): 46 let lowLevelEncoder = LowLevelEncoder(codingPath: codingPath, configuration: configuration) 47 48 try closure(date, lowLevelEncoder) 49 50 guard let container = lowLevelEncoder.container else { 51 preconditionFailure("Date was not encoded by low level encoder.") 52 } 53 54 return container 55 case let .formatted(formatter): 56 let container = EncodingContainer.SingleValue(codingPath: codingPath, configuration: configuration) 57 58 try container.encode(formatter.string(from: date)) 59 60 return .singleValue(container) 61 case .iso8601: 62 let formatter = ISO8601DateFormatter() 63 formatter.formatOptions = .withInternetDateTime 64 65 let container = EncodingContainer.SingleValue(codingPath: codingPath, configuration: configuration) 66 67 try container.encode(formatter.string(from: date)) 68 69 return .singleValue(container) 70 case .deferredToDate: 71 return try .encodeByDeferringToType(date, at: codingPath, using: configuration) 72 case .millisecondsSince1970: 73 let container = EncodingContainer.SingleValue(codingPath: codingPath, configuration: configuration) 74 75 try container.encode(date.timeIntervalSince1970 * 1_000) 76 77 return .singleValue(container) 78 case .secondsSince1970: 79 let container = EncodingContainer.SingleValue(codingPath: codingPath, configuration: configuration) 80 81 try container.encode(date.timeIntervalSince1970) 82 83 return .singleValue(container) 84 } 85 } 86}