Skip to main content

road_runner_common/
pagination.rs

1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "openapi")]
4use utoipa::ToSchema;
5
6#[derive(Debug, Clone, Copy, Deserialize)]
7#[cfg_attr(feature = "openapi", derive(ToSchema, utoipa::IntoParams))]
8pub struct PageRequest {
9    #[serde(default = "default_page")]
10    pub page: u32, // 1'den başlar
11
12    #[serde(default = "default_size")]
13    pub size: u32,
14}
15
16fn default_page() -> u32 {
17    1
18}
19fn default_size() -> u32 {
20    10
21}
22
23impl Default for PageRequest {
24    fn default() -> Self {
25        Self {
26            page: default_page(),
27            size: default_size(),
28        }
29    }
30}
31
32impl PageRequest {
33    pub fn normalized(self, max_page_size: u32) -> Self {
34        let size = self.size.clamp(1, max_page_size.max(1));
35        let page = self.page.max(1);
36        Self { page, size }
37    }
38
39    pub fn normalized_with_default(self, default_size: u32, max_page_size: u32) -> Self {
40        let max_size = max_page_size.max(1);
41        let default_size = default_size.clamp(1, max_size);
42        let size = if self.size == 0 {
43            default_size
44        } else {
45            self.size.clamp(1, max_size)
46        };
47        let page = self.page.max(1);
48        Self { page, size }
49    }
50
51    pub fn offset_limit(self) -> (u32, u32) {
52        let page = self.page.max(1);
53        let size = self.size.max(1);
54        let offset = (page - 1).saturating_mul(size);
55        (offset, size)
56    }
57}
58
59#[derive(Debug, Clone, Serialize)]
60#[cfg_attr(feature = "openapi", derive(ToSchema))]
61pub struct Paged<T> {
62    pub items: Vec<T>,
63    pub total_items: u64,
64    pub page: u32,
65    pub size: u32,
66    pub total_pages: u32,
67}
68
69impl<T> Paged<T> {
70    pub fn new(items: Vec<T>, total_items: u64, page: u32, size: u32) -> Self {
71        let size = size.max(1);
72        let total_pages = if total_items == 0 {
73            0
74        } else {
75            ((total_items + size as u64 - 1) / size as u64) as u32
76        };
77
78        Self {
79            items,
80            total_items,
81            page: page.max(1),
82            size,
83            total_pages,
84        }
85    }
86}