1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

use FromRequest instead of HttpRequestExtractor

This commit is contained in:
Nikolay Kim 2018-03-29 13:12:28 -07:00
parent dfd8f1058e
commit 86dd732704
8 changed files with 93 additions and 93 deletions

View File

@ -2,29 +2,12 @@ use std::ops::{Deref, DerefMut};
use serde_urlencoded; use serde_urlencoded;
use serde::de::{self, Deserializer, DeserializeOwned, Visitor, Error as DeError}; use serde::de::{self, Deserializer, DeserializeOwned, Visitor, Error as DeError};
use futures::future::{Future, FutureResult, result}; use futures::future::{FutureResult, result};
use error::Error; use error::Error;
use handler::FromRequest;
use httprequest::HttpRequest; use httprequest::HttpRequest;
pub trait HttpRequestExtractor<S>: Sized where S: 'static
{
type Result: Future<Item=Self, Error=Error>;
fn extract(req: &HttpRequest<S>) -> Self::Result;
}
impl<S: 'static> HttpRequestExtractor<S> for HttpRequest<S>
{
type Result = FutureResult<Self, Error>;
#[inline]
fn extract(req: &HttpRequest<S>) -> Self::Result {
result(Ok(req.clone()))
}
}
/// Extract typed information from the request's path. /// Extract typed information from the request's path.
/// ///
/// `S` - application state type /// `S` - application state type
@ -98,15 +81,15 @@ impl<T, S> Path<T, S> {
} }
impl<T, S> HttpRequestExtractor<S> for Path<T, S> impl<T, S> FromRequest<S> for Path<T, S>
where T: DeserializeOwned, S: 'static where T: DeserializeOwned, S: 'static
{ {
type Result = FutureResult<Self, Error>; type Result = FutureResult<Self, Error>;
#[inline] #[inline]
fn extract(req: &HttpRequest<S>) -> Self::Result { fn from_request(req: &HttpRequest<S>) -> Self::Result {
let req = req.clone(); let req = req.clone();
result(de::Deserialize::deserialize(PathExtractor{req: &req}) result(de::Deserialize::deserialize(PathDeserializer{req: &req})
.map_err(|e| e.into()) .map_err(|e| e.into())
.map(|item| Path{item, req})) .map(|item| Path{item, req}))
} }
@ -185,13 +168,13 @@ impl<T, S> Query<T, S> {
} }
} }
impl<T, S> HttpRequestExtractor<S> for Query<T, S> impl<T, S> FromRequest<S> for Query<T, S>
where T: de::DeserializeOwned, S: 'static where T: de::DeserializeOwned, S: 'static
{ {
type Result = FutureResult<Self, Error>; type Result = FutureResult<Self, Error>;
#[inline] #[inline]
fn extract(req: &HttpRequest<S>) -> Self::Result { fn from_request(req: &HttpRequest<S>) -> Self::Result {
let req = req.clone(); let req = req.clone();
result(serde_urlencoded::from_str::<T>(req.query_string()) result(serde_urlencoded::from_str::<T>(req.query_string())
.map_err(|e| e.into()) .map_err(|e| e.into())
@ -209,11 +192,11 @@ macro_rules! unsupported_type {
}; };
} }
pub struct PathExtractor<'de, S: 'de> { pub struct PathDeserializer<'de, S: 'de> {
req: &'de HttpRequest<S> req: &'de HttpRequest<S>
} }
impl<'de, S: 'de> Deserializer<'de> for PathExtractor<'de, S> impl<'de, S: 'de> Deserializer<'de> for PathDeserializer<'de, S>
{ {
type Error = de::value::Error; type Error = de::value::Error;
@ -305,7 +288,7 @@ impl<'de, S: 'de> Deserializer<'de> for PathExtractor<'de, S>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use futures::Async; use futures::{Async, Future};
use super::*; use super::*;
use router::{Router, Pattern}; use router::{Router, Pattern};
use resource::Resource; use resource::Resource;
@ -334,7 +317,7 @@ mod tests {
let (router, _) = Router::new("", ServerSettings::default(), routes); let (router, _) = Router::new("", ServerSettings::default(), routes);
assert!(router.recognize(&mut req).is_some()); assert!(router.recognize(&mut req).is_some());
match Path::<MyStruct, _>::extract(&req).poll().unwrap() { match Path::<MyStruct, _>::from_request(&req).poll().unwrap() {
Async::Ready(s) => { Async::Ready(s) => {
assert_eq!(s.key, "name"); assert_eq!(s.key, "name");
assert_eq!(s.value, "user1"); assert_eq!(s.value, "user1");
@ -342,7 +325,7 @@ mod tests {
_ => unreachable!(), _ => unreachable!(),
} }
match Path::<(String, String), _>::extract(&req).poll().unwrap() { match Path::<(String, String), _>::from_request(&req).poll().unwrap() {
Async::Ready(s) => { Async::Ready(s) => {
assert_eq!(s.0, "name"); assert_eq!(s.0, "name");
assert_eq!(s.1, "user1"); assert_eq!(s.1, "user1");
@ -350,7 +333,7 @@ mod tests {
_ => unreachable!(), _ => unreachable!(),
} }
match Query::<Id, _>::extract(&req).poll().unwrap() { match Query::<Id, _>::from_request(&req).poll().unwrap() {
Async::Ready(s) => { Async::Ready(s) => {
assert_eq!(s.id, "test"); assert_eq!(s.id, "test");
}, },

View File

@ -30,6 +30,16 @@ pub trait Responder {
fn respond_to(self, req: HttpRequest) -> Result<Self::Item, Self::Error>; fn respond_to(self, req: HttpRequest) -> Result<Self::Item, Self::Error>;
} }
/// Trait implemented by types that can be extracted from request.
///
/// Types that implement this trait can be used with `Route::with()` method.
pub trait FromRequest<S>: Sized where S: 'static
{
type Result: Future<Item=Self, Error=Error>;
fn from_request(req: &HttpRequest<S>) -> Self::Result;
}
/// Combines two different responder types into a single type /// Combines two different responder types into a single type
/// ///
/// ```rust /// ```rust

View File

@ -6,6 +6,7 @@ use std::borrow::Cow;
use bytes::Bytes; use bytes::Bytes;
use cookie::Cookie; use cookie::Cookie;
use futures::{Async, Stream, Poll}; use futures::{Async, Stream, Poll};
use futures::future::{FutureResult, result};
use futures_cpupool::CpuPool; use futures_cpupool::CpuPool;
use failure; use failure;
use url::{Url, form_urlencoded}; use url::{Url, form_urlencoded};
@ -18,10 +19,11 @@ use info::ConnectionInfo;
use param::Params; use param::Params;
use router::Router; use router::Router;
use payload::Payload; use payload::Payload;
use handler::FromRequest;
use httpmessage::HttpMessage; use httpmessage::HttpMessage;
use httpresponse::{HttpResponse, HttpResponseBuilder}; use httpresponse::{HttpResponse, HttpResponseBuilder};
use server::helpers::SharedHttpInnerMessage; use server::helpers::SharedHttpInnerMessage;
use error::{UrlGenerationError, CookieParseError, PayloadError}; use error::{Error, UrlGenerationError, CookieParseError, PayloadError};
pub struct HttpInnerMessage { pub struct HttpInnerMessage {
@ -461,6 +463,16 @@ impl<S> Clone for HttpRequest<S> {
} }
} }
impl<S: 'static> FromRequest<S> for HttpRequest<S>
{
type Result = FutureResult<Self, Error>;
#[inline]
fn from_request(req: &HttpRequest<S>) -> Self::Result {
result(Ok(req.clone()))
}
}
impl<S> Stream for HttpRequest<S> { impl<S> Stream for HttpRequest<S> {
type Item = Bytes; type Item = Bytes;
type Error = PayloadError; type Error = PayloadError;

View File

@ -10,11 +10,10 @@ use serde::Serialize;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use error::{Error, JsonPayloadError, PayloadError}; use error::{Error, JsonPayloadError, PayloadError};
use handler::Responder; use handler::{Responder, FromRequest};
use httpmessage::HttpMessage; use httpmessage::HttpMessage;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use extractor::HttpRequestExtractor;
/// Json helper /// Json helper
/// ///
@ -112,13 +111,13 @@ impl<T: Serialize> Responder for Json<T> {
} }
} }
impl<T, S> HttpRequestExtractor<S> for Json<T> impl<T, S> FromRequest<S> for Json<T>
where T: DeserializeOwned + 'static, S: 'static where T: DeserializeOwned + 'static, S: 'static
{ {
type Result = Box<Future<Item=Self, Error=Error>>; type Result = Box<Future<Item=Self, Error=Error>>;
#[inline] #[inline]
fn extract(req: &HttpRequest<S>) -> Self::Result { fn from_request(req: &HttpRequest<S>) -> Self::Result {
Box::new( Box::new(
JsonBody::new(req.clone()) JsonBody::new(req.clone())
.from_err() .from_err()

View File

@ -106,6 +106,7 @@ extern crate tokio_openssl;
mod application; mod application;
mod body; mod body;
mod context; mod context;
mod de;
mod handler; mod handler;
mod httpmessage; mod httpmessage;
mod httprequest; mod httprequest;
@ -119,7 +120,6 @@ mod param;
mod payload; mod payload;
mod pipeline; mod pipeline;
mod with; mod with;
mod extractor;
pub mod client; pub mod client;
pub mod fs; pub mod fs;
@ -136,6 +136,7 @@ pub mod server;
pub use error::{Error, Result, ResponseError}; pub use error::{Error, Result, ResponseError};
pub use body::{Body, Binary}; pub use body::{Body, Binary};
pub use json::Json; pub use json::Json;
pub use de::{Path, Query};
pub use application::Application; pub use application::Application;
pub use httpmessage::HttpMessage; pub use httpmessage::HttpMessage;
pub use httprequest::HttpRequest; pub use httprequest::HttpRequest;
@ -143,7 +144,6 @@ pub use httpresponse::HttpResponse;
pub use handler::{Either, Responder, AsyncResponder, FutureResponse}; pub use handler::{Either, Responder, AsyncResponder, FutureResponse};
pub use context::HttpContext; pub use context::HttpContext;
pub use server::HttpServer; pub use server::HttpServer;
pub use extractor::{Path, Query};
// re-exports // re-exports
pub use http::{Method, StatusCode}; pub use http::{Method, StatusCode};
@ -172,14 +172,13 @@ pub mod dev {
pub use body::BodyStream; pub use body::BodyStream;
pub use context::Drain; pub use context::Drain;
pub use info::ConnectionInfo; pub use info::ConnectionInfo;
pub use handler::{Handler, Reply}; pub use handler::{Handler, Reply, FromRequest};
pub use route::Route; pub use route::Route;
pub use resource::Resource; pub use resource::Resource;
pub use with::WithHandler; pub use with::WithHandler;
pub use json::JsonBody; pub use json::JsonBody;
pub use router::{Router, Pattern}; pub use router::{Router, Pattern};
pub use param::{FromParam, Params}; pub use param::{FromParam, Params};
pub use extractor::HttpRequestExtractor;
pub use httpmessage::{UrlEncoded, MessageBody}; pub use httpmessage::{UrlEncoded, MessageBody};
pub use httpresponse::HttpResponseBuilder; pub use httpresponse::HttpResponseBuilder;
} }

View File

@ -7,12 +7,11 @@ use http::{Method, StatusCode};
use pred; use pred;
use body::Body; use body::Body;
use route::Route; use route::Route;
use handler::{Reply, Handler, Responder}; use handler::{Reply, Handler, Responder, FromRequest};
use middleware::Middleware; use middleware::Middleware;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use with::WithHandler; use with::WithHandler;
use extractor::HttpRequestExtractor;
/// *Resource* is an entry in route table which corresponds to requested URL. /// *Resource* is an entry in route table which corresponds to requested URL.
/// ///
@ -143,7 +142,7 @@ impl<S: 'static> Resource<S> {
/// ``` /// ```
pub fn with<T, H>(&mut self, handler: H) pub fn with<T, H>(&mut self, handler: H)
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S> + 'static, T: FromRequest<S> + 'static,
{ {
self.routes.push(Route::default()); self.routes.push(Route::default());
self.routes.last_mut().unwrap().with(handler) self.routes.last_mut().unwrap().with(handler)

View File

@ -5,14 +5,13 @@ use futures::{Async, Future, Poll};
use error::Error; use error::Error;
use pred::Predicate; use pred::Predicate;
use handler::{Reply, ReplyItem, Handler, use handler::{Reply, ReplyItem, Handler, FromRequest,
Responder, RouteHandler, AsyncHandler, WrapHandler}; Responder, RouteHandler, AsyncHandler, WrapHandler};
use middleware::{Middleware, Response as MiddlewareResponse, Started as MiddlewareStarted}; use middleware::{Middleware, Response as MiddlewareResponse, Started as MiddlewareStarted};
use httpcodes::HttpNotFound; use httpcodes::HttpNotFound;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use with::{with, with2, with3, WithHandler}; use with::{with, with2, with3, WithHandler};
use extractor::HttpRequestExtractor;
/// Resource route definition /// Resource route definition
/// ///
@ -132,7 +131,7 @@ impl<S: 'static> Route<S> {
/// ``` /// ```
pub fn with<T, H>(&mut self, handler: H) pub fn with<T, H>(&mut self, handler: H)
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S> + 'static, T: FromRequest<S> + 'static,
{ {
self.h(with(handler)) self.h(with(handler))
} }
@ -171,8 +170,8 @@ impl<S: 'static> Route<S> {
pub fn with2<T1, T2, F, R>(&mut self, handler: F) pub fn with2<T1, T2, F, R>(&mut self, handler: F)
where F: Fn(T1, T2) -> R + 'static, where F: Fn(T1, T2) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
{ {
self.h(with2(handler)) self.h(with2(handler))
} }
@ -181,9 +180,9 @@ impl<S: 'static> Route<S> {
pub fn with3<T1, T2, T3, F, R>(&mut self, handler: F) pub fn with3<T1, T2, T3, F, R>(&mut self, handler: F)
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
T3: HttpRequestExtractor<S> + 'static, T3: FromRequest<S> + 'static,
{ {
self.h(with3(handler)) self.h(with3(handler))
} }

View File

@ -4,16 +4,15 @@ use std::marker::PhantomData;
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use error::Error; use error::Error;
use handler::{Handler, Reply, ReplyItem, Responder}; use handler::{Handler, FromRequest, Reply, ReplyItem, Responder};
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use extractor::HttpRequestExtractor;
/// Trait defines object that could be registered as route handler /// Trait defines object that could be registered as route handler
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait WithHandler<T, S>: 'static pub trait WithHandler<T, S>: 'static
where T: HttpRequestExtractor<S>, S: 'static where T: FromRequest<S>, S: 'static
{ {
/// The type of value that handler will return. /// The type of value that handler will return.
type Result: Responder; type Result: Responder;
@ -26,7 +25,7 @@ pub trait WithHandler<T, S>: 'static
impl<T, S, F, R> WithHandler<T, S> for F impl<T, S, F, R> WithHandler<T, S> for F
where F: Fn(T) -> R + 'static, where F: Fn(T) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T: HttpRequestExtractor<S>, T: FromRequest<S>,
S: 'static, S: 'static,
{ {
type Result = R; type Result = R;
@ -39,14 +38,14 @@ impl<T, S, F, R> WithHandler<T, S> for F
pub(crate) pub(crate)
fn with<T, S, H>(h: H) -> With<T, S, H> fn with<T, S, H>(h: H) -> With<T, S, H>
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S>, T: FromRequest<S>,
{ {
With{hnd: Rc::new(UnsafeCell::new(h)), _t: PhantomData, _s: PhantomData} With{hnd: Rc::new(UnsafeCell::new(h)), _t: PhantomData, _s: PhantomData}
} }
pub struct With<T, S, H> pub struct With<T, S, H>
where H: WithHandler<T, S> + 'static, where H: WithHandler<T, S> + 'static,
T: HttpRequestExtractor<S>, T: FromRequest<S>,
S: 'static, S: 'static,
{ {
hnd: Rc<UnsafeCell<H>>, hnd: Rc<UnsafeCell<H>>,
@ -56,7 +55,7 @@ pub struct With<T, S, H>
impl<T, S, H> Handler<S> for With<T, S, H> impl<T, S, H> Handler<S> for With<T, S, H>
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S> + 'static, T: FromRequest<S> + 'static,
S: 'static, H: 'static S: 'static, H: 'static
{ {
type Result = Reply; type Result = Reply;
@ -80,7 +79,7 @@ impl<T, S, H> Handler<S> for With<T, S, H>
struct WithHandlerFut<T, S, H> struct WithHandlerFut<T, S, H>
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S>, T: FromRequest<S>,
T: 'static, S: 'static T: 'static, S: 'static
{ {
started: bool, started: bool,
@ -92,7 +91,7 @@ struct WithHandlerFut<T, S, H>
impl<T, S, H> Future for WithHandlerFut<T, S, H> impl<T, S, H> Future for WithHandlerFut<T, S, H>
where H: WithHandler<T, S>, where H: WithHandler<T, S>,
T: HttpRequestExtractor<S> + 'static, T: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
type Item = HttpResponse; type Item = HttpResponse;
@ -105,7 +104,7 @@ impl<T, S, H> Future for WithHandlerFut<T, S, H>
let item = if !self.started { let item = if !self.started {
self.started = true; self.started = true;
let mut fut = T::extract(&self.req); let mut fut = T::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item)) => item, Ok(Async::Ready(item)) => item,
Ok(Async::NotReady) => { Ok(Async::NotReady) => {
@ -140,8 +139,8 @@ pub(crate)
fn with2<T1, T2, S, F, R>(h: F) -> With2<T1, T2, S, F, R> fn with2<T1, T2, S, F, R>(h: F) -> With2<T1, T2, S, F, R>
where F: Fn(T1, T2) -> R, where F: Fn(T1, T2) -> R,
R: Responder, R: Responder,
T1: HttpRequestExtractor<S>, T1: FromRequest<S>,
T2: HttpRequestExtractor<S>, T2: FromRequest<S>,
{ {
With2{hnd: Rc::new(UnsafeCell::new(h)), With2{hnd: Rc::new(UnsafeCell::new(h)),
_t1: PhantomData, _t2: PhantomData, _s: PhantomData} _t1: PhantomData, _t2: PhantomData, _s: PhantomData}
@ -150,8 +149,8 @@ fn with2<T1, T2, S, F, R>(h: F) -> With2<T1, T2, S, F, R>
pub struct With2<T1, T2, S, F, R> pub struct With2<T1, T2, S, F, R>
where F: Fn(T1, T2) -> R, where F: Fn(T1, T2) -> R,
R: Responder, R: Responder,
T1: HttpRequestExtractor<S>, T1: FromRequest<S>,
T2: HttpRequestExtractor<S>, T2: FromRequest<S>,
S: 'static, S: 'static,
{ {
hnd: Rc<UnsafeCell<F>>, hnd: Rc<UnsafeCell<F>>,
@ -163,8 +162,8 @@ pub struct With2<T1, T2, S, F, R>
impl<T1, T2, S, F, R> Handler<S> for With2<T1, T2, S, F, R> impl<T1, T2, S, F, R> Handler<S> for With2<T1, T2, S, F, R>
where F: Fn(T1, T2) -> R + 'static, where F: Fn(T1, T2) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
type Result = Reply; type Result = Reply;
@ -190,8 +189,8 @@ impl<T1, T2, S, F, R> Handler<S> for With2<T1, T2, S, F, R>
struct WithHandlerFut2<T1, T2, S, F, R> struct WithHandlerFut2<T1, T2, S, F, R>
where F: Fn(T1, T2) -> R + 'static, where F: Fn(T1, T2) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
started: bool, started: bool,
@ -206,8 +205,8 @@ struct WithHandlerFut2<T1, T2, S, F, R>
impl<T1, T2, S, F, R> Future for WithHandlerFut2<T1, T2, S, F, R> impl<T1, T2, S, F, R> Future for WithHandlerFut2<T1, T2, S, F, R>
where F: Fn(T1, T2) -> R + 'static, where F: Fn(T1, T2) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
type Item = HttpResponse; type Item = HttpResponse;
@ -220,10 +219,10 @@ impl<T1, T2, S, F, R> Future for WithHandlerFut2<T1, T2, S, F, R>
if !self.started { if !self.started {
self.started = true; self.started = true;
let mut fut = T1::extract(&self.req); let mut fut = T1::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item1)) => { Ok(Async::Ready(item1)) => {
let mut fut = T2::extract(&self.req); let mut fut = T2::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item2)) => { Ok(Async::Ready(item2)) => {
let hnd: &mut F = unsafe{&mut *self.hnd.get()}; let hnd: &mut F = unsafe{&mut *self.hnd.get()};
@ -262,7 +261,7 @@ impl<T1, T2, S, F, R> Future for WithHandlerFut2<T1, T2, S, F, R>
Async::Ready(item) => { Async::Ready(item) => {
self.item = Some(item); self.item = Some(item);
self.fut1.take(); self.fut1.take();
self.fut2 = Some(Box::new(T2::extract(&self.req))); self.fut2 = Some(Box::new(T2::from_request(&self.req)));
}, },
Async::NotReady => return Ok(Async::NotReady), Async::NotReady => return Ok(Async::NotReady),
} }
@ -294,9 +293,9 @@ pub(crate)
fn with3<T1, T2, T3, S, F, R>(h: F) -> With3<T1, T2, T3, S, F, R> fn with3<T1, T2, T3, S, F, R>(h: F) -> With3<T1, T2, T3, S, F, R>
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder, R: Responder,
T1: HttpRequestExtractor<S>, T1: FromRequest<S>,
T2: HttpRequestExtractor<S>, T2: FromRequest<S>,
T3: HttpRequestExtractor<S>, T3: FromRequest<S>,
{ {
With3{hnd: Rc::new(UnsafeCell::new(h)), With3{hnd: Rc::new(UnsafeCell::new(h)),
_s: PhantomData, _t1: PhantomData, _t2: PhantomData, _t3: PhantomData} _s: PhantomData, _t1: PhantomData, _t2: PhantomData, _t3: PhantomData}
@ -305,9 +304,9 @@ fn with3<T1, T2, T3, S, F, R>(h: F) -> With3<T1, T2, T3, S, F, R>
pub struct With3<T1, T2, T3, S, F, R> pub struct With3<T1, T2, T3, S, F, R>
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S>, T1: FromRequest<S>,
T2: HttpRequestExtractor<S>, T2: FromRequest<S>,
T3: HttpRequestExtractor<S>, T3: FromRequest<S>,
S: 'static, S: 'static,
{ {
hnd: Rc<UnsafeCell<F>>, hnd: Rc<UnsafeCell<F>>,
@ -320,9 +319,9 @@ pub struct With3<T1, T2, T3, S, F, R>
impl<T1, T2, T3, S, F, R> Handler<S> for With3<T1, T2, T3, S, F, R> impl<T1, T2, T3, S, F, R> Handler<S> for With3<T1, T2, T3, S, F, R>
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S>, T1: FromRequest<S>,
T2: HttpRequestExtractor<S>, T2: FromRequest<S>,
T3: HttpRequestExtractor<S>, T3: FromRequest<S>,
T1: 'static, T2: 'static, T3: 'static, S: 'static T1: 'static, T2: 'static, T3: 'static, S: 'static
{ {
type Result = Reply; type Result = Reply;
@ -350,9 +349,9 @@ impl<T1, T2, T3, S, F, R> Handler<S> for With3<T1, T2, T3, S, F, R>
struct WithHandlerFut3<T1, T2, T3, S, F, R> struct WithHandlerFut3<T1, T2, T3, S, F, R>
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
T3: HttpRequestExtractor<S> + 'static, T3: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
hnd: Rc<UnsafeCell<F>>, hnd: Rc<UnsafeCell<F>>,
@ -369,9 +368,9 @@ struct WithHandlerFut3<T1, T2, T3, S, F, R>
impl<T1, T2, T3, S, F, R> Future for WithHandlerFut3<T1, T2, T3, S, F, R> impl<T1, T2, T3, S, F, R> Future for WithHandlerFut3<T1, T2, T3, S, F, R>
where F: Fn(T1, T2, T3) -> R + 'static, where F: Fn(T1, T2, T3) -> R + 'static,
R: Responder + 'static, R: Responder + 'static,
T1: HttpRequestExtractor<S> + 'static, T1: FromRequest<S> + 'static,
T2: HttpRequestExtractor<S> + 'static, T2: FromRequest<S> + 'static,
T3: HttpRequestExtractor<S> + 'static, T3: FromRequest<S> + 'static,
S: 'static S: 'static
{ {
type Item = HttpResponse; type Item = HttpResponse;
@ -384,13 +383,13 @@ impl<T1, T2, T3, S, F, R> Future for WithHandlerFut3<T1, T2, T3, S, F, R>
if !self.started { if !self.started {
self.started = true; self.started = true;
let mut fut = T1::extract(&self.req); let mut fut = T1::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item1)) => { Ok(Async::Ready(item1)) => {
let mut fut = T2::extract(&self.req); let mut fut = T2::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item2)) => { Ok(Async::Ready(item2)) => {
let mut fut = T3::extract(&self.req); let mut fut = T3::from_request(&self.req);
match fut.poll() { match fut.poll() {
Ok(Async::Ready(item3)) => { Ok(Async::Ready(item3)) => {
let hnd: &mut F = unsafe{&mut *self.hnd.get()}; let hnd: &mut F = unsafe{&mut *self.hnd.get()};
@ -438,7 +437,7 @@ impl<T1, T2, T3, S, F, R> Future for WithHandlerFut3<T1, T2, T3, S, F, R>
Async::Ready(item) => { Async::Ready(item) => {
self.item1 = Some(item); self.item1 = Some(item);
self.fut1.take(); self.fut1.take();
self.fut2 = Some(Box::new(T2::extract(&self.req))); self.fut2 = Some(Box::new(T2::from_request(&self.req)));
}, },
Async::NotReady => return Ok(Async::NotReady), Async::NotReady => return Ok(Async::NotReady),
} }
@ -449,7 +448,7 @@ impl<T1, T2, T3, S, F, R> Future for WithHandlerFut3<T1, T2, T3, S, F, R>
Async::Ready(item) => { Async::Ready(item) => {
self.item2 = Some(item); self.item2 = Some(item);
self.fut2.take(); self.fut2.take();
self.fut3 = Some(Box::new(T3::extract(&self.req))); self.fut3 = Some(Box::new(T3::from_request(&self.req)));
}, },
Async::NotReady => return Ok(Async::NotReady), Async::NotReady => return Ok(Async::NotReady),
} }