1 year ago
#314465
JacobCXDev
Composing property wrappers in Swift with Vapor + Fluent
I've implemented a system to automatically generate Fluent's Migration
s by reflecting 'registered' Model
s, saving the boilerplate of creating them manually. To achieve this, I must allow the specification of any DatabaseSchema.FieldConstraint
s directly in the Model
. Since I'm unable to inherit from FieldProperty
, etc. as they're marked as final
, this system requires that I use nested property wrappers like so:
final class User: Model {
ā¦
@Constrained(.required)
@Field(key: .userForename)
var forename: String
ā¦
}
Inside the implementation of the @Constrained
property wrapper, I have the following code:
@propertyWrapper
class ConstrainedProperty<T, U>: AnyConstrainedProperty where T: Fields, U: AnyProperty {
// MARK: - Properties
// MARK: Property Wrapper
var projectedValue: ConstrainedProperty<T, U> { self }
var wrappedValue: U
// MARK: Stored
var constraints: [DatabaseSchema.FieldConstraint]
// MARK: - Initialisers
init(wrappedValue: U, _ constraints: DatabaseSchema.FieldConstraint...) {
self.wrappedValue = wrappedValue
self.constraints = constraints
}
}
// MARK: - Fields
extension Fields {
typealias Constrained<T> = ConstrainedProperty<Self, T> where T: Property
}
Since wrappedValue
is Optional
, wrappedValue
never being initialised is not an issue and the code compiles just fine. However, if I want wrappedValue
not to be Optional
and for it to be provided a value when the property wrapper is initialised, the Swift Evolution proposal (SE-0258) states that I should use the following code:
var wrappedValue: T
var constraints: [DatabaseSchema.FieldConstraint]
init(wrappedValue: T, _ constraints: DatabaseSchema.FieldConstraint...) {
self.wrappedValue = wrappedValue
self.constraints = constraints
}
(T
should be FieldProperty<Model, Value>
where Model == Self
and Value: Codable
.)
Unfortunately, the issue is that Swift complains:
It doesn't appear that Swift's passing the value of the nested property wrapper to the wrappedValue
parameter of the initialiser of the outer property wrapper automatically ā I inferred from the proposal that it should; how else would property wrapper composition work š
?
swift
codable
vapor
property-wrapper
vapor-fluent
0 Answers
Your Answer