Common `diesel` type for filter expressions on joined tables

Hello everyone,
I'm currently working on extending the filtering system for diesel which I asked a question about around one year ago (here). The new version I'm working on should support filtering on related tables.

The database schema I'm using for testing is the following:

diesel::table! {
    bookstore_addresses (bookstore_id) {
        bookstore_id -> Uuid,
        street -> Varchar,
        city -> Varchar,
        zip -> Varchar,
        state -> Nullable<Varchar>,
        country -> Varchar,
    }
}

diesel::table! {
    bookstores (id) {
        id -> Uuid,
        name -> Varchar,
    }
}

diesel::allow_tables_to_appear_in_same_query!(
    bookstore_addresses, bookstores,
);

Usage of the filtering system should ideally look something like this:

use schema::{bookstore_addresses, bookstores};

fn main() {
    // Defining a WHERE-clause with nested enums, which filters for
    // all bookstores with a zip code of "12345".
    let filter = BookstoreFilter::Address(
        BookstoreAddressFilter::Zip(
            StrFilter::Eq("12345".into())
        )
    );

    let query = bookstores::table
        // The zip code value is not stored on the "bookstores" table
        // but on the related "bookstore_addresses" table.
        .left_join(bookstore_addresses::table.on(
            bookstore_addresses::bookstore_id.eq(bookstores::id)
        ))
        // The filter enum is converted to a diesel expression
        .filter(filter.to_expression());
}

The BookstoreFilter and BookstoreAddressFilter enums are defined as follows:

enum BookstoreFilter {
    Id(dqg::UuidFilter),
    Address(BookstoreAddressFilter),
}

enum BookstoreAddressFilter {
    Zip(dqg::StrFilter),
}

With their corresponding impl blocks which define their to_expression method:

impl BookstoreFilter {
    fn to_expression(self) -> Box<dyn BoxableExpression<
        bookstores::table,
        diesel::pg::Pg,
        SqlType = diesel::sql_types::Bool
    >> {
        match self {
            Self::Id(f) => match f {
                UuidFilter::Eq(value) => Box::new(
                    bookstores::id.eq(value)
                ),

                UuidFilter::EqAny(values) => Box::new(
                    bookstores::id.eq_any(values)
                ),
            },

            Self::Address(f) => f.to_expression(), // <- error occurs here
        }
    }
}

impl BookstoreAddressFilter {
    fn to_expression(self) -> Box<dyn BoxableExpression<
        bookstore_addresses::table,
        diesel::pg::Pg,
        SqlType = diesel::sql_types::Bool
    >> {
        match self {
            Self::Zip(f) => match f {
                StrFilter::Eq(value) => Box::new(
                    bookstore_addresses::zip.eq(value)
                ),

                StrFilter::Contains(value) => Box::new(
                    bookstore_addresses::zip.like(format!("%{}%", value))
                ),

                _ => todo!(),
            }
        }
    }
}

Calling to.expression() in the impl block of BookstoreFilter causes an error, because the types of the match arms differ. This makes sense, as the other match arms return values of type...

Box<dyn BoxableExpression<
    bookstores::table,
    diesel::pg::Pg,
    SqlType = diesel::sql_types::Bool
>>

...whereas the to_expression() call returns a value of type...

Box<dyn BoxableExpression<
    bookstore_addresses::table, // <- the "query source" is different
    diesel::pg::Pg,
    SqlType = diesel::sql_types::Bool
>>

Is there a common type which the to_expression method could return or even a completely different approach to compose diesel expressions like I described?

Thank you very much in advance!