pexels_sdk/collections/
media.rs

1use crate::{
2    MediaResponse, MediaSort, MediaType, Pexels, PexelsError, PEXELS_API, PEXELS_COLLECTIONS_PATH,
3    PEXELS_VERSION,
4};
5use url::Url;
6
7/// Represents a request to fetch a specific media item by its ID from the Pexels API.
8/// This endpoint returns all media items (photos and videos) within a single collection.
9/// Use the `type` parameter to filter results to only photos or only videos.
10pub struct Media {
11    id: String,
12    r#type: Option<MediaType>,
13    sort: Option<MediaSort>,
14    page: Option<usize>,
15    per_page: Option<usize>,
16}
17
18impl Media {
19    /// Creates a new `MediaBuilder` for constructing a `Media` request.
20    pub fn builder() -> MediaBuilder {
21        MediaBuilder::new()
22    }
23
24    /// Constructs the URI for the media request based on the builder's parameters.
25    pub fn create_uri(&self) -> crate::BuilderResult {
26        let uri = format!(
27            "{}/{}/{}/{}",
28            PEXELS_API, PEXELS_VERSION, PEXELS_COLLECTIONS_PATH, self.id
29        );
30
31        let mut url = Url::parse(uri.as_str())?;
32
33        if let Some(r#type) = &self.r#type {
34            match r#type {
35                MediaType::Empty => {}
36                _ => {
37                    url.query_pairs_mut().append_pair("type", r#type.as_str());
38                }
39            }
40        }
41
42        if let Some(sort) = &self.sort {
43            url.query_pairs_mut().append_pair("sort", sort.as_str());
44        }
45
46        if let Some(page) = &self.page {
47            url.query_pairs_mut()
48                .append_pair("page", page.to_string().as_str());
49        }
50
51        if let Some(per_page) = &self.per_page {
52            url.query_pairs_mut()
53                .append_pair("per_page", per_page.to_string().as_str());
54        }
55
56        Ok(url.into())
57    }
58
59    /// Fetches the media data from the Pexels API.
60    pub async fn fetch(&self, client: &Pexels) -> Result<MediaResponse, PexelsError> {
61        let url = self.create_uri()?;
62        let response = client.make_request(url.as_str()).await?;
63        let media_response: MediaResponse = serde_json::from_value(response)?;
64        Ok(media_response)
65    }
66}
67
68/// Builder for constructing a `Media` request.
69#[derive(Default)]
70pub struct MediaBuilder {
71    id: String,
72    r#type: Option<MediaType>,
73    sort: Option<MediaSort>,
74    page: Option<usize>,
75    per_page: Option<usize>,
76}
77
78impl MediaBuilder {
79    /// Creates a new `MediaBuilder`.
80    pub fn new() -> Self {
81        Self {
82            id: "".to_string(),
83            r#type: None,
84            sort: None,
85            page: None,
86            per_page: None,
87        }
88    }
89
90    /// Sets the ID of the media item to be fetched.
91    pub fn id(mut self, id: String) -> Self {
92        self.id = id;
93        self
94    }
95
96    /// Sets the type of media to be fetched (photo or video).
97    pub fn r#type(mut self, r#type: MediaType) -> Self {
98        self.r#type = Some(r#type);
99        self
100    }
101
102    /// Sets the sorting order of the media items.
103    pub fn sort(mut self, sort: MediaSort) -> Self {
104        self.sort = Some(sort);
105        self
106    }
107
108    /// Sets the page number for the request.
109    pub fn page(mut self, page: usize) -> Self {
110        self.page = Some(page);
111        self
112    }
113
114    /// Sets the number of results per page for the request.
115    pub fn per_page(mut self, per_page: usize) -> Self {
116        self.per_page = Some(per_page);
117        self
118    }
119
120    /// Builds a `Media` instance from the `MediaBuilder`.
121    pub fn build(self) -> Media {
122        Media {
123            id: self.id,
124            r#type: self.r#type,
125            sort: self.sort,
126            page: self.page,
127            per_page: self.per_page,
128        }
129    }
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn test_id() {
138        let uri = MediaBuilder::new().id("123".to_string()).build();
139        assert_eq!(
140            "https://api.pexels.com/v1/collections/123",
141            uri.create_uri().unwrap()
142        );
143    }
144}