vantage_table/
pagination.rs1use vantage_expressions::traits::selectable::Selectable;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Pagination {
6 page: i64,
7 items_per_page: i64,
8 offset: Option<i64>,
12}
13
14impl Pagination {
15 pub fn new(page: i64, items_per_page: i64) -> Self {
17 Self {
18 page: page.max(1),
19 items_per_page: items_per_page.max(1),
20 offset: None,
21 }
22 }
23
24 pub fn window(offset: i64, limit: i64) -> Self {
28 Self {
29 page: 1,
30 items_per_page: limit.max(1),
31 offset: Some(offset.max(0)),
32 }
33 }
34
35 pub fn set_page(&mut self, page: i64) {
37 self.page = page.max(1);
38 }
39
40 pub fn set_ipp(&mut self, items_per_page: i64) {
43 let items_per_page = items_per_page.max(1);
44
45 let first_item_index = (self.page - 1) * self.items_per_page;
47
48 self.page = (first_item_index / items_per_page) + 1;
50 self.items_per_page = items_per_page;
51 }
52
53 pub fn get_page(&self) -> i64 {
55 self.page
56 }
57
58 pub fn get_ipp(&self) -> i64 {
60 self.items_per_page
61 }
62
63 pub fn limit(&self) -> i64 {
65 self.items_per_page
66 }
67
68 pub fn skip(&self) -> i64 {
70 self.offset.unwrap_or((self.page - 1) * self.items_per_page)
71 }
72
73 pub fn apply_on_select<S, E>(&self, select: &mut S)
75 where
76 S: Selectable<E>,
77 {
78 select.set_limit(Some(self.limit()), Some(self.skip()));
79 }
80}
81
82impl Default for Pagination {
83 fn default() -> Self {
84 Self {
85 page: 1,
86 items_per_page: 50,
87 offset: None,
88 }
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_new_pagination() {
98 let p = Pagination::new(2, 25);
99 assert_eq!(p.get_page(), 2);
100 assert_eq!(p.get_ipp(), 25);
101 assert_eq!(p.limit(), 25);
102 assert_eq!(p.skip(), 25);
103 }
104
105 #[test]
106 fn test_pagination_bounds() {
107 let p = Pagination::new(0, 0);
108 assert_eq!(p.get_page(), 1);
109 assert_eq!(p.get_ipp(), 1);
110 }
111
112 #[test]
113 fn test_set_page() {
114 let mut p = Pagination::new(1, 10);
115 p.set_page(3);
116 assert_eq!(p.get_page(), 3);
117 assert_eq!(p.skip(), 20);
118 }
119
120 #[test]
121 fn test_set_ipp_keeps_focus() {
122 let mut p = Pagination::new(3, 10);
123 p.set_ipp(5);
127 assert_eq!(p.get_page(), 5);
129 assert_eq!(p.get_ipp(), 5);
130 assert_eq!(p.skip(), 20);
131 }
132
133 #[test]
134 fn test_set_ipp_larger_page_size() {
135 let mut p = Pagination::new(5, 5);
136 p.set_ipp(25);
139 assert_eq!(p.get_page(), 1);
141 assert_eq!(p.get_ipp(), 25);
142 assert_eq!(p.skip(), 0);
143 }
144
145 #[test]
146 fn test_default_pagination() {
147 let p = Pagination::default();
148 assert_eq!(p.get_page(), 1);
149 assert_eq!(p.get_ipp(), 50);
150 assert_eq!(p.skip(), 0);
151 }
152}