use crate::{error::ServerFnError, request::Req};
use actix_web::{web::Payload, HttpRequest};
use bytes::Bytes;
use futures::Stream;
use send_wrapper::SendWrapper;
use std::{borrow::Cow, future::Future};
pub struct ActixRequest(pub(crate) SendWrapper<(HttpRequest, Payload)>);
impl ActixRequest {
pub fn take(self) -> (HttpRequest, Payload) {
self.0.take()
}
fn header(&self, name: &str) -> Option<Cow<'_, str>> {
self.0
.0
.headers()
.get(name)
.map(|h| String::from_utf8_lossy(h.as_bytes()))
}
}
impl From<(HttpRequest, Payload)> for ActixRequest {
fn from(value: (HttpRequest, Payload)) -> Self {
ActixRequest(SendWrapper::new(value))
}
}
impl<CustErr> Req<CustErr> for ActixRequest
where
CustErr: 'static,
{
fn as_query(&self) -> Option<&str> {
self.0 .0.uri().query()
}
fn to_content_type(&self) -> Option<Cow<'_, str>> {
self.header("Content-Type")
}
fn accepts(&self) -> Option<Cow<'_, str>> {
self.header("Accept")
}
fn referer(&self) -> Option<Cow<'_, str>> {
self.header("Referer")
}
fn try_into_bytes(
self,
) -> impl Future<Output = Result<Bytes, ServerFnError<CustErr>>> + Send
{
SendWrapper::new(async move {
let payload = self.0.take().1;
payload
.to_bytes()
.await
.map_err(|e| ServerFnError::Deserialization(e.to_string()))
})
}
fn try_into_string(
self,
) -> impl Future<Output = Result<String, ServerFnError<CustErr>>> + Send
{
SendWrapper::new(async move {
let payload = self.0.take().1;
let bytes = payload
.to_bytes()
.await
.map_err(|e| ServerFnError::Deserialization(e.to_string()))?;
String::from_utf8(bytes.into())
.map_err(|e| ServerFnError::Deserialization(e.to_string()))
})
}
fn try_into_stream(
self,
) -> Result<
impl Stream<Item = Result<Bytes, ServerFnError>> + Send,
ServerFnError<CustErr>,
> {
Ok(futures::stream::once(async { todo!() }))
}
}