I am trying to order diesel queries dynamically, something like this question. QueryOrdering::order_query
works fine, but when I tried to create the DynOrderDsl
trait, so that I can build the queries by chaining functions like in the example
fn I cannot get the code to compile.
I think the trait bounds should be fine, since those are all copy pasted from QueryOrdering::order_query
which works.
#[macro_use]
extern crate diesel;
use diesel::backend::Backend;
use diesel::dsl::{Asc, Desc};
use diesel::helper_types::IntoBoxed;
use diesel::query_dsl::methods::{BoxedDsl, OrderDsl};
use diesel::{table, ExpressionMethods, QueryDsl};
table! {
posts (id) {
id -> Nullable<Integer>,
}
}
enum QueryOrdering {
Ascending,
Descending,
}
impl QueryOrdering {
fn order_query<'a, Expr, Q, DB>(&self, query: Q, expr: Expr) -> IntoBoxed<'a, Q, DB>
where
Expr: ExpressionMethods,
Q: QueryDsl + BoxedDsl<'a, DB>,
DB: Backend,
IntoBoxed<'a, Q, DB>: OrderDsl<Asc<Expr>, Output = IntoBoxed<'a, Q, DB>>
+ OrderDsl<Desc<Expr>, Output = IntoBoxed<'a, Q, DB>>,
{
match self {
Self::Ascending => query.into_boxed().order(expr.asc()),
Self::Descending => query.into_boxed().order(expr.desc()),
}
}
}
pub trait DynOrderDsl<'a, DB, Expr>
where
Expr: ExpressionMethods,
Self: QueryDsl + BoxedDsl<'a, DB>,
DB: Backend,
IntoBoxed<'a, Self, DB>: OrderDsl<Asc<Expr>, Output = IntoBoxed<'a, Self, DB>>
+ OrderDsl<Desc<Expr>, Output = IntoBoxed<'a, Self, DB>>,
{
fn dyn_order(self, order: QueryOrdering, expr: Expr) -> IntoBoxed<'a, Self, DB>;
}
impl<'a, Expr, DB, Q> DynOrderDsl<'a, Expr, DB> for Q
where
Expr: ExpressionMethods,
Q: QueryDsl + BoxedDsl<'a, DB>,
DB: Backend,
IntoBoxed<'a, Q, DB>: OrderDsl<Asc<Expr>, Output = IntoBoxed<'a, Q, DB>>
+ OrderDsl<Desc<Expr>, Output = IntoBoxed<'a, Q, DB>>,
{
fn dyn_order(self, order: QueryOrdering, expr: Expr) -> IntoBoxed<'a, Q, DB> {
order.order_query(self, expr)
}
}
fn example<DB: Backend>(order: QueryOrdering) {
order
.order_query::<_, _, DB>(posts::table, posts::id)
.limit(5);
// want to do this instead
posts::table.dyn_order(order, posts::id).limit(5);
}
The compiler shows this error
error[E0275]: overflow evaluating the requirement `Q: BoxedDsl<'_, Expr>`
--> src/main.rs:48:23
|
48 | impl<'a, Expr, DB, Q> DynOrderDsl<'a, Expr, DB> for Q
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`databases`)
= note: required for `Q` to implement `BoxedDsl<'_, Expr>`
= note: 126 redundant requirements hidden
= note: required for `Q` to implement `BoxedDsl<'_, Expr>`
As I see I somehow should tell the compiler that