rust 柴油机查询的动态排序

jtjikinw  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(142)

我试图动态地对diesel查询排序,类似this question . QueryOrdering::order_query的东西工作得很好,但是当我试图创建DynOrderDsl trait,以便我可以通过链接example fn中的函数来构建查询时,我无法编译代码。
我认为特征边界应该是好的,因为这些都是从QueryOrdering::order_query复制粘贴的,它可以工作。

#[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);
}

编译器显示此错误

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>`

我想我应该告诉编译器

zzwlnbp8

zzwlnbp81#

最后我明白了,DynOrderDsl的impl中泛型参数的顺序和trait decralation是错误的,最后,工作代码:
我将最终的工作代码张贴到我在开始时链接的问题。

相关问题