use serde::de::DeserializeOwned;
use crate::error::{ApiError, ApiException, Error};
#[derive(Debug, Clone, Copy)]
pub(crate) enum ErrorKind {
Rich,
Legacy,
}
pub(crate) async fn decode_response<T: DeserializeOwned>(
response: reqwest::Response,
kind: ErrorKind,
) -> Result<T, Error> {
let status = response.status();
if status.is_success() {
let bytes = response.bytes().await?;
if bytes.is_empty() {
return Ok(serde_json::from_str::<T>("null")
.or_else(|_| serde_json::from_str::<T>("{}"))?);
}
return Ok(serde_json::from_slice(&bytes)?);
}
let status_code = status.as_u16();
let body = response.text().await.unwrap_or_default();
match kind {
ErrorKind::Rich => {
if let Ok(api_error) = serde_json::from_str::<ApiError>(&body) {
return Err(Error::Api {
status: status_code,
error: Box::new(api_error),
});
}
}
ErrorKind::Legacy => {
if let Ok(exception) = serde_json::from_str::<ApiException>(&body) {
return Err(Error::Exception {
status: status_code,
exception: Box::new(exception),
});
}
}
}
Err(Error::Unexpected {
status: status_code,
body,
})
}