use http::Request;
#[async_trait::async_trait]
pub trait Bufferer<Body: http_body::Body> {
type Data: bytes::Buf;
type Error;
async fn buffer(&self, body: Body) -> Result<Self::Data, Self::Error>;
}
#[derive(Debug)]
pub enum Error<B, V> {
BodyBuffering(B),
Validation(V),
}
pub async fn validate<InBody, OutBody, Bufferer, Validator>(
bufferer: Bufferer,
validator: Validator,
req: Request<InBody>,
) -> Result<Request<OutBody>, Error<Bufferer::Error, Validator::Error>>
where
InBody: http_body::Body,
OutBody: http_body::Body,
Bufferer: self::Bufferer<InBody>,
OutBody: From<Bufferer::Data>,
Validator: http_request_validator::Validator<Bufferer::Data>,
{
let (parts, body) = req.into_parts();
let buffered_body = bufferer.buffer(body).await.map_err(Error::BodyBuffering)?;
validator
.validate(&parts, &buffered_body)
.await
.map_err(Error::Validation)?;
let req = Request::from_parts(parts, OutBody::from(buffered_body));
Ok(req)
}