google_cloud_vision_rest/v1/resources/
method_common.rs

1use core::fmt;
2
3use http_api_client_endpoint::{
4    http::{Error as HttpError, StatusCode},
5    Body, Response,
6};
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
8use serde_json::Error as SerdeJsonError;
9
10//
11//
12//
13#[derive(Debug, Clone)]
14pub enum MethodEndpointRet<T>
15where
16    T: fmt::Debug + Clone,
17{
18    Ok(T),
19    Other((StatusCode, Result<MethodResponseErrorBody, Body>)),
20}
21
22//
23//
24//
25#[derive(thiserror::Error, Debug)]
26pub enum MethodEndpointError {
27    #[error("SerRequestBodyFailed {0}")]
28    SerRequestBodyFailed(SerdeJsonError),
29    #[error("MakeRequestFailed {0}")]
30    MakeRequestFailed(HttpError),
31    #[error("DeResponseBodyFailed {0}")]
32    DeResponseBodyFailed(SerdeJsonError),
33}
34
35//
36//
37//
38#[derive(Serialize, Deserialize, Debug, Clone)]
39pub struct MethodResponseErrorBody {
40    pub error: MethodResponseErrorBodyError,
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone)]
44pub struct MethodResponseErrorBodyError {
45    pub code: usize,
46    pub message: String,
47    pub status: String,
48}
49
50//
51//
52//
53pub fn method_endpoint_parse_response<T>(
54    response: Response<Body>,
55) -> Result<MethodEndpointRet<T>, MethodEndpointError>
56where
57    T: fmt::Debug + Clone + DeserializeOwned,
58{
59    let status = response.status();
60    match status {
61        StatusCode::OK => {
62            let ok_json = serde_json::from_slice::<T>(response.body())
63                .map_err(MethodEndpointError::DeResponseBodyFailed)?;
64
65            Ok(MethodEndpointRet::Ok(ok_json))
66        }
67        status => match serde_json::from_slice::<MethodResponseErrorBody>(response.body()) {
68            Ok(err_json) => Ok(MethodEndpointRet::Other((status, Ok(err_json)))),
69            Err(_) => Ok(MethodEndpointRet::Other((
70                status,
71                Err(response.body().to_owned()),
72            ))),
73        },
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn de_response_error_body() {
83        match serde_json::from_str::<MethodResponseErrorBody>(include_str!(
84            "../../../tests/response_body_files/err__401.json"
85        )) {
86            Ok(body) => {
87                assert_eq!(body.error.code, 401);
88            }
89            Err(err) => panic!("{}", err),
90        }
91    }
92}