//! Request extractors use actix_http::error::Error; use futures::future::ok; use futures::{future, Async, Future, IntoFuture, Poll}; use crate::service::ServiceFromRequest; mod form; mod json; mod path; mod payload; mod query; pub use self::form::{Form, FormConfig}; pub use self::json::{Json, JsonConfig}; pub use self::path::Path; pub use self::payload::{Payload, PayloadConfig}; pub use self::query::Query; /// Trait implemented by types that can be extracted from request. /// /// Types that implement this trait can be used with `Route` handlers. pub trait FromRequest
: Sized {
/// The associated error which can be returned.
type Error: Into ) -> Self::Future;
}
/// Optionally extract a field from the request
///
/// If the FromRequest for T fails, return None rather than returning an error response
///
/// ## Example
///
/// ```rust
/// # #[macro_use] extern crate serde_derive;
/// use actix_web::{web, App, Error, FromRequest, ServiceFromRequest};
/// use actix_web::error::ErrorBadRequest;
/// use rand;
///
/// #[derive(Debug, Deserialize)]
/// struct Thing {
/// name: String
/// }
///
/// impl FromRequest for Thing {
/// type Error = Error;
/// type Future = Result ) -> Self::Future {
/// if rand::random() {
/// Ok(Thing { name: "thingy".into() })
/// } else {
/// Err(ErrorBadRequest("no luck"))
/// }
///
/// }
/// }
///
/// /// extract `Thing` from request
/// fn index(supplied_thing: Option for Option ,
T::Future: 'static,
{
type Error = Error;
type Future = Box ) -> Self::Future {
Box::new(T::from_request(req).into_future().then(|r| match r {
Ok(v) => future::ok(Some(v)),
Err(e) => {
log::debug!("Error for Option FromRequest for Thing {
/// type Error = Error;
/// type Future = Result ) -> Self::Future {
/// if rand::random() {
/// Ok(Thing { name: "thingy".into() })
/// } else {
/// Err(ErrorBadRequest("no luck"))
/// }
/// }
/// }
///
/// /// extract `Thing` from request
/// fn index(supplied_thing: Result for Result ,
T::Future: 'static,
T::Error: 'static,
{
type Error = Error;
type Future = Box ) -> Self::Future {
Box::new(T::from_request(req).into_future().then(|res| match res {
Ok(v) => ok(Ok(v)),
Err(e) => ok(Err(e)),
}))
}
}
#[doc(hidden)]
impl FromRequest for () {
type Error = Error;
type Future = Result<(), Error>;
fn from_request(_req: &mut ServiceFromRequest ) -> Self::Future {
Ok(())
}
}
macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
/// FromRequest implementation for tuple
#[doc(hidden)]
impl + 'static),+> FromRequest for ($($T,)+)
{
type Error = Error;
type Future = $fut_type ;
fn from_request(req: &mut ServiceFromRequest ) -> Self::Future {
$fut_type {
items: <($(Option<$T>,)+)>::default(),
futs: ($($T::from_request(req).into_future(),)+),
}
}
}
#[doc(hidden)]
pub struct $fut_type ),+> {
items: ($(Option<$T>,)+),
futs: ($(<$T::Future as futures::IntoFuture>::Future,)+),
}
impl ),+> Future for $fut_type
{
type Item = ($($T,)+);
type Error = Error;
fn poll(&mut self) -> Poll