use crate::BodyLimit;
use rama_core::{Layer, Service, extensions::ExtensionsRef, io::Io};
use rama_utils::macros::define_inner_service_accessors;
use std::fmt;
#[derive(Debug, Clone)]
pub struct BodyLimitLayer {
limit: BodyLimit,
}
impl BodyLimitLayer {
#[must_use]
pub fn request_only(limit: usize) -> Self {
Self {
limit: BodyLimit::request_only(limit),
}
}
#[must_use]
pub fn response_only(limit: usize) -> Self {
Self {
limit: BodyLimit::response_only(limit),
}
}
#[must_use]
pub fn symmetric(limit: usize) -> Self {
Self {
limit: BodyLimit::symmetric(limit),
}
}
#[must_use]
pub fn asymmetric(request: usize, response: usize) -> Self {
Self {
limit: BodyLimit::asymmetric(request, response),
}
}
}
impl<S> Layer<S> for BodyLimitLayer {
type Service = BodyLimitService<S>;
fn layer(&self, inner: S) -> Self::Service {
BodyLimitService::new(inner, self.limit)
}
}
#[derive(Clone)]
pub struct BodyLimitService<S> {
inner: S,
limit: BodyLimit,
}
impl<S> BodyLimitService<S> {
pub const fn new(service: S, limit: BodyLimit) -> Self {
Self {
inner: service,
limit,
}
}
define_inner_service_accessors!();
pub fn request_only(service: S, limit: usize) -> Self {
BodyLimitLayer::request_only(limit).into_layer(service)
}
pub fn response_only(service: S, limit: usize) -> Self {
BodyLimitLayer::response_only(limit).into_layer(service)
}
pub fn symmetric(service: S, limit: usize) -> Self {
BodyLimitLayer::symmetric(limit).into_layer(service)
}
pub fn asymmetric(service: S, request: usize, response: usize) -> Self {
BodyLimitLayer::asymmetric(request, response).into_layer(service)
}
}
impl<S, IO> Service<IO> for BodyLimitService<S>
where
S: Service<IO>,
IO: Io + ExtensionsRef,
{
type Output = S::Output;
type Error = S::Error;
async fn serve(&self, stream: IO) -> Result<Self::Output, Self::Error> {
stream.extensions().insert(self.limit);
self.inner.serve(stream).await
}
}
impl<S> fmt::Debug for BodyLimitService<S>
where
S: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("BodyLimitService")
.field("inner", &self.inner)
.field("limit", &self.limit)
.finish()
}
}