giphy_api_lite/endpoints/
emoji.rs

1//! https://developers.giphy.com/docs/api/endpoint#trending
2
3use http_api_client_endpoint::{
4    http::{
5        header::{ACCEPT, USER_AGENT},
6        Method, StatusCode,
7    },
8    Body, Endpoint, Request, Response, MIME_APPLICATION_JSON,
9};
10use serde::{Deserialize, Serialize};
11use url::Url;
12
13use crate::{
14    endpoints::{
15        common::{EndpointError, EndpointRet},
16        URL_BASE, USER_AGENT_VALUE,
17    },
18    objects::{gif::Gif, meta::Meta, pagination::Pagination, ResponseBodyErrJson},
19    types::rating::Rating,
20};
21
22#[derive(Debug, Clone)]
23pub struct Emoji {
24    pub api_key: String,
25    //
26    pub limit: Option<u32>,
27    pub offset: Option<u32>,
28    pub rating: Option<Rating>,
29    pub random_id: Option<String>,
30}
31
32impl Emoji {
33    pub fn new(api_key: impl AsRef<str>) -> Self {
34        Self {
35            api_key: api_key.as_ref().to_owned(),
36            limit: Default::default(),
37            offset: Default::default(),
38            rating: Default::default(),
39            random_id: Default::default(),
40        }
41    }
42}
43
44impl Endpoint for Emoji {
45    type RenderRequestError = EndpointError;
46
47    type ParseResponseOutput = EndpointRet<EmojiResponseBodyOkJson>;
48    type ParseResponseError = EndpointError;
49
50    fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
51        let url = format!("{}/emoji", URL_BASE);
52        let mut url = Url::parse(url.as_str()).map_err(EndpointError::MakeRequestUrlFailed)?;
53
54        url.query_pairs_mut().append_pair("api_key", &self.api_key);
55
56        if let Some(limit) = &self.limit {
57            url.query_pairs_mut()
58                .append_pair("limit", limit.to_string().as_str());
59        }
60        if let Some(offset) = &self.offset {
61            url.query_pairs_mut()
62                .append_pair("offset", offset.to_string().as_str());
63        }
64        if let Some(rating) = &self.rating {
65            url.query_pairs_mut()
66                .append_pair("rating", rating.to_string().as_str());
67        }
68        if let Some(random_id) = &self.random_id {
69            url.query_pairs_mut().append_pair("random_id", random_id);
70        }
71
72        let request = Request::builder()
73            .method(Method::GET)
74            .uri(url.as_str())
75            .header(USER_AGENT, USER_AGENT_VALUE)
76            .header(ACCEPT, MIME_APPLICATION_JSON)
77            .body(vec![])
78            .map_err(EndpointError::MakeRequestFailed)?;
79
80        Ok(request)
81    }
82
83    fn parse_response(
84        &self,
85        response: Response<Body>,
86    ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
87        let status = response.status();
88        match status {
89            StatusCode::OK => Ok(EndpointRet::Ok(
90                serde_json::from_slice(response.body())
91                    .map_err(EndpointError::DeResponseBodyOkJsonFailed)?,
92            )),
93            StatusCode::TOO_MANY_REQUESTS => Ok(EndpointRet::RateLimitIsReached),
94            status => match serde_json::from_slice::<ResponseBodyErrJson>(response.body()) {
95                Ok(err_json) => Ok(EndpointRet::Other((status, Ok(err_json)))),
96                Err(_) => Ok(EndpointRet::Other((
97                    status,
98                    Err(response.body().to_owned()),
99                ))),
100            },
101        }
102    }
103}
104
105//
106//
107//
108#[derive(Deserialize, Serialize, Debug, Clone)]
109pub struct EmojiResponseBodyOkJson {
110    pub data: Vec<Gif>,
111    pub pagination: Pagination,
112    pub meta: Meta,
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118
119    #[test]
120    fn de_response_body_ok_json() {
121        match serde_json::from_str::<EmojiResponseBodyOkJson>(include_str!(
122            "../../tests/response_body_json_files/emoji_ok.json"
123        )) {
124            Ok(ok_json) => {
125                assert_eq!(ok_json.data.len(), 50);
126            }
127            Err(err) => panic!("{}", err),
128        }
129    }
130}