1mod tests;
7
8#[derive(Clone, Copy, Debug)]
10pub struct Page {
11 offset: usize,
13 limit: usize,
15}
16
17impl Page {
18 pub const DEFAULT: Page = Page { offset: 0, limit: 100 };
20
21 const MAX_PAGE_SIZE: usize = 500;
23
24 #[must_use]
26 pub fn new(offset: usize, limit: usize) -> Self {
27 let limit =
28 if limit == 0 { Self::DEFAULT.limit } else { limit.clamp(0, Self::MAX_PAGE_SIZE) };
29 Self { offset, limit }
30 }
31
32 #[must_use]
35 pub fn top(limit: usize) -> Page {
36 Page::new(0, limit)
37 }
38
39 #[must_use]
41 pub fn next(&self) -> Page {
42 Page { offset: self.offset.saturating_add(self.limit), limit: self.limit }
43 }
44
45 #[must_use]
47 pub fn offset(&self) -> i64 {
48 i64::try_from(self.offset).unwrap_or(i64::MAX)
49 }
50
51 #[must_use]
53 pub fn limit(&self) -> i64 {
54 i64::try_from(self.limit).unwrap_or(i64::MAX)
55 }
56}
57
58impl Default for Page {
59 fn default() -> Page {
60 Self::DEFAULT
61 }
62}
63
64#[derive(Debug, Default, PartialEq)]
66pub enum OrderDirection {
67 #[default]
69 Ascending,
70 Descending,
72}
73
74impl OrderDirection {
75 #[must_use]
77 pub fn as_str(&self) -> &'static str {
78 match self {
79 OrderDirection::Ascending => "ASC",
80 OrderDirection::Descending => "DESC",
81 }
82 }
83}