1use paginator_utils::{Cursor, CursorDirection, CursorValue, Filter, FilterOperator, FilterValue, PaginationParams, SearchParams, SortDirection};
2
3pub struct PaginatorBuilder {
4 params: PaginationParams,
5}
6
7impl Default for PaginatorBuilder {
8 fn default() -> Self {
9 Self::new()
10 }
11}
12
13impl PaginatorBuilder {
14 pub fn new() -> Self {
15 Self {
16 params: PaginationParams::default(),
17 }
18 }
19
20 pub fn page(mut self, page: u32) -> Self {
21 self.params.page = page.max(1);
22 self
23 }
24
25 pub fn per_page(mut self, per_page: u32) -> Self {
26 self.params.per_page = per_page.max(1).min(100);
27 self
28 }
29
30 pub fn sort_by(mut self, field: impl Into<String>) -> Self {
31 self.params.sort_by = Some(field.into());
32 self
33 }
34
35 pub fn sort_asc(mut self) -> Self {
36 self.params.sort_direction = Some(SortDirection::Asc);
37 self
38 }
39
40 pub fn sort_desc(mut self) -> Self {
41 self.params.sort_direction = Some(SortDirection::Desc);
42 self
43 }
44
45 pub fn filter(
46 mut self,
47 field: impl Into<String>,
48 operator: FilterOperator,
49 value: FilterValue,
50 ) -> Self {
51 self.params
52 .filters
53 .push(Filter::new(field, operator, value));
54 self
55 }
56
57 pub fn filter_eq(mut self, field: impl Into<String>, value: FilterValue) -> Self {
58 self.params
59 .filters
60 .push(Filter::new(field, FilterOperator::Eq, value));
61 self
62 }
63
64 pub fn filter_ne(mut self, field: impl Into<String>, value: FilterValue) -> Self {
65 self.params
66 .filters
67 .push(Filter::new(field, FilterOperator::Ne, value));
68 self
69 }
70
71 pub fn filter_gt(mut self, field: impl Into<String>, value: FilterValue) -> Self {
72 self.params
73 .filters
74 .push(Filter::new(field, FilterOperator::Gt, value));
75 self
76 }
77
78 pub fn filter_lt(mut self, field: impl Into<String>, value: FilterValue) -> Self {
79 self.params
80 .filters
81 .push(Filter::new(field, FilterOperator::Lt, value));
82 self
83 }
84
85 pub fn filter_gte(mut self, field: impl Into<String>, value: FilterValue) -> Self {
86 self.params
87 .filters
88 .push(Filter::new(field, FilterOperator::Gte, value));
89 self
90 }
91
92 pub fn filter_lte(mut self, field: impl Into<String>, value: FilterValue) -> Self {
93 self.params
94 .filters
95 .push(Filter::new(field, FilterOperator::Lte, value));
96 self
97 }
98
99 pub fn filter_like(mut self, field: impl Into<String>, pattern: impl Into<String>) -> Self {
100 self.params.filters.push(Filter::new(
101 field,
102 FilterOperator::Like,
103 FilterValue::String(pattern.into()),
104 ));
105 self
106 }
107
108 pub fn filter_ilike(mut self, field: impl Into<String>, pattern: impl Into<String>) -> Self {
109 self.params.filters.push(Filter::new(
110 field,
111 FilterOperator::ILike,
112 FilterValue::String(pattern.into()),
113 ));
114 self
115 }
116
117 pub fn filter_in(mut self, field: impl Into<String>, values: Vec<FilterValue>) -> Self {
118 self.params.filters.push(Filter::new(
119 field,
120 FilterOperator::In,
121 FilterValue::Array(values),
122 ));
123 self
124 }
125
126 pub fn filter_between(
127 mut self,
128 field: impl Into<String>,
129 min: FilterValue,
130 max: FilterValue,
131 ) -> Self {
132 self.params.filters.push(Filter::new(
133 field,
134 FilterOperator::Between,
135 FilterValue::Array(vec![min, max]),
136 ));
137 self
138 }
139
140 pub fn filter_is_null(mut self, field: impl Into<String>) -> Self {
141 self.params.filters.push(Filter::new(
142 field,
143 FilterOperator::IsNull,
144 FilterValue::Null,
145 ));
146 self
147 }
148
149 pub fn filter_is_not_null(mut self, field: impl Into<String>) -> Self {
150 self.params.filters.push(Filter::new(
151 field,
152 FilterOperator::IsNotNull,
153 FilterValue::Null,
154 ));
155 self
156 }
157
158 pub fn search(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
159 self.params.search = Some(SearchParams::new(query, fields));
160 self
161 }
162
163 pub fn search_exact(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
164 self.params.search = Some(SearchParams::new(query, fields).with_exact_match(true));
165 self
166 }
167
168 pub fn search_case_sensitive(mut self, query: impl Into<String>, fields: Vec<String>) -> Self {
169 self.params.search = Some(SearchParams::new(query, fields).with_case_sensitive(true));
170 self
171 }
172
173 pub fn disable_total_count(mut self) -> Self {
174 self.params.disable_total_count = true;
175 self
176 }
177
178 pub fn cursor(mut self, field: impl Into<String>, value: CursorValue, direction: CursorDirection) -> Self {
179 self.params.cursor = Some(Cursor::new(field.into(), value, direction));
180 self
181 }
182
183 pub fn cursor_after(mut self, field: impl Into<String>, value: CursorValue) -> Self {
184 self.params.cursor = Some(Cursor::new(field.into(), value, CursorDirection::After));
185 self
186 }
187
188 pub fn cursor_before(mut self, field: impl Into<String>, value: CursorValue) -> Self {
189 self.params.cursor = Some(Cursor::new(field.into(), value, CursorDirection::Before));
190 self
191 }
192
193 pub fn cursor_from_encoded(mut self, encoded: &str) -> Result<Self, String> {
194 self.params.cursor = Some(Cursor::decode(encoded)?);
195 Ok(self)
196 }
197
198 pub fn build(self) -> PaginationParams {
199 self.params
200 }
201}