microsoft_cognitive_computer_vision/operations/
common.rs1use 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;
9use url::ParseError as UrlParseError;
10
11#[derive(Debug, Clone)]
15pub enum EndpointRet<T>
16where
17 T: fmt::Debug + Clone,
18{
19 Ok(T),
20 Other((StatusCode, Result<EndpointResponseBodyErrJson, Body>)),
21}
22
23#[derive(thiserror::Error, Debug)]
27pub enum EndpointError {
28 #[error("MakeRequestUrlFailed {0}")]
29 MakeRequestUrlFailed(UrlParseError),
30 #[error("ImageInputToRequestBodyFailed {0}")]
31 ImageInputToRequestBodyFailed(String),
32 #[error("MakeRequestFailed {0}")]
33 MakeRequestFailed(HttpError),
34 #[error("DeResponseBodyOkJsonFailed {0}")]
35 DeResponseBodyOkJsonFailed(SerdeJsonError),
36}
37
38#[derive(Serialize, Deserialize, Debug, Clone)]
42pub struct EndpointResponseBodyErrJson {
43 pub error: EndpointResponseBodyErrJsonError,
44}
45
46#[derive(Serialize, Deserialize, Debug, Clone)]
47pub struct EndpointResponseBodyErrJsonError {
48 pub code: String,
49 pub message: String,
50 pub innererror: Option<EndpointResponseBodyErrJsonErrorInnererror>,
51}
52
53#[derive(Serialize, Deserialize, Debug, Clone)]
54pub struct EndpointResponseBodyErrJsonErrorInnererror {
55 pub code: String,
56 pub message: String,
57}
58
59pub fn endpoint_parse_response<T>(response: Response<Body>) -> Result<EndpointRet<T>, EndpointError>
63where
64 T: fmt::Debug + Clone + DeserializeOwned,
65{
66 let status = response.status();
67 match status {
68 StatusCode::OK => {
69 let ok_json = serde_json::from_slice::<T>(response.body())
70 .map_err(EndpointError::DeResponseBodyOkJsonFailed)?;
71
72 Ok(EndpointRet::Ok(ok_json))
73 }
74 StatusCode::METHOD_NOT_ALLOWED => {
75 match serde_json::from_slice::<EndpointResponseBodyErrJsonError>(response.body()) {
76 Ok(err_json) => Ok(EndpointRet::Other((
77 status,
78 Ok(EndpointResponseBodyErrJson { error: err_json }),
79 ))),
80 Err(_) => Ok(EndpointRet::Other((
81 status,
82 Err(response.body().to_owned()),
83 ))),
84 }
85 }
86 status => match serde_json::from_slice::<EndpointResponseBodyErrJson>(response.body()) {
87 Ok(err_json) => Ok(EndpointRet::Other((status, Ok(err_json)))),
88 Err(_) => Ok(EndpointRet::Other((
89 status,
90 Err(response.body().to_owned()),
91 ))),
92 },
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn de_response_body_err_json() {
102 match serde_json::from_str::<EndpointResponseBodyErrJson>(include_str!(
103 "../../tests/response_body_files/detect_objects_err__401.json"
104 )) {
105 Ok(err_json) => {
106 assert_eq!(err_json.error.code, "401");
107 }
108 Err(err) => panic!("{}", err),
109 }
110 }
111}