1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct PageRequest {
8 pub page: u64,
10 pub per_page: u64,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct Page<T> {
17 pub items: Vec<T>,
19 pub total: u64,
21 pub page: u64,
23 pub per_page: u64,
25}
26
27impl<T> Page<T> {
28 pub fn total_pages(&self) -> u64 {
30 if self.per_page == 0 {
31 return 0;
32 }
33 self.total.div_ceil(self.per_page)
34 }
35
36 pub fn has_next_page(&self) -> bool {
38 self.page < self.total_pages()
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn page_total_pages_exact_division() {
48 let page: Page<i32> = Page {
49 items: vec![1, 2],
50 total: 10,
51 page: 1,
52 per_page: 5,
53 };
54 assert_eq!(page.total_pages(), 2);
55 }
56
57 #[test]
58 fn page_total_pages_with_remainder() {
59 let page: Page<i32> = Page {
60 items: vec![1, 2, 3],
61 total: 7,
62 page: 1,
63 per_page: 3,
64 };
65 assert_eq!(page.total_pages(), 3);
66 }
67
68 #[test]
69 fn page_total_pages_zero_per_page() {
70 let page: Page<i32> = Page {
71 items: vec![],
72 total: 10,
73 page: 1,
74 per_page: 0,
75 };
76 assert_eq!(page.total_pages(), 0);
77 }
78
79 #[test]
80 fn page_total_pages_zero_total() {
81 let page: Page<i32> = Page {
82 items: vec![],
83 total: 0,
84 page: 1,
85 per_page: 10,
86 };
87 assert_eq!(page.total_pages(), 0);
88 }
89
90 #[test]
91 fn has_next_page_true() {
92 let page: Page<i32> = Page {
93 items: vec![1, 2],
94 total: 10,
95 page: 1,
96 per_page: 5,
97 };
98 assert!(page.has_next_page());
99 }
100
101 #[test]
102 fn has_next_page_false_on_last_page() {
103 let page: Page<i32> = Page {
104 items: vec![1],
105 total: 10,
106 page: 2,
107 per_page: 5,
108 };
109 assert!(!page.has_next_page());
110 }
111
112 #[test]
113 fn has_next_page_false_when_empty() {
114 let page: Page<i32> = Page {
115 items: vec![],
116 total: 0,
117 page: 1,
118 per_page: 10,
119 };
120 assert!(!page.has_next_page());
121 }
122
123 #[test]
124 fn page_request_construction() {
125 let req = PageRequest {
126 page: 2,
127 per_page: 25,
128 };
129 assert_eq!(req.page, 2);
130 assert_eq!(req.per_page, 25);
131 }
132
133 #[test]
134 fn page_request_clone_and_eq() {
135 let req = PageRequest {
136 page: 1,
137 per_page: 10,
138 };
139 let cloned = req.clone();
140 assert_eq!(req, cloned);
141 }
142}