pexels_sdk/videos/
popular.rs

1use crate::{Pexels, PexelsError, VideoResponse, PEXELS_API, PEXELS_VIDEO_PATH};
2use url::Url;
3
4/// Path to get popular videos.
5const PEXELS_POPULAR_PATH: &str = "popular";
6
7/// Represents a request for popular videos from the Pexels API.
8pub struct Popular {
9    min_width: Option<usize>,
10    min_height: Option<usize>,
11    min_duration: Option<usize>,
12    max_duration: Option<usize>,
13    page: Option<usize>,
14    per_page: Option<usize>,
15}
16
17impl Popular {
18    /// Creates a new [`PopularBuilder`] for building URI's.
19    pub fn builder() -> PopularBuilder {
20        PopularBuilder::default()
21    }
22
23    /// Creates a URI from the provided parameters.
24    pub fn create_uri(&self) -> crate::BuilderResult {
25        let uri = format!("{PEXELS_API}/{PEXELS_VIDEO_PATH}/{PEXELS_POPULAR_PATH}");
26
27        let mut url = Url::parse(uri.as_str())?;
28
29        if let Some(min_width) = &self.min_width {
30            url.query_pairs_mut()
31                .append_pair("min_width", min_width.to_string().as_str());
32        }
33
34        if let Some(min_height) = &self.min_height {
35            url.query_pairs_mut()
36                .append_pair("min_height", min_height.to_string().as_str());
37        }
38
39        if let Some(min_duration) = &self.min_duration {
40            url.query_pairs_mut()
41                .append_pair("min_duration", min_duration.to_string().as_str());
42        }
43
44        if let Some(max_duration) = &self.max_duration {
45            url.query_pairs_mut()
46                .append_pair("max_duration", max_duration.to_string().as_str());
47        }
48
49        if let Some(page) = &self.page {
50            url.query_pairs_mut()
51                .append_pair("page", page.to_string().as_str());
52        }
53
54        if let Some(per_page) = &self.per_page {
55            url.query_pairs_mut()
56                .append_pair("per_page", per_page.to_string().as_str());
57        }
58
59        Ok(url.into())
60    }
61
62    /// Fetches the list of popular videos from the Pexels API.
63    pub async fn fetch(&self, client: &Pexels) -> Result<VideoResponse, PexelsError> {
64        let url = self.create_uri()?;
65        let response = client.make_request(url.as_str()).await?;
66        let response_video: VideoResponse = serde_json::from_value(response)?;
67        Ok(response_video)
68    }
69}
70
71/// Builder for [`Popular`].
72#[derive(Default)]
73pub struct PopularBuilder {
74    min_width: Option<usize>,
75    min_height: Option<usize>,
76    min_duration: Option<usize>,
77    max_duration: Option<usize>,
78    page: Option<usize>,
79    per_page: Option<usize>,
80}
81
82impl PopularBuilder {
83    /// Creates a new [`PopularBuilder`].
84    pub fn new() -> Self {
85        Self::default()
86    }
87
88    /// Sets the minimum width in pixels of the returned videos.
89    pub fn min_width(mut self, min_width: usize) -> Self {
90        self.min_width = Some(min_width);
91        self
92    }
93
94    /// Sets the minimum height in pixels of the returned videos.
95    pub fn min_height(mut self, min_height: usize) -> Self {
96        self.min_height = Some(min_height);
97        self
98    }
99
100    /// Sets the minimum duration in seconds of the returned videos.
101    pub fn min_duration(mut self, min_duration: usize) -> Self {
102        self.min_duration = Some(min_duration);
103        self
104    }
105
106    /// Sets the maximum duration in seconds of the returned videos.
107    pub fn max_duration(mut self, max_duration: usize) -> Self {
108        self.max_duration = Some(max_duration);
109        self
110    }
111
112    /// Sets the page number for the request.
113    pub fn page(mut self, page: usize) -> Self {
114        self.page = Some(page);
115        self
116    }
117
118    /// Sets the number of results per page for the request.
119    pub fn per_page(mut self, per_page: usize) -> Self {
120        self.per_page = Some(per_page);
121        self
122    }
123
124    /// Builds a `Popular` instance from the `PopularBuilder`.
125    pub fn build(self) -> Popular {
126        Popular {
127            page: self.page,
128            per_page: self.per_page,
129            min_width: self.min_width,
130            min_height: self.min_height,
131            min_duration: self.min_duration,
132            max_duration: self.max_duration,
133        }
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn test_min_width() {
143        let uri = PopularBuilder::new().min_width(1).build();
144        assert_eq!(
145            "https://api.pexels.com/videos/popular?min_width=1",
146            uri.create_uri().unwrap()
147        );
148    }
149
150    #[test]
151    fn test_min_height() {
152        let uri = PopularBuilder::new().min_height(1).build();
153        assert_eq!(
154            "https://api.pexels.com/videos/popular?min_height=1",
155            uri.create_uri().unwrap()
156        );
157    }
158
159    #[test]
160    fn test_min_duration() {
161        let uri = PopularBuilder::new().min_duration(10).build();
162        assert_eq!(
163            "https://api.pexels.com/videos/popular?min_duration=10",
164            uri.create_uri().unwrap()
165        );
166    }
167
168    #[test]
169    fn test_max_duration() {
170        let uri = PopularBuilder::new().max_duration(100).build();
171        assert_eq!(
172            "https://api.pexels.com/videos/popular?max_duration=100",
173            uri.create_uri().unwrap()
174        );
175    }
176
177    #[test]
178    fn test_page() {
179        let uri = PopularBuilder::new().page(1).build();
180        assert_eq!(
181            "https://api.pexels.com/videos/popular?page=1",
182            uri.create_uri().unwrap()
183        );
184    }
185
186    #[test]
187    fn test_per_page() {
188        let uri = PopularBuilder::new().per_page(1).build();
189        assert_eq!(
190            "https://api.pexels.com/videos/popular?per_page=1",
191            uri.create_uri().unwrap()
192        );
193    }
194}