use crate::core::error::Result;
use async_trait::async_trait;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::Value;
#[async_trait]
pub trait HttpProviderSafe: Send + Sync {
async fn get_json(&self, path: &str) -> Result<Value>;
async fn post_json(&self, path: &str, body: Value) -> Result<Value>;
async fn put_json(&self, path: &str, body: Value) -> Result<Value>;
async fn delete_json(&self, path: &str) -> Result<Value>;
async fn post_binary(&self, path: &str, body: Value) -> Result<Vec<u8>>;
}
#[async_trait]
pub trait HttpProviderExt: HttpProviderSafe {
async fn get<T>(&self, path: &str) -> Result<T>
where
T: DeserializeOwned + Send,
{
let json = self.get_json(path).await?;
serde_json::from_value(json)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))
}
async fn post<T, B>(&self, path: &str, body: &B) -> Result<T>
where
T: DeserializeOwned + Send,
B: Serialize + Send + Sync,
{
let body_json = serde_json::to_value(body)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))?;
let json = self.post_json(path, body_json).await?;
serde_json::from_value(json)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))
}
async fn put<T, B>(&self, path: &str, body: &B) -> Result<T>
where
T: DeserializeOwned + Send,
B: Serialize + Send + Sync,
{
let body_json = serde_json::to_value(body)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))?;
let json = self.put_json(path, body_json).await?;
serde_json::from_value(json)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))
}
async fn delete<T>(&self, path: &str) -> Result<T>
where
T: DeserializeOwned + Send,
{
let json = self.delete_json(path).await?;
serde_json::from_value(json)
.map_err(|e| crate::core::error::Error::Serialization(e.to_string()))
}
}
impl<T: HttpProviderSafe + ?Sized> HttpProviderExt for T {}
use crate::transport::HttpClient;
pub struct HttpClientAdapter {
client: HttpClient,
}
impl HttpClientAdapter {
pub fn new(client: HttpClient) -> Self {
Self { client }
}
}
#[async_trait]
impl HttpProviderSafe for HttpClientAdapter {
async fn get_json(&self, path: &str) -> Result<Value> {
self.client.get(path).await
}
async fn post_json(&self, path: &str, body: Value) -> Result<Value> {
self.client.post(path, &body).await
}
async fn put_json(&self, path: &str, body: Value) -> Result<Value> {
self.client.put(path, &body).await
}
async fn delete_json(&self, path: &str) -> Result<Value> {
self.client.delete(path).await?;
Ok(serde_json::json!(null)) }
async fn post_binary(&self, path: &str, body: Value) -> Result<Vec<u8>> {
self.client.post_binary(path, &body).await
}
}