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§
Sourcetype Context: RequestContext
type Context: RequestContext
Sourcetype Result: IntoFuture<Item = Self, Error = BoxedError>
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§
Sourcefn from_body(
request: &Arc<Request<()>>,
body: Body,
context: &Self::Context,
) -> Self::Result
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 thehttpcrate.body: The body stream. Implementsfutures::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.