Skip to main content

systemprompt_models/api/
pagination.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub struct PaginationInfo {
5    pub total: i64,
6
7    pub page: i32,
8
9    pub per_page: i32,
10
11    pub total_pages: i32,
12
13    pub has_next: bool,
14
15    pub has_prev: bool,
16
17    pub next_url: Option<String>,
18
19    pub prev_url: Option<String>,
20}
21
22impl PaginationInfo {
23    pub fn new(total: i64, page: i32, per_page: i32) -> Self {
24        let per_page_i64 = i64::from(per_page);
25        let total_pages =
26            i32::try_from((total + per_page_i64 - 1) / per_page_i64).unwrap_or(i32::MAX);
27        let has_next = page < total_pages;
28        let has_prev = page > 1;
29
30        Self {
31            total,
32            page,
33            per_page,
34            total_pages,
35            has_next,
36            has_prev,
37            next_url: None,
38            prev_url: None,
39        }
40    }
41
42    pub fn with_base_url(mut self, base_url: &str) -> Self {
43        if self.has_next {
44            self.next_url = Some(format!(
45                "{}?page={}&per_page={}",
46                base_url,
47                self.page + 1,
48                self.per_page
49            ));
50        }
51        if self.has_prev {
52            self.prev_url = Some(format!(
53                "{}?page={}&per_page={}",
54                base_url,
55                self.page - 1,
56                self.per_page
57            ));
58        }
59        self
60    }
61}
62
63#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
64pub struct PaginationParams {
65    #[serde(default = "default_page")]
66    pub page: i32,
67
68    #[serde(default = "default_per_page")]
69    pub per_page: i32,
70}
71
72const fn default_page() -> i32 {
73    1
74}
75
76const fn default_per_page() -> i32 {
77    20
78}
79
80impl Default for PaginationParams {
81    fn default() -> Self {
82        Self {
83            page: default_page(),
84            per_page: default_per_page(),
85        }
86    }
87}
88
89impl PaginationParams {
90    pub const fn offset(&self) -> i32 {
91        (self.page - 1) * self.per_page
92    }
93
94    pub const fn limit(&self) -> i32 {
95        self.per_page
96    }
97}
98
99#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize)]
100#[serde(rename_all = "lowercase")]
101pub enum SortOrder {
102    #[default]
103    Asc,
104    Desc,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct SortParams {
109    pub sort_by: Option<String>,
110
111    #[serde(default)]
112    pub sort_order: SortOrder,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct SearchQuery {
117    pub search: Option<String>,
118    pub sort_by: Option<String>,
119    pub sort_dir: Option<String>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct ApiQuery {
124    #[serde(flatten)]
125    pub pagination: PaginationParams,
126
127    #[serde(flatten)]
128    pub search: SearchQuery,
129}