Trait FromBody

Source
pub trait FromBody: Sized {
    type Context: RequestContext;
    type Result: IntoFuture<Item = Self, Error = BoxedError>;

    // Required method
    fn from_body(
        request: &Arc<Request<()>>,
        body: Body,
        context: &Self::Context,
    ) -> Self::Result;
}
Expand description

Asynchronous conversion from an HTTP request body.

Types implementing this trait are provided in the body module. They allow easy deserialization from a variety of data formats.

§Examples

Collect the whole body and then deserialize it using a serde data format crate serde_whatever:

struct CustomFormat<T>(T);

impl<T: serde::de::DeserializeOwned + Send + 'static> FromBody for CustomFormat<T> {
    type Context = NoContext;
    type Result = DefaultFuture<Self, BoxedError>;

    fn from_body(
        request: &Arc<http::Request<()>>,
        body: hyper::Body,
        context: &Self::Context,
    ) -> Self::Result {
        Box::new(body.concat2().map_err(Into::into).and_then(|body| {
            match serde_whatever::from_slice(&body) {
                Ok(t) => Ok(CustomFormat(t)),
                Err(e) => Err(e.into()),
            }
        }))
    }
}

Process the body stream on-the-fly and calculate a checksum by adding all the bytes:

struct BodyChecksum(u8);

impl FromBody for BodyChecksum {
    type Context = NoContext;
    type Result = DefaultFuture<Self, BoxedError>;

    fn from_body(
        request: &Arc<http::Request<()>>,
        body: hyper::Body,
        context: &Self::Context,
    ) -> Self::Result {
        Box::new(body
            .map_err(BoxedError::from)
            .fold(0, |checksum, chunk| -> Result<_, BoxedError> {
                Ok(chunk.as_ref().iter()
                    .fold(checksum, |checksum: u8, byte| {
                        checksum.wrapping_add(*byte)
                }))
            })
            .map(|checksum| BodyChecksum(checksum))  // wrap it up to create a `Self`
        )
    }
}

Required Associated Types§

Source

type Context: RequestContext

A context parameter passed to from_body.

This can be used to pass application-specific data like a logger or a database connection around.

If no context is needed, this should be set to NoContext.

Source

type Result: IntoFuture<Item = Self, Error = BoxedError>

The result returned by from_body.

Because impl Trait cannot be used inside traits (and named existential types aren’t stable), the type here might not be nameable. In that case, you can set it to DefaultFuture<Self, Error> and box the returned future.

If your FromBody implementation doesn’t need to return a future, you can set this to Result<Self, BoxedError> and immediately return the result of the conversion.

Required Methods§

Source

fn from_body( request: &Arc<Request<()>>, body: Body, context: &Self::Context, ) -> Self::Result

Create an instance of this type from an HTTP request body, asynchronously.

This will consume the body, so only one FromBody type can be used for every processed request.

Implementations of this function must not block, since this function is always run on a futures executor. If you need to perform blocking I/O or long-running computations, you can call tokio_threadpool::blocking.

Note: You probably want to limit the size of the body to prevent denial of service attacks.

§Parameters
  • request: An HTTP request (without body) from the http crate.
  • body: The body stream. Implements futures::Stream.
  • context: User-defined context.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<T: DeserializeOwned + Send + 'static> FromBody for HtmlForm<T>

Source§

type Context = NoContext

Source§

type Result = Box<dyn Future<Item = HtmlForm<T>, Error = Box<dyn Error + Send + Sync>> + Send>

Source§

impl<T: DeserializeOwned + Send + 'static> FromBody for Json<T>

Source§

type Context = NoContext

Source§

type Result = Box<dyn Future<Item = Json<T>, Error = Box<dyn Error + Send + Sync>> + Send>