Skip to main content

BodyLimit

Struct BodyLimit 

Source
pub struct BodyLimit<T, const LIMIT: usize>(pub T);
Expand description

Wraps a body extractor with a size limit expressed as a const generic.

BodyLimit<Json<Avatar>, { 1 << 20 }> is a one-megabyte JSON body. The limit is part of the handler’s signature, so it is visible at the call site and cannot drift away from the route it protects.

§Why this is worth trying

Churust’s RouteBuilder::max_body_bytes already attaches a limit to a route, and it is attached to the builder, so it cannot be registered against the wrong thing. The failure mode this avoids belongs to a different design: config resolved at runtime by type lookup, which silently falls back to a default when registered on the wrong scope. A limit that quietly is not applied is worse than no limit, and putting it in the type makes “not applied” unrepresentable.

What is still unsettled — and why this lives in the lab — is whether the ergonomics earn their place next to the builder method, which reads better and does not push a const generic through every signature.

§Interaction with the other limits

This only ever tightens. The server-wide max_body_bytes is enforced by the engine before any extractor runs, and a per-route limit applies underneath that. Whichever is smallest wins.

use churust_core::{Churust, TestClient};
use churust_lab::BodyLimit;
let app = Churust::server()
    .routing(|r| {
        r.post("/note", |BodyLimit(text): BodyLimit<String, 16>| async move {
            format!("{} bytes", text.len())
        });
    })
    .build();

let client = TestClient::new(app);
assert_eq!(client.post("/note").body("short").send().await.text(), "5 bytes");
assert_eq!(
    client.post("/note").body("far too long to fit in sixteen").send().await.status(),
    http::StatusCode::PAYLOAD_TOO_LARGE
);

Tuple Fields§

§0: T

The extracted value.

Trait Implementations§

Source§

impl<T: Clone, const LIMIT: usize> Clone for BodyLimit<T, LIMIT>

Source§

fn clone(&self) -> BodyLimit<T, LIMIT>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug, const LIMIT: usize> Debug for BodyLimit<T, LIMIT>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, const LIMIT: usize> FromCall for BodyLimit<T, LIMIT>
where T: FromCall,

Source§

fn from_call<'async_trait>( call: Call, ) -> Pin<Box<dyn Future<Output = Result<Self>> + Send + 'async_trait>>
where Self: 'async_trait,

Build Self by consuming the call, or return an Error (which the handler renders as the response).

Auto Trait Implementations§

§

impl<T, const LIMIT: usize> Freeze for BodyLimit<T, LIMIT>
where T: Freeze,

§

impl<T, const LIMIT: usize> RefUnwindSafe for BodyLimit<T, LIMIT>
where T: RefUnwindSafe,

§

impl<T, const LIMIT: usize> Send for BodyLimit<T, LIMIT>
where T: Send,

§

impl<T, const LIMIT: usize> Sync for BodyLimit<T, LIMIT>
where T: Sync,

§

impl<T, const LIMIT: usize> Unpin for BodyLimit<T, LIMIT>
where T: Unpin,

§

impl<T, const LIMIT: usize> UnsafeUnpin for BodyLimit<T, LIMIT>
where T: UnsafeUnpin,

§

impl<T, const LIMIT: usize> UnwindSafe for BodyLimit<T, LIMIT>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more