The smokesignal.events web application
1use crate::http::utils::stringify;
2use serde::{Deserialize, Serialize};
3
4pub(crate) const PAGE_DEFAULT: i64 = 1;
5pub(crate) const PAGE_MIN: i64 = 1;
6pub(crate) const PAGE_MAX: i64 = 100;
7pub(crate) const PAGE_SIZE_DEFAULT: i64 = 10;
8pub(crate) const PAGE_SIZE_MIN: i64 = 5;
9pub(crate) const PAGE_SIZE_MAX: i64 = 100;
10
11#[derive(Deserialize, Default)]
12pub(crate) struct Pagination {
13 pub(crate) page: Option<i64>,
14 pub(crate) page_size: Option<i64>,
15}
16
17#[derive(Serialize, Debug)]
18pub(crate) struct PaginationView {
19 pub(crate) previous: Option<i64>,
20 pub(crate) previous_url: Option<String>,
21 pub(crate) next: Option<i64>,
22 pub(crate) next_url: Option<String>,
23}
24
25impl Pagination {
26 pub(crate) fn admin_clamped(&self) -> (i64, i64) {
27 let page = self.page.unwrap_or(1).clamp(1, 25000);
28 let page_size = self.page_size.unwrap_or(1).clamp(20, 100);
29 (page, page_size)
30 }
31
32 pub(crate) fn clamped(&self) -> (i64, i64) {
33 let page = self.page.unwrap_or(PAGE_DEFAULT).clamp(PAGE_MIN, PAGE_MAX);
34 let page_size = self
35 .page_size
36 .unwrap_or(PAGE_SIZE_DEFAULT)
37 .clamp(PAGE_SIZE_MIN, PAGE_SIZE_MAX);
38 (page, page_size)
39 }
40
41 pub(crate) fn clamped_with_options(
42 &self,
43 page_default: i64,
44 page_min: i64,
45 page_max: i64,
46 page_size_default: i64,
47 page_size_min: i64,
48 page_size_max: i64,
49 ) -> (i64, i64) {
50 let page = self.page.unwrap_or(page_default).clamp(page_min, page_max);
51 let page_size = self
52 .page_size
53 .unwrap_or(page_size_default)
54 .clamp(page_size_min, page_size_max);
55 (page, page_size)
56 }
57}
58
59impl PaginationView {
60 pub(crate) fn new(page_size: i64, total: i64, page: i64, params: Vec<(&str, &str)>) -> Self {
61 let (previous, previous_url) = {
62 if page > 1 {
63 let page_value = (page - 1).to_string();
64 let mut page_args: Vec<(&str, &str)> = vec![("page", &page_value)];
65 page_args.extend(params.clone());
66 (Some(page - 1), Some(stringify(page_args)))
67 } else {
68 (None, None)
69 }
70 };
71
72 let (next, next_url) = {
73 if total > page_size {
74 let page_value = (page + 1).to_string();
75 let mut page_args: Vec<(&str, &str)> = vec![("page", &page_value)];
76 page_args.extend(params);
77 (Some(page + 1), Some(stringify(page_args)))
78 } else {
79 (None, None)
80 }
81 };
82
83 Self {
84 previous,
85 previous_url,
86 next,
87 next_url,
88 }
89 }
90}