1use paginator_utils;
2pub use paginator_utils::*;
3
4use serde::Serialize;
5use serde_json::{Value, to_value};
6use std::error::Error;
7use std::fmt;
8
9#[derive(Debug)]
11pub enum PaginatorError {
12 InvalidPage(u32),
14 InvalidPerPage(u32),
16 SerializationError(String),
18 Custom(String),
20}
21
22impl fmt::Display for PaginatorError {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 PaginatorError::InvalidPage(page) => {
26 write!(f, "Invalid page number: {}. Page must be >= 1", page)
27 }
28 PaginatorError::InvalidPerPage(per_page) => {
29 write!(
30 f,
31 "Invalid per_page value: {}. Must be between 1 and 100",
32 per_page
33 )
34 }
35 PaginatorError::SerializationError(msg) => {
36 write!(f, "Serialization error: {}", msg)
37 }
38 PaginatorError::Custom(msg) => write!(f, "{}", msg),
39 }
40 }
41}
42
43impl Error for PaginatorError {}
44
45pub type PaginatorResult<T> = Result<T, PaginatorError>;
47
48pub trait PaginatorTrait<T>
50where
51 T: Serialize,
52{
53 fn paginate(&self, params: &PaginationParams) -> PaginatorResult<PaginatorResponse<T>> {
55 if params.page < 1 {
57 return Err(PaginatorError::InvalidPage(params.page));
58 }
59 if params.per_page < 1 || params.per_page > 100 {
60 return Err(PaginatorError::InvalidPerPage(params.per_page));
61 }
62
63 Ok(PaginatorResponse {
64 data: vec![],
65 meta: PaginatorResponseMeta::new(0, params.per_page, 0),
66 })
67 }
68
69 fn paginate_json(&self, params: &PaginationParams) -> PaginatorResult<Value> {
71 let response = self.paginate(params)?;
72 to_value(response)
73 .map_err(|e| PaginatorError::SerializationError(e.to_string()))
74 }
75}
76
77pub struct PaginatorBuilder {
79 params: PaginationParams,
80}
81
82impl Default for PaginatorBuilder {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl PaginatorBuilder {
89 pub fn new() -> Self {
91 Self {
92 params: PaginationParams::default(),
93 }
94 }
95
96 pub fn page(mut self, page: u32) -> Self {
98 self.params.page = page.max(1);
99 self
100 }
101
102 pub fn per_page(mut self, per_page: u32) -> Self {
104 self.params.per_page = per_page.max(1).min(100);
105 self
106 }
107
108 pub fn sort_by(mut self, field: impl Into<String>) -> Self {
110 self.params.sort_by = Some(field.into());
111 self
112 }
113
114 pub fn sort_asc(mut self) -> Self {
116 self.params.sort_direction = Some(SortDirection::Asc);
117 self
118 }
119
120 pub fn sort_desc(mut self) -> Self {
122 self.params.sort_direction = Some(SortDirection::Desc);
123 self
124 }
125
126 pub fn filter(mut self, field: impl Into<String>, operator: FilterOperator, value: FilterValue) -> Self {
128 self.params.filters.push(Filter::new(field, operator, value));
129 self
130 }
131
132 pub fn filter_eq(mut self, field: impl Into<String>, value: FilterValue) -> Self {
134 self.params.filters.push(Filter::new(field, FilterOperator::Eq, value));
135 self
136 }
137
138 pub fn filter_ne(mut self, field: impl Into<String>, value: FilterValue) -> Self {
140 self.params.filters.push(Filter::new(field, FilterOperator::Ne, value));
141 self
142 }
143
144 pub fn filter_gt(mut self, field: impl Into<String>, value: FilterValue) -> Self {
146 self.params.filters.push(Filter::new(field, FilterOperator::Gt, value));
147 self
148 }
149
150 pub fn filter_lt(mut self, field: impl Into<String>, value: FilterValue) -> Self {
152 self.params.filters.push(Filter::new(field, FilterOperator::Lt, value));
153 self
154 }
155
156 pub fn filter_gte(mut self, field: impl Into<String>, value: FilterValue) -> Self {
158 self.params.filters.push(Filter::new(field, FilterOperator::Gte, value));
159 self
160 }
161
162 pub fn filter_lte(mut self, field: impl Into<String>, value: FilterValue) -> Self {
164 self.params.filters.push(Filter::new(field, FilterOperator::Lte, value));
165 self
166 }
167
168 pub fn filter_like(mut self, field: impl Into<String>, pattern: impl Into<String>) -> Self {
170 self.params.filters.push(Filter::new(
171 field,
172 FilterOperator::Like,
173 FilterValue::String(pattern.into()),
174 ));
175 self
176 }
177
178 pub fn filter_ilike(mut self, field: impl Into<String>, pattern: impl Into<String>) -> Self {
180 self.params.filters.push(Filter::new(
181 field,
182 FilterOperator::ILike,
183 FilterValue::String(pattern.into()),
184 ));
185 self
186 }
187
188 pub fn filter_in(mut self, field: impl Into<String>, values: Vec<FilterValue>) -> Self {
190 self.params.filters.push(Filter::new(
191 field,
192 FilterOperator::In,
193 FilterValue::Array(values),
194 ));
195 self
196 }
197
198 pub fn filter_between(mut self, field: impl Into<String>, min: FilterValue, max: FilterValue) -> Self {
200 self.params.filters.push(Filter::new(
201 field,
202 FilterOperator::Between,
203 FilterValue::Array(vec![min, max]),
204 ));
205 self
206 }
207
208 pub fn filter_is_null(mut self, field: impl Into<String>) -> Self {
210 self.params.filters.push(Filter::new(
211 field,
212 FilterOperator::IsNull,
213 FilterValue::Null,
214 ));
215 self
216 }
217
218 pub fn filter_is_not_null(mut self, field: impl Into<String>) -> Self {
220 self.params.filters.push(Filter::new(
221 field,
222 FilterOperator::IsNotNull,
223 FilterValue::Null,
224 ));
225 self
226 }
227
228 pub fn search(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
230 self.params.search = Some(SearchParams::new(query, fields));
231 self
232 }
233
234 pub fn search_exact(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
236 self.params.search = Some(SearchParams::new(query, fields).with_exact_match(true));
237 self
238 }
239
240 pub fn search_case_sensitive(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
242 self.params.search = Some(SearchParams::new(query, fields).with_case_sensitive(true));
243 self
244 }
245
246 pub fn build(self) -> PaginationParams {
248 self.params
249 }
250}