rust_webx_core/
pagination.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Deserialize)]
6pub struct PagedRequest {
7 #[serde(default = "default_page")]
8 pub page: u32,
9 #[serde(default = "default_page_size")]
10 pub page_size: u32,
11}
12
13fn default_page() -> u32 {
14 1
15}
16fn default_page_size() -> u32 {
17 20
18}
19
20impl Default for PagedRequest {
21 fn default() -> Self {
22 Self {
23 page: 1,
24 page_size: 20,
25 }
26 }
27}
28
29impl PagedRequest {
30 pub fn new(page: u32, page_size: u32) -> Self {
31 Self { page, page_size }
32 }
33
34 pub fn offset(&self) -> u32 {
35 (self.page.saturating_sub(1)).saturating_mul(self.page_size)
36 }
37
38 pub fn clamped(mut self) -> Self {
39 self.page = self.page.max(1);
40 self.page_size = self.page_size.clamp(1, 100);
41 self
42 }
43}
44
45#[derive(Debug, Clone, Serialize)]
46pub struct PagedResponse<T: Serialize> {
47 pub items: Vec<T>,
48 pub total: u64,
49 pub page: u32,
50 pub page_size: u32,
51 pub total_pages: u32,
52}
53
54impl<T: Serialize> PagedResponse<T> {
55 pub fn new(items: Vec<T>, total: u64, page: u32, page_size: u32) -> Self {
56 let total_pages = if page_size > 0 {
57 total.div_ceil(page_size as u64) as u32
58 } else {
59 0
60 };
61 Self {
62 items,
63 total,
64 page,
65 page_size,
66 total_pages,
67 }
68 }
69
70 pub fn from_request(items: Vec<T>, total: u64, req: &PagedRequest) -> Self {
71 Self::new(items, total, req.page, req.page_size)
72 }
73}