-
-
Notifications
You must be signed in to change notification settings - Fork 560
/
Copy pathlimiter.rs
87 lines (76 loc) Β· 2.29 KB
/
limiter.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use crate::{
ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Paginator, PaginatorTrait, QuerySelect,
Select, SelectModel, SelectTwo, SelectTwoMany, SelectTwoModel, Selector, SelectorTrait,
};
use std::num::NonZeroU64;
#[derive(Debug)]
pub struct Limiter<'db, C, S>
where
C: ConnectionTrait,
S: SelectorTrait + 'db,
{
db: &'db C,
selector: Selector<S>,
paginator: Paginator<'db, C, S>,
}
impl<'db, C, S> Limiter<'db, C, S>
where
C: ConnectionTrait,
S: SelectorTrait + 'db,
{
pub async fn fetch(self) -> Result<Vec<S::Item>, DbErr> {
self.selector.all(self.db).await
}
pub async fn total(&self) -> Result<u64, DbErr> {
self.paginator.num_items().await
}
}
pub trait LimiterTrait<'db, C>
where
C: ConnectionTrait,
{
type Selector: SelectorTrait + 'db;
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector>;
}
impl<'db, C, M, E> LimiterTrait<'db, C> for Select<E>
where
C: ConnectionTrait,
E: EntityTrait<Model = M>,
M: FromQueryResult + Sized + Send + Sync + 'db,
{
type Selector = SelectModel<M>;
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector> {
let selector = self
.clone()
.limit(NonZeroU64::new(limit).map(|limit| limit.get()))
.offset(NonZeroU64::new(offset).map(|offset| offset.get()))
.into_model();
Limiter {
db,
paginator: self.clone().paginate(db, 1),
selector,
}
}
}
impl<'db, C, M1, M2, E1, E2> LimiterTrait<'db, C> for SelectTwo<E1, E2>
where
C: ConnectionTrait,
E1: EntityTrait<Model = M1>,
E2: EntityTrait<Model = M2>,
M1: FromQueryResult + Sized + Send + Sync + 'db,
M2: FromQueryResult + Sized + Send + Sync + 'db,
{
type Selector = SelectTwoModel<M1, M2>;
fn limiting(self, db: &'db C, offset: u64, limit: u64) -> Limiter<'db, C, Self::Selector> {
let selector = self
.clone()
.limit(NonZeroU64::new(limit).map(|limit| limit.get()))
.offset(NonZeroU64::new(offset).map(|offset| offset.get()))
.into_model();
Limiter {
db,
paginator: self.clone().paginate(db, 1),
selector,
}
}
}