tiktok_api/endpoints/oauth/
common.rs1use http_api_client_endpoint::{
2 http::{Error as HttpError, StatusCode},
3 Body, Response,
4};
5use serde::de::DeserializeOwned;
6use serde_json::Error as SerdeJsonError;
7use url::ParseError as UrlParseError;
8
9use crate::objects::oauth::ResponseErrorBody;
10
11#[derive(Debug, Clone)]
15pub enum EndpointRet<T>
16where
17 T: core::fmt::Debug + Clone,
18{
19 Ok(T),
20 Other((StatusCode, Result<ResponseErrorBody, Body>)),
21}
22
23#[derive(Debug)]
27pub enum EndpointError {
28 MakeRequestUrlFailed(UrlParseError),
29 MakeRequestFailed(HttpError),
30 DeResponseBodyFailed(SerdeJsonError),
31}
32impl core::fmt::Display for EndpointError {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 write!(f, "{self:?}")
35 }
36}
37impl std::error::Error for EndpointError {}
38
39pub fn endpoint_parse_response<T>(response: Response<Body>) -> Result<EndpointRet<T>, EndpointError>
43where
44 T: core::fmt::Debug + Clone + DeserializeOwned,
45{
46 let status = response.status();
47 #[allow(clippy::single_match)]
48 match status {
49 StatusCode::OK => {
50 use crate::objects::oauth::Message;
51
52 #[allow(clippy::single_match)]
53 match serde_json::from_slice::<Message>(response.body()) {
54 Ok(Message::Success) => {
55 let ok_json = serde_json::from_slice::<T>(response.body())
56 .map_err(EndpointError::DeResponseBodyFailed)?;
57
58 return Ok(EndpointRet::Ok(ok_json));
59 }
60 _ => {}
61 }
62 }
63 _ => {}
64 }
65
66 match serde_json::from_slice::<ResponseErrorBody>(response.body()) {
67 Ok(err_json) => Ok(EndpointRet::Other((status, Ok(err_json)))),
68 Err(_) => Ok(EndpointRet::Other((
69 status,
70 Err(response.body().to_owned()),
71 ))),
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_endpoint_parse_response() -> Result<(), Box<dyn std::error::Error>> {
81 let resp_body = include_str!("../../../tests/response_body_files/oauth/refresh_token__err_with_expired_refresh_token.json");
82 let resp = Response::builder()
83 .status(StatusCode::OK)
84 .body(resp_body.as_bytes().to_vec())?;
85
86 match endpoint_parse_response::<()>(resp) {
87 Ok(EndpointRet::Other((status_code, Ok(err_body)))) => {
88 assert_eq!(status_code, StatusCode::OK);
89 assert_eq!(err_body.data.error_code, 10010);
90 }
91 x => panic!("{x:?}"),
92 }
93
94 Ok(())
95 }
96}