pexels_api/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().append_pair("min_width", min_width.to_string().as_str());
31        }
32
33        if let Some(min_height) = &self.min_height {
34            url.query_pairs_mut().append_pair("min_height", min_height.to_string().as_str());
35        }
36
37        if let Some(min_duration) = &self.min_duration {
38            url.query_pairs_mut().append_pair("min_duration", min_duration.to_string().as_str());
39        }
40
41        if let Some(max_duration) = &self.max_duration {
42            url.query_pairs_mut().append_pair("max_duration", max_duration.to_string().as_str());
43        }
44
45        if let Some(page) = &self.page {
46            url.query_pairs_mut().append_pair("page", page.to_string().as_str());
47        }
48
49        if let Some(per_page) = &self.per_page {
50            url.query_pairs_mut().append_pair("per_page", per_page.to_string().as_str());
51        }
52
53        Ok(url.into())
54    }
55
56    /// Fetches the list of popular videos from the Pexels API.
57    pub async fn fetch(&self, client: &Pexels) -> Result<VideoResponse, PexelsError> {
58        let url = self.create_uri()?;
59        let response = client.make_request(url.as_str()).await?;
60        let response_video: VideoResponse = serde_json::from_value(response)?;
61        Ok(response_video)
62    }
63}
64
65/// Builder for [`Popular`].
66#[derive(Default)]
67pub struct PopularBuilder {
68    min_width: Option<usize>,
69    min_height: Option<usize>,
70    min_duration: Option<usize>,
71    max_duration: Option<usize>,
72    page: Option<usize>,
73    per_page: Option<usize>,
74}
75
76impl PopularBuilder {
77    /// Creates a new [`PopularBuilder`].
78    pub fn new() -> Self {
79        Self::default()
80    }
81
82    /// Sets the minimum width in pixels of the returned videos.
83    pub fn min_width(mut self, min_width: usize) -> Self {
84        self.min_width = Some(min_width);
85        self
86    }
87
88    /// Sets the minimum height in pixels of the returned videos.
89    pub fn min_height(mut self, min_height: usize) -> Self {
90        self.min_height = Some(min_height);
91        self
92    }
93
94    /// Sets the minimum duration in seconds of the returned videos.
95    pub fn min_duration(mut self, min_duration: usize) -> Self {
96        self.min_duration = Some(min_duration);
97        self
98    }
99
100    /// Sets the maximum duration in seconds of the returned videos.
101    pub fn max_duration(mut self, max_duration: usize) -> Self {
102        self.max_duration = Some(max_duration);
103        self
104    }
105
106    /// Sets the page number for the request.
107    pub fn page(mut self, page: usize) -> Self {
108        self.page = Some(page);
109        self
110    }
111
112    /// Sets the number of results per page for the request.
113    pub fn per_page(mut self, per_page: usize) -> Self {
114        self.per_page = Some(per_page);
115        self
116    }
117
118    /// Builds a `Popular` instance from the `PopularBuilder`.
119    pub fn build(self) -> Popular {
120        Popular {
121            page: self.page,
122            per_page: self.per_page,
123            min_width: self.min_width,
124            min_height: self.min_height,
125            min_duration: self.min_duration,
126            max_duration: self.max_duration,
127        }
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn test_min_width() {
137        let uri = PopularBuilder::new().min_width(1).build();
138        assert_eq!("https://api.pexels.com/videos/popular?min_width=1", uri.create_uri().unwrap());
139    }
140
141    #[test]
142    fn test_min_height() {
143        let uri = PopularBuilder::new().min_height(1).build();
144        assert_eq!("https://api.pexels.com/videos/popular?min_height=1", uri.create_uri().unwrap());
145    }
146
147    #[test]
148    fn test_min_duration() {
149        let uri = PopularBuilder::new().min_duration(10).build();
150        assert_eq!(
151            "https://api.pexels.com/videos/popular?min_duration=10",
152            uri.create_uri().unwrap()
153        );
154    }
155
156    #[test]
157    fn test_max_duration() {
158        let uri = PopularBuilder::new().max_duration(100).build();
159        assert_eq!(
160            "https://api.pexels.com/videos/popular?max_duration=100",
161            uri.create_uri().unwrap()
162        );
163    }
164
165    #[test]
166    fn test_page() {
167        let uri = PopularBuilder::new().page(1).build();
168        assert_eq!("https://api.pexels.com/videos/popular?page=1", uri.create_uri().unwrap());
169    }
170
171    #[test]
172    fn test_per_page() {
173        let uri = PopularBuilder::new().per_page(1).build();
174        assert_eq!("https://api.pexels.com/videos/popular?per_page=1", uri.create_uri().unwrap());
175    }
176}