How does this Vapor Fluent Syntax work?

I am staring at Fluent code but I am somehow unable to find what I am looking for, so maybe someone here can point me into the right direction?

Basically I want to implement my own filter expression over remote objects. So I looked at Fluent for inspiration and saw this in the documentation:

// An example of Fluent's query API.
let planets = try await Planet.query(on: database)
    .filter(\.$type == .gasGiant)
    .sort(\.$name)
    .with(\.$star)
    .all()

Specifically .filter(\.$type == .gasGiant): what would the function signature of filter be? And what kind of syntax is \.$type? I think I read most of the Swift Language Book by now, but I don't think I've seen this? What kind of language features would I need to familiarize myself if I want to implement something similar?

I believe what you are looking at is this definition of filter:

extension QueryBuilder {
    @discardableResult
    public func filter(_ filter: ModelValueFilter<Model>) -> Self {
        self.filter(Model.self, filter)
    }

    ...

and this definition of ==:

public func == <Model, Field>(lhs: KeyPath<Model, Field>, rhs: Field.Value) -> ModelValueFilter<Model>
    where Model: Fields, Field: QueryableProperty
{
    lhs == Field.queryValue(rhs)
}

which calls this definition of ==:

public func == <Model, Field>(lhs: KeyPath<Model, Field>, rhs: DatabaseQuery.Value) -> ModelValueFilter<Model>
    where Model: Fields, Field: QueryableProperty
{
    .init(lhs, .equal, rhs)
}

And here is the definition of ModelValueFilter, which is what those == operators return:

public struct ModelValueFilter<Model> where Model: Fields {
    public init<Field>(
        _ lhs: KeyPath<Model, Field>,
        _ method: DatabaseQuery.Filter.Method,
        _ rhs: DatabaseQuery.Value
    )
        where Field: QueryableProperty
    {
        self.path = Model.path(for: lhs)
        self.method = method
        self.value = rhs
    }

    let path: [FieldKey]
    let method: DatabaseQuery.Filter.Method
    let value: DatabaseQuery.Value
}

In \.$type, the \. means it is a KeyPath literal. The $ means it is referring to the projectedValue of a property wrapper. The type field of Planet is presumably annotated @FieldProperty, and FieldProperty conforms to QueryableProperty, as required by those == operators.

4 Likes

Oh awesome thank you! I didn't know key-path expressions -- it seems I have a lot more to learn :slight_smile: (also Swift is larger than I originally thought)

1 Like