Closed lordzsolt closed 3 years ago
💯 I will see what I can do.
Hi. Any progress on this? I have the same problem with LossyArray. Don't know why T is restricted to Codable in current implementation. If LossyArray is implemented like this, it will support both Codable and Decodable.
@propertyWrapper
public struct LossyArray<T: Decodable>: Decodable {
private struct AnyDecodableValue: Decodable {}
private struct LossyDecodableValue<Value: Decodable>: Decodable {
let value: Value
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
value = try container.decode(Value.self)
}
}
public var wrappedValue: [T]
public init(wrappedValue: [T]) {
self.wrappedValue = wrappedValue
}
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var elements: [T] = []
while !container.isAtEnd {
do {
let value = try container.decode(LossyDecodableValue<T>.self).value
elements.append(value)
} catch {
_ = try? container.decode(AnyDecodableValue.self)
}
}
self.wrappedValue = elements
}
}
Don't know why T is restricted to Codable in current implementation.
Answering just this part. @LossyArray
supports encoding as well, which your code doesn't.
Some people might want that feature.
Keen to see this too. I think this should be possible to implement with extensions instead similar to how Equatable and Hashable are handled
extension DefaultCodable: Decodable where Default.DefaultValue: Decodable {
...
}
extension DefaultCodable: Encodable where Default.DefaultValue: Encodable {
...
}
Question
What are the options and thoughts on adding separate Decodable / Encodable support?
Problem
With the current implementation, everything relies on
T: Codable
.So for example, the following code will not compile, because
@DefaultEmptyArray
requiresResponseObject
to confirm toEncodable
as well.But I only care that
NetworkResponse
beDecodable
, I don't needEncodable
as well.In order to make it compile. I need to conform/implement
Encodable
onResponseObject
. It's trivial of course for the currentResponseObject
, but when the object is more complex and uses a custom decoder initializer, I'm left with 2 bad options:Encodable
implementation, which will never be usedencode(into:)
method, but then I lose compile time guarantee (which is the whole reason I'm usingBetterCodable
, so I don't have to write a bunch of uselessguard
s)Solutions
DefaultCodable<Strategy<T>>
would only requireT
to confirm to what the parent requires. In this caseNetworkResponse
only requiresDecodable
, soResponseObject
should only needDecodable
.ResponseObject
could be used in 2 places, one requiringDecodable
, the other one requiringEncodable
)DefaultDecodableEmptyArray
etc. etc.