CodableWrappers
CodableWrappers copied to clipboard
`@EncodeNulls` and `@OptionalEncoding<X>` can’t be used together
I want to write something like this:
@Immutable @EncodeNulls @OptionalEncoding<DateFormatterEncoding<RFC3339DateCoder>> var completedOn: Date?
However, currently that doesn’t work. I did try a few variations but from what I could tell we don’t have the functionality to do this yet.
@jayrhynas kindly helped me out and we were able to come up with:
struct Model: Codable {
@Immutable @EncodeOptionalNulls @OptionalEncoding<DateFormatterEncoding<RFC3339DateCoder>> var completedOn: Date?
}
/// Encodes an optional nil value in a singleValueContainer using `encodeNil` rather than it being omitted.
typealias EncodeOptionalNulls<T: Encodable & OptionalEncodingWrapper> = EncodingUses<OptionalNullStaticEncoder<T>>
struct OptionalNullStaticEncoder<T: Encodable>: StaticEncoder, AnyNullEncoder where T: OptionalEncodingWrapper {
static func encode(value: T, to encoder: Encoder) throws {
if case Optional<Any>.none = value.wrappedValue as Any {
var container = encoder.singleValueContainer()
try container.encodeNil()
return
}
try value.encode(to: encoder)
}
}
struct RFC3339DateCoder: DateFormatterStaticCoder {
static let dateFormatter = with(DateFormatter()) {
$0.timeZone = TimeZone(secondsFromGMT: 0)
$0.locale = Locale(identifier: "en_US_POSIX")
$0.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
}
}
I’m not sure if the above could be simplified or made so that an additional StaticEncoder struct is not needed?