geekorm_core/queries/
pagination.rs1use super::pages::Page;
4use crate::{GeekConnection, QueryBuilderTrait, TableBuilder};
5
6pub struct Pagination<T>
42where
43 T: TableBuilder
44 + QueryBuilderTrait
45 + serde::Serialize
46 + for<'de> serde::Deserialize<'de>
47 + Sized,
48{
49 phantom: std::marker::PhantomData<T>,
50 page: Page,
51}
52
53impl<T> Pagination<T>
54where
55 T: TableBuilder
56 + QueryBuilderTrait
57 + serde::Serialize
58 + for<'de> serde::Deserialize<'de>
59 + Sized,
60{
61 pub fn new() -> Self {
63 Self::default()
64 }
65 pub fn page(&self) -> u32 {
67 self.page.page()
68 }
69 pub fn limit(&self) -> u32 {
71 self.page.limit()
72 }
73 pub fn total(&self) -> u32 {
75 self.page.total
76 }
77 pub fn set_total(&mut self, total: u32) {
79 self.page.set_total(total);
80 }
81
82 pub async fn get<'a, C>(&mut self, connection: &'a C) -> Result<Vec<T>, crate::Error>
84 where
85 C: GeekConnection<Connection = C> + 'a,
86 {
87 if self.page.total == 0 {
89 self.page
90 .set_total(C::row_count(connection, T::query_count().build()?).await? as u32);
91 }
92 C::query(connection, T::query_select().page(&self.page).build()?).await
93 }
94
95 pub async fn next<'a, C>(&mut self, connection: &'a C) -> Result<Vec<T>, crate::Error>
97 where
98 C: GeekConnection<Connection = C> + 'a,
99 {
100 self.page.next();
101 if self.page.max() < self.page.page {
102 return Err(crate::Error::PaginationError(
103 "Cannot go to next page".to_string(),
104 ));
105 }
106 self.get(connection).await
107 }
108
109 pub async fn prev<'a, C>(&mut self, connection: &'a C) -> Result<Vec<T>, crate::Error>
111 where
112 C: GeekConnection<Connection = C> + 'a,
113 {
114 if self.page.page == u32::MAX || self.page.page == 0 {
115 return Err(crate::Error::PaginationError(
116 "Cannot go to previous page".to_string(),
117 ));
118 }
119 self.page.prev();
120 self.get(connection).await
121 }
122}
123
124impl<T> Default for Pagination<T>
125where
126 T: TableBuilder
127 + QueryBuilderTrait
128 + serde::Serialize
129 + for<'de> serde::Deserialize<'de>
130 + Sized,
131{
132 fn default() -> Self {
133 Self {
134 phantom: std::marker::PhantomData,
135 page: Page {
136 page: u32::MAX,
137 ..Default::default()
138 },
139 }
140 }
141}