use crate::error::ParseError;
use reqwest::{Method, Response as HttpResponse};
use serde::{de::DeserializeOwned, Serialize};
use serde_json::Value;
impl crate::Parse {
pub(crate) async fn _send_and_process_response<R: DeserializeOwned + Send + 'static>(
&self, response: HttpResponse, _endpoint_context: &str, ) -> Result<R, ParseError> {
let status = response.status();
let response_url = response.url().to_string();
let response_text = response.text().await.map_err(ParseError::ReqwestError)?;
if status.is_success() {
if response_text.is_empty() || response_text == "{}" {
if std::any::TypeId::of::<R>() == std::any::TypeId::of::<()>() {
return serde_json::from_str("null").map_err(ParseError::JsonError);
}
}
serde_json::from_str::<R>(&response_text).map_err(|e| {
log::error!(
"JSON Deserialization failed for successful response from '{}'. Status: {}. Error: {}. Body: {}",
response_url,
status,
e,
&response_text );
ParseError::JsonDeserializationFailed(format!(
"Failed to deserialize successful response from '{}': {}. Body: {}",
response_url, e, &response_text
))
})
} else {
let parsed_body: Value = match serde_json::from_str(&response_text) {
Ok(json_val) => json_val,
Err(_) => {
log::warn!(
"Failed to parse error response body as JSON from '{}'. Status: {}. Body: {}",
response_url, status, &response_text
);
Value::Object(serde_json::Map::from_iter(vec![
(
"error".to_string(),
Value::String(format!("HTTP Error {} with non-JSON body", status)),
),
(
"body_snippet".to_string(),
Value::String(response_text.chars().take(100).collect()),
),
]))
}
};
Err(ParseError::from_response(status.as_u16(), parsed_body))
}
}
pub async fn get<R: DeserializeOwned + Send + 'static>(
&self,
endpoint: &str,
) -> Result<R, ParseError> {
self._request(Method::GET, endpoint, None::<&Value>, false, None)
.await
}
pub async fn post<T: Serialize + Send + Sync, R: DeserializeOwned + Send + 'static>(
&self,
endpoint: &str,
data: &T,
) -> Result<R, ParseError> {
self._request(Method::POST, endpoint, Some(data), false, None)
.await
}
pub async fn put<T: Serialize + Send + Sync, R: DeserializeOwned + Send + 'static>(
&self,
endpoint: &str,
data: &T,
) -> Result<R, ParseError> {
self._request(Method::PUT, endpoint, Some(data), false, None)
.await
}
pub async fn delete<R: DeserializeOwned + Send + 'static>(
&self,
endpoint: &str,
) -> Result<R, ParseError> {
self._request(Method::DELETE, endpoint, None::<&Value>, false, None)
.await
}
}