mik_sql/pagination/
page_info.rs1use super::cursor::Cursor;
4
5#[derive(Debug, Clone, Default, PartialEq, Eq)]
21#[non_exhaustive]
22pub struct PageInfo {
23 pub has_next: bool,
25 pub has_prev: bool,
27 pub next_cursor: Option<String>,
29 pub prev_cursor: Option<String>,
31 pub total: Option<u64>,
33}
34
35impl PageInfo {
36 #[must_use]
40 pub const fn new(count: usize, limit: usize) -> Self {
41 Self {
42 has_next: count >= limit,
43 has_prev: false,
44 next_cursor: None,
45 prev_cursor: None,
46 total: None,
47 }
48 }
49
50 #[must_use]
52 pub const fn with_has_prev(mut self, has_prev: bool) -> Self {
53 self.has_prev = has_prev;
54 self
55 }
56
57 #[must_use]
59 pub fn with_next_cursor(mut self, cursor: Option<String>) -> Self {
60 self.next_cursor = cursor;
61 if self.next_cursor.is_some() {
62 self.has_next = true;
63 }
64 self
65 }
66
67 #[must_use]
69 pub fn with_prev_cursor(mut self, cursor: Option<String>) -> Self {
70 self.prev_cursor = cursor;
71 if self.prev_cursor.is_some() {
72 self.has_prev = true;
73 }
74 self
75 }
76
77 #[must_use]
79 pub const fn with_total(mut self, total: u64) -> Self {
80 self.total = Some(total);
81 self
82 }
83
84 #[allow(clippy::single_option_map)] pub fn cursor_from<T, F>(item: Option<&T>, builder: F) -> Option<String>
87 where
88 F: FnOnce(&T) -> Cursor,
89 {
90 item.map(|item| builder(item).encode())
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn test_page_info_basic() {
100 let info = PageInfo::new(20, 20);
101 assert!(info.has_next);
102 assert!(!info.has_prev);
103
104 let info = PageInfo::new(15, 20);
105 assert!(!info.has_next);
106 }
107
108 #[test]
109 fn test_page_info_with_cursors() {
110 let info = PageInfo::new(20, 20)
111 .with_next_cursor(Some("abc".to_string()))
112 .with_prev_cursor(Some("xyz".to_string()))
113 .with_total(100);
114
115 assert!(info.has_next);
116 assert!(info.has_prev);
117 assert_eq!(info.next_cursor, Some("abc".to_string()));
118 assert_eq!(info.prev_cursor, Some("xyz".to_string()));
119 assert_eq!(info.total, Some(100));
120 }
121}