use crate::{HttpRequest, HttpResponse, HttpTransport, Method, StatusCode};
use anyhow::Result;
use async_trait::async_trait;
use rocket::local::asynchronous::Client;
use std::sync::Arc;
#[derive(Clone)]
pub struct RocketTransport {
client: Arc<Client>,
}
impl std::fmt::Debug for RocketTransport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RocketTransport")
.field("client", &"<rocket::Client>")
.finish()
}
}
impl RocketTransport {
pub async fn new(rocket: rocket::Rocket<rocket::Build>) -> Result<Self> {
let client = Client::tracked(rocket)
.await
.map_err(|e| anyhow::anyhow!("Failed to create Rocket client: {}", e))?;
Ok(Self {
client: Arc::new(client),
})
}
}
#[async_trait]
impl HttpTransport for RocketTransport {
async fn send(&self, req: HttpRequest) -> Result<HttpResponse> {
let request = match req.method {
Method::Get => self.client.get(&req.url),
Method::Post => {
let mut post_req = self.client.post(&req.url);
for (key, value) in &req.headers {
post_req = post_req.header(rocket::http::Header::new(
key.to_string(),
value.to_string(),
));
}
if let Some(body) = req.body {
post_req = post_req.body(body);
}
post_req
}
};
let response = request.dispatch().await;
let status = StatusCode(response.status().code);
let headers = response
.headers()
.iter()
.map(|h| (h.name.to_string(), h.value.to_string()))
.collect();
let body = response.into_string().await.unwrap_or_else(String::new);
Ok(HttpResponse {
status,
headers,
body,
})
}
}