pexels_api/photos/
photo.rs

1use crate::{Pexels, PexelsError, Photo, PEXELS_API, PEXELS_VERSION};
2use url::Url;
3
4/// Path to get a specific photo.
5const PEXELS_GET_PHOTO_PATH: &str = "photos";
6
7/// Retrieve a specific Photo from its id.
8pub struct FetchPhoto {
9    id: usize,
10}
11
12impl FetchPhoto {
13    /// Creates [`FetchPhotoBuilder`] for building URI's.
14    pub fn builder() -> FetchPhotoBuilder {
15        FetchPhotoBuilder::default()
16    }
17
18    /// Creates a URI from the values provided by the [`FetchPhotoBuilder`].
19    pub fn create_uri(&self) -> crate::BuilderResult {
20        let uri =
21            format!("{}/{}/{}/{}", PEXELS_API, PEXELS_VERSION, PEXELS_GET_PHOTO_PATH, self.id);
22
23        let url = Url::parse(uri.as_str())?;
24
25        Ok(url.into())
26    }
27
28    /// Fetches the photo data from the Pexels API using the provided client.
29    pub async fn fetch(&self, client: &Pexels) -> Result<Photo, PexelsError> {
30        let url = self.create_uri()?;
31        let response = client.make_request(url.as_str()).await?;
32        let photo: Photo = serde_json::from_value(response)?;
33        Ok(photo)
34    }
35}
36
37/// Builder for [`FetchPhoto`].
38#[derive(Default)]
39pub struct FetchPhotoBuilder {
40    id: usize,
41}
42
43impl FetchPhotoBuilder {
44    /// Create a new [`FetchPhotoBuilder`].
45    pub fn new() -> Self {
46        Self { id: 0 }
47    }
48
49    /// Sets the ID of the photo to be requested.
50    pub fn id(mut self, id: usize) -> Self {
51        self.id = id;
52        self
53    }
54
55    /// Create [`FetchPhoto`] from the [`FetchPhotoBuilder`]
56    pub fn build(self) -> FetchPhoto {
57        FetchPhoto { id: self.id }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64    use dotenvy::dotenv;
65    use std::env;
66    use tokio;
67
68    #[test]
69    fn test_id() {
70        let uri = FetchPhotoBuilder::new().id(123).build();
71        assert_eq!("https://api.pexels.com/v1/photos/123", uri.create_uri().unwrap());
72    }
73
74    #[tokio::test]
75    async fn test_fetch_photo() {
76        dotenv().ok();
77        let api_key = env::var("PEXELS_API_KEY").expect("PEXELS_API_KEY not set");
78        let client = Pexels::new(api_key);
79
80        let get_photo = FetchPhoto::builder().id(10967).build();
81        let result = get_photo.fetch(&client).await;
82        println!("get_photo result: {:?}", result);
83        assert!(result.is_ok());
84    }
85}