1use crate::{MediaSort, MediaType, Orientation, Size};
2
3#[derive(Debug, Clone, Default)]
4pub struct SearchParams {
5 pub page: Option<u32>,
6 pub per_page: Option<u32>,
7 pub orientation: Option<Orientation>,
8 pub size: Option<Size>,
9 pub color: Option<String>,
10 pub locale: Option<String>,
11}
12
13impl SearchParams {
14 pub fn new() -> Self {
15 Self::default()
16 }
17
18 pub fn page(mut self, page: u32) -> Self {
19 self.page = Some(page);
20 self
21 }
22
23 pub fn per_page(mut self, per_page: u32) -> Self {
24 self.per_page = Some(per_page);
25 self
26 }
27
28 pub fn orientation(mut self, orientation: Orientation) -> Self {
29 self.orientation = Some(orientation);
30 self
31 }
32
33 pub fn size(mut self, size: Size) -> Self {
34 self.size = Some(size);
35 self
36 }
37
38 pub fn color(mut self, color: impl Into<String>) -> Self {
39 self.color = Some(color.into());
40 self
41 }
42
43 pub fn locale(mut self, locale: impl Into<String>) -> Self {
44 self.locale = Some(locale.into());
45 self
46 }
47
48 pub fn to_query_params(&self) -> Vec<(String, String)> {
49 let mut params = Vec::new();
50
51 if let Some(page) = self.page {
52 params.push(("page".to_string(), page.to_string()));
53 }
54
55 if let Some(per_page) = self.per_page {
56 params.push(("per_page".to_string(), per_page.to_string()));
57 }
58
59 if let Some(orientation) = &self.orientation {
60 params.push(("orientation".to_string(), orientation.to_string()));
61 }
62
63 if let Some(size) = &self.size {
64 params.push(("size".to_string(), size.to_string()));
65 }
66
67 if let Some(color) = &self.color {
68 params.push(("color".to_string(), color.clone()));
69 }
70
71 if let Some(locale) = &self.locale {
72 params.push(("locale".to_string(), locale.clone()));
73 }
74
75 params
76 }
77}
78
79#[derive(Debug, Clone, Default)]
81pub struct PaginationParams {
82 pub page: Option<u32>,
84
85 pub per_page: Option<u32>,
87}
88
89impl PaginationParams {
90 pub fn new() -> Self {
92 Self::default()
93 }
94
95 pub fn page(mut self, page: u32) -> Self {
97 self.page = Some(page);
98 self
99 }
100
101 pub fn per_page(mut self, per_page: u32) -> Self {
103 self.per_page = Some(per_page);
104 self
105 }
106
107 pub(crate) fn to_query_params(&self) -> Vec<(String, String)> {
108 let mut params = Vec::new();
109
110 if let Some(page) = self.page {
111 params.push(("page".to_string(), page.to_string()));
112 }
113
114 if let Some(per_page) = self.per_page {
115 params.push(("per_page".to_string(), per_page.to_string()));
116 }
117
118 params
119 }
120}
121
122#[derive(Debug, Clone, Default)]
124pub struct VideoSearchParams {
125 pub page: Option<u32>,
127
128 pub per_page: Option<u32>,
130
131 pub orientation: Option<String>,
133
134 pub size: Option<String>,
136
137 pub locale: Option<String>,
139}
140
141impl VideoSearchParams {
142 pub fn new() -> Self {
144 Self::default()
145 }
146
147 pub fn page(mut self, page: u32) -> Self {
149 self.page = Some(page);
150 self
151 }
152
153 pub fn per_page(mut self, per_page: u32) -> Self {
155 self.per_page = Some(per_page);
156 self
157 }
158
159 pub fn orientation(mut self, orientation: impl Into<String>) -> Self {
161 self.orientation = Some(orientation.into());
162 self
163 }
164
165 pub fn size(mut self, size: impl Into<String>) -> Self {
167 self.size = Some(size.into());
168 self
169 }
170
171 pub fn locale(mut self, locale: impl Into<String>) -> Self {
173 self.locale = Some(locale.into());
174 self
175 }
176
177 pub(crate) fn to_query_params(&self) -> Vec<(String, String)> {
178 let mut params = Vec::new();
179
180 if let Some(page) = self.page {
181 params.push(("page".to_string(), page.to_string()));
182 }
183
184 if let Some(per_page) = self.per_page {
185 params.push(("per_page".to_string(), per_page.to_string()));
186 }
187
188 if let Some(orientation) = &self.orientation {
189 params.push(("orientation".to_string(), orientation.clone()));
190 }
191
192 if let Some(size) = &self.size {
193 params.push(("size".to_string(), size.clone()));
194 }
195
196 if let Some(locale) = &self.locale {
197 params.push(("locale".to_string(), locale.clone()));
198 }
199
200 params
201 }
202}
203
204#[derive(Debug, Clone, Default)]
206pub struct PopularVideoParams {
207 pub page: Option<u32>,
209
210 pub per_page: Option<u32>,
212
213 pub min_width: Option<u32>,
215
216 pub min_height: Option<u32>,
218
219 pub min_duration: Option<u32>,
221
222 pub max_duration: Option<u32>,
224}
225
226impl PopularVideoParams {
227 pub fn new() -> Self {
229 Self::default()
230 }
231
232 pub fn from_pagination(params: &PaginationParams) -> Self {
234 Self { page: params.page, per_page: params.per_page, ..Self::default() }
235 }
236
237 pub fn page(mut self, page: u32) -> Self {
239 self.page = Some(page);
240 self
241 }
242
243 pub fn per_page(mut self, per_page: u32) -> Self {
245 self.per_page = Some(per_page);
246 self
247 }
248
249 pub fn min_width(mut self, min_width: u32) -> Self {
251 self.min_width = Some(min_width);
252 self
253 }
254
255 pub fn min_height(mut self, min_height: u32) -> Self {
257 self.min_height = Some(min_height);
258 self
259 }
260
261 pub fn min_duration(mut self, min_duration: u32) -> Self {
263 self.min_duration = Some(min_duration);
264 self
265 }
266
267 pub fn max_duration(mut self, max_duration: u32) -> Self {
269 self.max_duration = Some(max_duration);
270 self
271 }
272
273 pub(crate) fn to_query_params(&self) -> Vec<(String, String)> {
274 let mut params = Vec::new();
275
276 if let Some(page) = self.page {
277 params.push(("page".to_string(), page.to_string()));
278 }
279
280 if let Some(per_page) = self.per_page {
281 params.push(("per_page".to_string(), per_page.to_string()));
282 }
283
284 if let Some(min_width) = self.min_width {
285 params.push(("min_width".to_string(), min_width.to_string()));
286 }
287
288 if let Some(min_height) = self.min_height {
289 params.push(("min_height".to_string(), min_height.to_string()));
290 }
291
292 if let Some(min_duration) = self.min_duration {
293 params.push(("min_duration".to_string(), min_duration.to_string()));
294 }
295
296 if let Some(max_duration) = self.max_duration {
297 params.push(("max_duration".to_string(), max_duration.to_string()));
298 }
299
300 params
301 }
302}
303
304#[derive(Debug, Clone, Default)]
306pub struct CollectionMediaParams {
307 pub page: Option<u32>,
309
310 pub per_page: Option<u32>,
312
313 pub media_type: Option<MediaType>,
315
316 pub sort: Option<MediaSort>,
318}
319
320impl CollectionMediaParams {
321 pub fn new() -> Self {
323 Self::default()
324 }
325
326 pub fn from_pagination(params: &PaginationParams) -> Self {
328 Self { page: params.page, per_page: params.per_page, ..Self::default() }
329 }
330
331 pub fn page(mut self, page: u32) -> Self {
333 self.page = Some(page);
334 self
335 }
336
337 pub fn per_page(mut self, per_page: u32) -> Self {
339 self.per_page = Some(per_page);
340 self
341 }
342
343 pub fn media_type(mut self, media_type: MediaType) -> Self {
345 self.media_type = Some(media_type);
346 self
347 }
348
349 pub fn sort(mut self, sort: MediaSort) -> Self {
351 self.sort = Some(sort);
352 self
353 }
354
355 pub(crate) fn to_query_params(&self) -> Vec<(String, String)> {
356 let mut params = Vec::new();
357
358 if let Some(page) = self.page {
359 params.push(("page".to_string(), page.to_string()));
360 }
361
362 if let Some(per_page) = self.per_page {
363 params.push(("per_page".to_string(), per_page.to_string()));
364 }
365
366 if let Some(media_type) = &self.media_type {
367 if !matches!(media_type, MediaType::Empty) {
368 params.push(("type".to_string(), media_type.as_str().to_string()));
369 }
370 }
371
372 if let Some(sort) = &self.sort {
373 params.push(("sort".to_string(), sort.as_str().to_string()));
374 }
375
376 params
377 }
378}
379
380#[cfg(test)]
381mod tests {
382 use super::*;
383
384 #[test]
385 fn popular_video_params_include_documented_filters() {
386 let params = PopularVideoParams::new()
387 .page(2)
388 .per_page(20)
389 .min_width(1280)
390 .min_height(720)
391 .min_duration(5)
392 .max_duration(60)
393 .to_query_params();
394
395 assert_eq!(
396 params,
397 vec![
398 ("page".to_string(), "2".to_string()),
399 ("per_page".to_string(), "20".to_string()),
400 ("min_width".to_string(), "1280".to_string()),
401 ("min_height".to_string(), "720".to_string()),
402 ("min_duration".to_string(), "5".to_string()),
403 ("max_duration".to_string(), "60".to_string()),
404 ]
405 );
406 }
407
408 #[test]
409 fn collection_media_params_include_type_and_sort() {
410 let params = CollectionMediaParams::new()
411 .page(1)
412 .per_page(10)
413 .media_type(MediaType::Photo)
414 .sort(MediaSort::Desc)
415 .to_query_params();
416
417 assert_eq!(
418 params,
419 vec![
420 ("page".to_string(), "1".to_string()),
421 ("per_page".to_string(), "10".to_string()),
422 ("type".to_string(), "photos".to_string()),
423 ("sort".to_string(), "desc".to_string()),
424 ]
425 );
426 }
427}