1 stable release
Uses new Rust 2024
| 2.0.0 | Aug 20, 2025 |
|---|
#58 in #pagination
11KB
123 lines
diesel_filter
Diesel filter is a quick way to add filters and pagination to your diesel models.
Works with diesel and Postgres.
Crate features
rocketDerivesFromFormon the generated filter struct (See this example)actixDerivesDeserializeon the generated filter struct (See this example)serializewithpaginationAdds thePaginatedPayloadtrait that can directly be sent to your client
Changes in 2.0
- Pagination was moved to a new crate called
diesel_pagination, see new usage below.
Usage & Examples
Cargo.toml
diesel_filter = { path = "../../diesel_filter/diesel_filter", features = ["serialize", "rocket"] }
Derive your struct with DieselFilter and annotate the fields that will be used as filters.
The top level annotation #[diesel(table_name = db_table)] is mandatory.
#[derive(Queryable, DieselFilter)]
#[diesel(table_name = projects)]
pub struct Project {
pub id: Uuid,
#[filter(substring, insensitive)]
pub name: String,
#[filter(substring)]
pub owner_email: String,
#[filter]
pub owner_id: Uuid,
pub created_at: NaiveDateTime,
}
The #[filter] annotation can receive the kinds of filter you want to apply on it, for the moment, there is only substring and insensitive.
A struct for the filtering data will be generated with the name [YourStructName]Filters, e.g: ProjectFilters.
Two methods will be generated (let's keep Project as an example):
pub fn filter<'a>(filters: &'a ProjectFilters) -> BoxedQuery<'a, Pg>
The filter method can be used in conjunction with other diesel methods like inner_join and such.
Project::filter(&filters)
.inner_join(clients::table)
.select((projects::id, clients::name))
.load::<ProjectResponse>(conn)
With Rocket
With the rocket feature, the generated struct can be obtained from the request query parameters (dot notation ?filters.name=xxx)
With Actix
With the actix feature, the generated struct can be obtained from the request query parameters
N.B: unlike the rocket integration, the query parameters must be sent unscopped. e.g ?field=xxx&other=1
Pagination
The diesel_pagination crate exports a trait with paginate and load_and_count methods.
use diesel_pagination::Paginate;
Project::filter(&filters)
.inner_join(clients::table)
.select((projects::id, clients::name))
.paginate(PaginationParams { page: Some(1), per_page: Some(10) })
.load_and_count::<ProjectResponse>(conn)
PaginationParams can be used as an additional query parameters struct to the generated [YourStruct]Filter in actix/axum/rocket.
#[derive(Queryable, DieselFilter)]
#[diesel(table_name = projects)]
pub struct Project
#[filter(multiple)]
When using #[filter(multiple)] with actix or axum features, parsing of multiple options is done with StringWithSeparator<CommaSeparator, T>.
This requires the underlying type to impl FromStr, for example:
#[derive(Debug, DieselNewType)]
pub struct CustomType(String);
impl FromStr for CustomType {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.to_owned()))
}
}
Enums can use EnumString:
use strum::EnumString;
#[derive(EnumString, DieselNewType)]
pub enum CustomType {
A,
B,
C,
}
#[derive(DieselFilter)]
struct Model {
#[filter(multiple)]
custom: CustomType,
}
License
Diesel filter is licensed under either of the following, at your option:
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or https://opensource.org/licenses/MIT)
Dependencies
~4MB
~75K SLoC