tiktok_api/endpoints/v2/
common.rs

1use 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::v2::ResponseErrorBody;
10
11//
12//
13//
14#[derive(Debug, Clone)]
15pub enum EndpointRet<T>
16where
17    T: core::fmt::Debug + Clone,
18{
19    Ok(T),
20    Other((StatusCode, Result<ResponseErrorBody, Result<String, Body>>)),
21}
22
23//
24//
25//
26#[derive(Debug)]
27pub enum EndpointError {
28    MakeRequestUrlFailed(UrlParseError),
29    SerRequestBodyFailed(SerdeJsonError),
30    MakeRequestFailed(HttpError),
31    DeResponseBodyFailed(SerdeJsonError),
32    #[cfg(feature = "with_tokio_fs")]
33    GetFileInfoFailed(std::io::Error),
34}
35impl core::fmt::Display for EndpointError {
36    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
37        write!(f, "{self:?}")
38    }
39}
40impl std::error::Error for EndpointError {}
41
42//
43//
44//
45pub fn endpoint_parse_response<T>(response: Response<Body>) -> Result<EndpointRet<T>, EndpointError>
46where
47    T: core::fmt::Debug + Clone + DeserializeOwned,
48{
49    let status = response.status();
50    match status {
51        StatusCode::OK => {
52            let ok_json = serde_json::from_slice::<T>(response.body())
53                .map_err(EndpointError::DeResponseBodyFailed)?;
54
55            Ok(EndpointRet::Ok(ok_json))
56        }
57        status => match serde_json::from_slice::<ResponseErrorBody>(response.body()) {
58            Ok(err_json) => Ok(EndpointRet::Other((status, Ok(err_json)))),
59            Err(_) => Ok(EndpointRet::Other((
60                status,
61                Err(String::from_utf8(response.body().to_owned())
62                    .map_err(|_| response.body().to_owned())),
63            ))),
64        },
65    }
66}