Skip to main content

rustorm_core/
pagination.rs

1/// Результат постраничного запроса.
2#[derive(Debug, Clone)]
3pub struct Page<T> {
4    pub items: Vec<T>,
5    pub total: i64,
6    pub current_page: i64,
7    pub per_page: i64,
8    pub total_pages: i64,
9}
10
11impl<T> Page<T> {
12    pub fn new(items: Vec<T>, total: i64, current_page: i64, per_page: i64) -> Self {
13        let per_page = per_page.max(1);
14        let total_pages = (total + per_page - 1) / per_page;
15        Self {
16            items,
17            total,
18            current_page,
19            per_page,
20            total_pages,
21        }
22    }
23
24    pub fn has_next(&self) -> bool {
25        self.current_page < self.total_pages
26    }
27
28    pub fn has_prev(&self) -> bool {
29        self.current_page > 1
30    }
31
32    pub fn next_page(&self) -> Option<i64> {
33        if self.has_next() {
34            Some(self.current_page + 1)
35        } else {
36            None
37        }
38    }
39
40    pub fn prev_page(&self) -> Option<i64> {
41        if self.has_prev() {
42            Some(self.current_page - 1)
43        } else {
44            None
45        }
46    }
47
48    /// Маппинг элементов без изменения метаданных пагинации.
49    pub fn map<U>(self, f: impl FnMut(T) -> U) -> Page<U> {
50        Page {
51            items: self.items.into_iter().map(f).collect(),
52            total: self.total,
53            current_page: self.current_page,
54            per_page: self.per_page,
55            total_pages: self.total_pages,
56        }
57    }
58}
59
60/// Результат курсорной пагинации.
61#[derive(Debug, Clone)]
62pub struct CursorPage<T> {
63    pub items: Vec<T>,
64    pub next_cursor: Option<i64>,
65    pub has_more: bool,
66}