-
-
Notifications
You must be signed in to change notification settings - Fork 50
custom Codable init(from:)
method causing incorrect reflection
#161
Comments
After digging into this a bit more, the issue seems unavoidable. The problem is that The problem is that TL;DR is that the algorithm used to power Codable reflection is not compatible with setting default values in a custom Fortunately Codable reflection is protocol based and you can work around this issue by simply implementing the Until Swift gets better reflection, this is really our best option. The alternative to using Codable-based reflection is having every model implement Also worth noting that the init(from decoder: Decoder)throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.email = try container.decode(String.self, forKey: .email)
if container.contains(.active) {
self.active = try container.decode(Bool.self, forKey: .active)
} else {
self.active = false
}
} |
Here's an example of how to implement the custom reflection methods for desired effect. struct User: Reflectable, Codable {
var email: String
var active: Bool
static func reflectProperty<T>(forKey keyPath: KeyPath<User, T>) throws -> ReflectedProperty? {
let name: String
switch keyPath {
case \User.email: name = "email"
case \User.active: name = "active"
default: return nil
}
return .init(T.self, at: [name])
}
init(from decoder: Decoder)throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.email = try container.decode(String.self, forKey: .email)
self.active = try container.decodeIfPresent(Bool.self, forKey: .active) ?? false
}
}
try XCTAssertEqual(User.reflectProperties().description, "[email: String, active: Bool]")
try XCTAssertEqual(User.reflectProperty(forKey: \.email)?.description ?? "n/a", "email: String")
try XCTAssertEqual(User.reflectProperty(forKey: \.active)?.description ?? "n/a", "active: Bool") |
Thanks @tanner0101 ! The custom implementation of reflectProperty seems to be the most appropriate way to deal with it, though I like the I think I'll go with the |
Moving vapor/fluent#524 here.
The text was updated successfully, but these errors were encountered: