giphy_api_lite/endpoints/
emoji.rs1use 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 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#[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}