Rust Diesel:如何为谓词设置简洁返回类型并统一管理?
在Diesel中优雅管理过滤谓词的方案
1. 使用impl trait简化返回类型
Rust的impl trait语法可以直接返回匿名类型,只要它实现了Diesel要求的Expression trait且对应的SQL类型为Bool,无需手动编写冗长的具体类型:
use diesel::{Expression, sql_types::Bool}; use crate::schema::posts::dsl::{published, id}; fn published_with_id(n: i64) -> impl Expression<SqlType = Bool> { published.eq(true).and(id.eq(n)) } // 调用示例 let post = posts.filter(published_with_id(5)).first(conn)?;
2. 为冗长类型定义别名(灵活性较差,不推荐)
如果必须显式指定类型,可以把编译提示的长类型定义成type alias,给它起一个简洁的名字:
use diesel::expression::{grouped::Grouped, operators::And}; use diesel::sql_types::Bool; use crate::schema::posts::columns; type PublishedWithIdPredicate = Grouped<And< Grouped<columns::published::Eq<diesel::expression::bound::Bound<Bool, bool>>>, Grouped<columns::id::Eq<i64>>, >>; fn published_with_id(n: i64) -> PublishedWithIdPredicate { published.eq(true).and(id.eq(n)) }
注意:后续修改谓词逻辑时,这个类型别名需要同步更新,灵活性远不如impl trait。
3. 为查询构建器扩展方法(更贴合Diesel使用风格)
直接给查询构建器添加自定义方法,把过滤逻辑封装进去,调用起来更直观:
use diesel::QueryDsl; use crate::schema::posts::dsl::{posts, published, id}; pub trait PostQueryExt: QueryDsl { fn published_with_id(self, n: i64) -> Self::Output where Self: Sized, { self.filter(published.eq(true).and(id.eq(n))) } } // 为所有符合条件的查询构建器实现该扩展 trait impl<T> PostQueryExt for T where T: QueryDsl + Sized {} // 调用示例 let post = posts.published_with_id(5).first(conn)?;
内容的提问来源于stack exchange,提问作者Ibolit
相关产品推荐
相关产品推荐

