mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-28 01:32:57 +01:00
allow to use fn with multiple arguments with .with()/.with_async()
This commit is contained in:
parent
248bd388ca
commit
eb1e9a785f
@ -1,6 +1,6 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## [0.7.4] - 2018-08-xx
|
## [0.8.0] - 2018-08-xx
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
* It is allowed to use function with up to 10 parameters for handler with `extractor parameters`.
|
||||||
|
|
||||||
* native-tls - 0.2
|
* native-tls - 0.2
|
||||||
|
|
||||||
* `Content-Disposition` is re-worked. Its parser is now more robust and handles quoted content better. See #461
|
* `Content-Disposition` is re-worked. Its parser is now more robust and handles quoted content better. See #461
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
## 0.8
|
||||||
|
|
||||||
|
* `Route::with_config()`/`Route::with_async_config()` always passes configuration objects as tuple
|
||||||
|
even for handler with one parameter.
|
||||||
|
|
||||||
|
|
||||||
## 0.7
|
## 0.7
|
||||||
|
|
||||||
* `HttpRequest` does not implement `Stream` anymore. If you need to read request payload
|
* `HttpRequest` does not implement `Stream` anymore. If you need to read request payload
|
||||||
|
@ -12,6 +12,7 @@ use resource::Resource;
|
|||||||
use router::{ResourceDef, Router};
|
use router::{ResourceDef, Router};
|
||||||
use scope::Scope;
|
use scope::Scope;
|
||||||
use server::{HttpHandler, HttpHandlerTask, IntoHttpHandler, Request};
|
use server::{HttpHandler, HttpHandlerTask, IntoHttpHandler, Request};
|
||||||
|
use with::WithFactory;
|
||||||
|
|
||||||
/// Application
|
/// Application
|
||||||
pub struct HttpApplication<S = ()> {
|
pub struct HttpApplication<S = ()> {
|
||||||
@ -249,7 +250,7 @@ where
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> App<S>
|
pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> App<S>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R>,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -332,7 +332,7 @@ impl<T: fmt::Display> fmt::Display for Form<T> {
|
|||||||
/// |r| {
|
/// |r| {
|
||||||
/// r.method(http::Method::GET)
|
/// r.method(http::Method::GET)
|
||||||
/// // register form handler and change form extractor configuration
|
/// // register form handler and change form extractor configuration
|
||||||
/// .with_config(index, |cfg| {cfg.limit(4096);})
|
/// .with_config(index, |cfg| {cfg.0.limit(4096);})
|
||||||
/// },
|
/// },
|
||||||
/// );
|
/// );
|
||||||
/// }
|
/// }
|
||||||
@ -427,7 +427,7 @@ impl<S: 'static> FromRequest<S> for Bytes {
|
|||||||
/// let app = App::new().resource("/index.html", |r| {
|
/// let app = App::new().resource("/index.html", |r| {
|
||||||
/// r.method(http::Method::GET)
|
/// r.method(http::Method::GET)
|
||||||
/// .with_config(index, |cfg| { // <- register handler with extractor params
|
/// .with_config(index, |cfg| { // <- register handler with extractor params
|
||||||
/// cfg.limit(4096); // <- limit size of the payload
|
/// cfg.0.limit(4096); // <- limit size of the payload
|
||||||
/// })
|
/// })
|
||||||
/// });
|
/// });
|
||||||
/// }
|
/// }
|
||||||
|
@ -172,7 +172,7 @@ where
|
|||||||
/// let app = App::new().resource("/index.html", |r| {
|
/// let app = App::new().resource("/index.html", |r| {
|
||||||
/// r.method(http::Method::POST)
|
/// r.method(http::Method::POST)
|
||||||
/// .with_config(index, |cfg| {
|
/// .with_config(index, |cfg| {
|
||||||
/// cfg.limit(4096) // <- change json extractor configuration
|
/// cfg.0.limit(4096) // <- change json extractor configuration
|
||||||
/// .error_handler(|err, req| { // <- create custom error response
|
/// .error_handler(|err, req| { // <- create custom error response
|
||||||
/// error::InternalError::from_response(
|
/// error::InternalError::from_response(
|
||||||
/// err, HttpResponse::Conflict().finish()).into()
|
/// err, HttpResponse::Conflict().finish()).into()
|
||||||
|
@ -13,6 +13,7 @@ use middleware::Middleware;
|
|||||||
use pred;
|
use pred;
|
||||||
use route::Route;
|
use route::Route;
|
||||||
use router::ResourceDef;
|
use router::ResourceDef;
|
||||||
|
use with::WithFactory;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub(crate) struct RouteId(usize);
|
pub(crate) struct RouteId(usize);
|
||||||
@ -217,7 +218,7 @@ impl<S: 'static> Resource<S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn with<T, F, R>(&mut self, handler: F)
|
pub fn with<T, F, R>(&mut self, handler: F)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R>,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
|
27
src/route.rs
27
src/route.rs
@ -16,7 +16,7 @@ use middleware::{
|
|||||||
Started as MiddlewareStarted,
|
Started as MiddlewareStarted,
|
||||||
};
|
};
|
||||||
use pred::Predicate;
|
use pred::Predicate;
|
||||||
use with::{With, WithAsync};
|
use with::{WithAsyncFactory, WithFactory};
|
||||||
|
|
||||||
/// Resource route definition
|
/// Resource route definition
|
||||||
///
|
///
|
||||||
@ -166,15 +166,15 @@ impl<S: 'static> Route<S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn with<T, F, R>(&mut self, handler: F)
|
pub fn with<T, F, R>(&mut self, handler: F)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R> + 'static,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
self.h(With::new(handler, <T::Config as Default>::default()));
|
self.h(handler.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set handler function. Same as `.with()` but it allows to configure
|
/// Set handler function. Same as `.with()` but it allows to configure
|
||||||
/// extractor.
|
/// extractor. Configuration closure accepts config objects as tuple.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # extern crate bytes;
|
/// # extern crate bytes;
|
||||||
@ -192,21 +192,21 @@ impl<S: 'static> Route<S> {
|
|||||||
/// let app = App::new().resource("/index.html", |r| {
|
/// let app = App::new().resource("/index.html", |r| {
|
||||||
/// r.method(http::Method::GET)
|
/// r.method(http::Method::GET)
|
||||||
/// .with_config(index, |cfg| { // <- register handler
|
/// .with_config(index, |cfg| { // <- register handler
|
||||||
/// cfg.limit(4096); // <- limit size of the payload
|
/// cfg.0.limit(4096); // <- limit size of the payload
|
||||||
/// })
|
/// })
|
||||||
/// });
|
/// });
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn with_config<T, F, R, C>(&mut self, handler: F, cfg_f: C)
|
pub fn with_config<T, F, R, C>(&mut self, handler: F, cfg_f: C)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R>,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
C: FnOnce(&mut T::Config),
|
C: FnOnce(&mut T::Config),
|
||||||
{
|
{
|
||||||
let mut cfg = <T::Config as Default>::default();
|
let mut cfg = <T::Config as Default>::default();
|
||||||
cfg_f(&mut cfg);
|
cfg_f(&mut cfg);
|
||||||
self.h(With::new(handler, cfg));
|
self.h(handler.create_with_config(cfg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set async handler function, use request extractor for parameters.
|
/// Set async handler function, use request extractor for parameters.
|
||||||
@ -240,17 +240,18 @@ impl<S: 'static> Route<S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn with_async<T, F, R, I, E>(&mut self, handler: F)
|
pub fn with_async<T, F, R, I, E>(&mut self, handler: F)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithAsyncFactory<T, S, R, I, E>,
|
||||||
R: Future<Item = I, Error = E> + 'static,
|
R: Future<Item = I, Error = E> + 'static,
|
||||||
I: Responder + 'static,
|
I: Responder + 'static,
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
self.h(WithAsync::new(handler, <T::Config as Default>::default()));
|
self.h(handler.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set async handler function, use request extractor for parameters.
|
/// Set async handler function, use request extractor for parameters.
|
||||||
/// This method allows to configure extractor.
|
/// This method allows to configure extractor. Configuration closure
|
||||||
|
/// accepts config objects as tuple.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # extern crate bytes;
|
/// # extern crate bytes;
|
||||||
@ -275,14 +276,14 @@ impl<S: 'static> Route<S> {
|
|||||||
/// "/{username}/index.html", // <- define path parameters
|
/// "/{username}/index.html", // <- define path parameters
|
||||||
/// |r| r.method(http::Method::GET)
|
/// |r| r.method(http::Method::GET)
|
||||||
/// .with_async_config(index, |cfg| {
|
/// .with_async_config(index, |cfg| {
|
||||||
/// cfg.limit(4096);
|
/// cfg.0.limit(4096);
|
||||||
/// }),
|
/// }),
|
||||||
/// ); // <- use `with` extractor
|
/// ); // <- use `with` extractor
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn with_async_config<T, F, R, I, E, C>(&mut self, handler: F, cfg: C)
|
pub fn with_async_config<T, F, R, I, E, C>(&mut self, handler: F, cfg: C)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithAsyncFactory<T, S, R, I, E>,
|
||||||
R: Future<Item = I, Error = E> + 'static,
|
R: Future<Item = I, Error = E> + 'static,
|
||||||
I: Responder + 'static,
|
I: Responder + 'static,
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
@ -291,7 +292,7 @@ impl<S: 'static> Route<S> {
|
|||||||
{
|
{
|
||||||
let mut extractor_cfg = <T::Config as Default>::default();
|
let mut extractor_cfg = <T::Config as Default>::default();
|
||||||
cfg(&mut extractor_cfg);
|
cfg(&mut extractor_cfg);
|
||||||
self.h(WithAsync::new(handler, extractor_cfg));
|
self.h(handler.create_with_config(extractor_cfg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ use pred::Predicate;
|
|||||||
use resource::{DefaultResource, Resource};
|
use resource::{DefaultResource, Resource};
|
||||||
use scope::Scope;
|
use scope::Scope;
|
||||||
use server::Request;
|
use server::Request;
|
||||||
|
use with::WithFactory;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub(crate) enum ResourceId {
|
pub(crate) enum ResourceId {
|
||||||
@ -398,7 +399,7 @@ impl<S: 'static> Router<S> {
|
|||||||
|
|
||||||
pub(crate) fn register_route<T, F, R>(&mut self, path: &str, method: Method, f: F)
|
pub(crate) fn register_route<T, F, R>(&mut self, path: &str, method: Method, f: F)
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R>,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
|
@ -17,6 +17,7 @@ use pred::Predicate;
|
|||||||
use resource::{DefaultResource, Resource};
|
use resource::{DefaultResource, Resource};
|
||||||
use router::{ResourceDef, Router};
|
use router::{ResourceDef, Router};
|
||||||
use server::Request;
|
use server::Request;
|
||||||
|
use with::WithFactory;
|
||||||
|
|
||||||
/// Resources scope
|
/// Resources scope
|
||||||
///
|
///
|
||||||
@ -222,7 +223,7 @@ impl<S: 'static> Scope<S> {
|
|||||||
/// ```
|
/// ```
|
||||||
pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> Scope<S>
|
pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> Scope<S>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
F: WithFactory<T, S, R>,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
{
|
{
|
||||||
|
156
src/with.rs
156
src/with.rs
@ -7,24 +7,74 @@ use handler::{AsyncResult, AsyncResultItem, FromRequest, Handler, Responder};
|
|||||||
use httprequest::HttpRequest;
|
use httprequest::HttpRequest;
|
||||||
use httpresponse::HttpResponse;
|
use httpresponse::HttpResponse;
|
||||||
|
|
||||||
pub(crate) struct With<T, S, F, R>
|
trait FnWith<T, R>: 'static {
|
||||||
|
fn call_with(self: &Self, T) -> R;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, R, F: Fn(T) -> R + 'static> FnWith<T, R> for F {
|
||||||
|
#[cfg_attr(feature = "cargo-clippy", allow(boxed_local))]
|
||||||
|
fn call_with(self: &Self, arg: T) -> R {
|
||||||
|
(*self)(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub trait WithFactory<T, S, R>: 'static
|
||||||
|
where T: FromRequest<S>,
|
||||||
|
R: Responder,
|
||||||
|
{
|
||||||
|
fn create(self) -> With<T, S, R>;
|
||||||
|
|
||||||
|
fn create_with_config(self, T::Config) -> With<T, S, R>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub trait WithAsyncFactory<T, S, R, I, E>: 'static
|
||||||
|
where T: FromRequest<S>,
|
||||||
|
R: Future<Item=I, Error=E>,
|
||||||
|
I: Responder,
|
||||||
|
E: Into<Error>,
|
||||||
|
{
|
||||||
|
fn create(self) -> WithAsync<T, S, R, I, E>;
|
||||||
|
|
||||||
|
fn create_with_config(self, T::Config) -> WithAsync<T, S, R, I, E>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl<T1, T2, T3, S, F, R> WithFactory<(T1, T2, T3), S, R> for F
|
||||||
|
// where F: Fn(T1, T2, T3) -> R + 'static,
|
||||||
|
// T1: FromRequest<S> + 'static,
|
||||||
|
// T2: FromRequest<S> + 'static,
|
||||||
|
// T3: FromRequest<S> + 'static,
|
||||||
|
// R: Responder + 'static,
|
||||||
|
// S: 'static,
|
||||||
|
// {
|
||||||
|
// fn create(self) -> With<(T1, T2, T3), S, R> {
|
||||||
|
// With::new(move |(t1, t2, t3)| (self)(t1, t2, t3), (
|
||||||
|
// T1::Config::default(), T2::Config::default(), T3::Config::default()))
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn create_with_config(self, cfg: (T1::Config, T2::Config, T3::Config,)) -> With<(T1, T2, T3), S, R> {
|
||||||
|
// With::new(move |(t1, t2, t3)| (self)(t1, t2, t3), cfg)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub struct With<T, S, R>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
T: FromRequest<S>,
|
T: FromRequest<S>,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
hnd: Rc<F>,
|
hnd: Rc<FnWith<T, R>>,
|
||||||
cfg: Rc<T::Config>,
|
cfg: Rc<T::Config>,
|
||||||
_s: PhantomData<S>,
|
_s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R> With<T, S, F, R>
|
impl<T, S, R> With<T, S, R>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
T: FromRequest<S>,
|
T: FromRequest<S>,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
pub fn new(f: F, cfg: T::Config) -> Self {
|
pub fn new<F: Fn(T) -> R + 'static>(f: F, cfg: T::Config) -> Self {
|
||||||
With {
|
With {
|
||||||
cfg: Rc::new(cfg),
|
cfg: Rc::new(cfg),
|
||||||
hnd: Rc::new(f),
|
hnd: Rc::new(f),
|
||||||
@ -33,9 +83,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R> Handler<S> for With<T, S, F, R>
|
impl<T, S, R> Handler<S> for With<T, S, R>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
@ -60,24 +109,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WithHandlerFut<T, S, F, R>
|
struct WithHandlerFut<T, S, R>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Responder,
|
R: Responder,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
started: bool,
|
started: bool,
|
||||||
hnd: Rc<F>,
|
hnd: Rc<FnWith<T, R>>,
|
||||||
cfg: Rc<T::Config>,
|
cfg: Rc<T::Config>,
|
||||||
req: HttpRequest<S>,
|
req: HttpRequest<S>,
|
||||||
fut1: Option<Box<Future<Item = T, Error = Error>>>,
|
fut1: Option<Box<Future<Item = T, Error = Error>>>,
|
||||||
fut2: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
|
fut2: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R> Future for WithHandlerFut<T, S, F, R>
|
impl<T, S, R> Future for WithHandlerFut<T, S, R>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
T: FromRequest<S> + 'static,
|
T: FromRequest<S> + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
@ -108,7 +155,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let item = match (*self.hnd)(item).respond_to(&self.req) {
|
let item = match self.hnd.as_ref().call_with(item).respond_to(&self.req) {
|
||||||
Ok(item) => item.into(),
|
Ok(item) => item.into(),
|
||||||
Err(e) => return Err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
@ -124,30 +171,29 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct WithAsync<T, S, F, R, I, E>
|
#[doc(hidden)]
|
||||||
|
pub struct WithAsync<T, S, R, I, E>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Future<Item = I, Error = E>,
|
R: Future<Item = I, Error = E>,
|
||||||
I: Responder,
|
I: Responder,
|
||||||
E: Into<E>,
|
E: Into<E>,
|
||||||
T: FromRequest<S>,
|
T: FromRequest<S>,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
hnd: Rc<F>,
|
hnd: Rc<FnWith<T, R>>,
|
||||||
cfg: Rc<T::Config>,
|
cfg: Rc<T::Config>,
|
||||||
_s: PhantomData<S>,
|
_s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R, I, E> WithAsync<T, S, F, R, I, E>
|
impl<T, S, R, I, E> WithAsync<T, S, R, I, E>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Future<Item = I, Error = E>,
|
R: Future<Item = I, Error = E>,
|
||||||
I: Responder,
|
I: Responder,
|
||||||
E: Into<Error>,
|
E: Into<Error>,
|
||||||
T: FromRequest<S>,
|
T: FromRequest<S>,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
pub fn new(f: F, cfg: T::Config) -> Self {
|
pub fn new<F: Fn(T) -> R + 'static>(f: F, cfg: T::Config) -> Self {
|
||||||
WithAsync {
|
WithAsync {
|
||||||
cfg: Rc::new(cfg),
|
cfg: Rc::new(cfg),
|
||||||
hnd: Rc::new(f),
|
hnd: Rc::new(f),
|
||||||
@ -156,9 +202,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R, I, E> Handler<S> for WithAsync<T, S, F, R, I, E>
|
impl<T, S, R, I, E> Handler<S> for WithAsync<T, S, R, I, E>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R + 'static,
|
|
||||||
R: Future<Item = I, Error = E> + 'static,
|
R: Future<Item = I, Error = E> + 'static,
|
||||||
I: Responder + 'static,
|
I: Responder + 'static,
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
@ -186,9 +231,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WithAsyncHandlerFut<T, S, F, R, I, E>
|
struct WithAsyncHandlerFut<T, S, R, I, E>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Future<Item = I, Error = E> + 'static,
|
R: Future<Item = I, Error = E> + 'static,
|
||||||
I: Responder + 'static,
|
I: Responder + 'static,
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
@ -196,7 +240,7 @@ where
|
|||||||
S: 'static,
|
S: 'static,
|
||||||
{
|
{
|
||||||
started: bool,
|
started: bool,
|
||||||
hnd: Rc<F>,
|
hnd: Rc<FnWith<T, R>>,
|
||||||
cfg: Rc<T::Config>,
|
cfg: Rc<T::Config>,
|
||||||
req: HttpRequest<S>,
|
req: HttpRequest<S>,
|
||||||
fut1: Option<Box<Future<Item = T, Error = Error>>>,
|
fut1: Option<Box<Future<Item = T, Error = Error>>>,
|
||||||
@ -204,9 +248,8 @@ where
|
|||||||
fut3: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
|
fut3: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, S, F, R, I, E> Future for WithAsyncHandlerFut<T, S, F, R, I, E>
|
impl<T, S, R, I, E> Future for WithAsyncHandlerFut<T, S, R, I, E>
|
||||||
where
|
where
|
||||||
F: Fn(T) -> R,
|
|
||||||
R: Future<Item = I, Error = E> + 'static,
|
R: Future<Item = I, Error = E> + 'static,
|
||||||
I: Responder + 'static,
|
I: Responder + 'static,
|
||||||
E: Into<Error> + 'static,
|
E: Into<Error> + 'static,
|
||||||
@ -257,7 +300,64 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.fut2 = Some((*self.hnd)(item));
|
self.fut2 = Some(self.hnd.as_ref().call_with(item));
|
||||||
self.poll()
|
self.poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! with_factory_tuple ({$(($n:tt, $T:ident)),+} => {
|
||||||
|
impl<$($T,)+ State, Func, Res> WithFactory<($($T,)+), State, Res> for Func
|
||||||
|
where Func: Fn($($T,)+) -> Res + 'static,
|
||||||
|
$($T: FromRequest<State> + 'static,)+
|
||||||
|
Res: Responder + 'static,
|
||||||
|
State: 'static,
|
||||||
|
{
|
||||||
|
fn create(self) -> With<($($T,)+), State, Res> {
|
||||||
|
With::new(move |($($n,)+)| (self)($($n,)+), ($($T::Config::default(),)+))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_with_config(self, cfg: ($($T::Config,)+)) -> With<($($T,)+), State, Res> {
|
||||||
|
With::new(move |($($n,)+)| (self)($($n,)+), cfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
macro_rules! with_async_factory_tuple ({$(($n:tt, $T:ident)),+} => {
|
||||||
|
impl<$($T,)+ State, Func, Res, Item, Err> WithAsyncFactory<($($T,)+), State, Res, Item, Err> for Func
|
||||||
|
where Func: Fn($($T,)+) -> Res + 'static,
|
||||||
|
$($T: FromRequest<State> + 'static,)+
|
||||||
|
Res: Future<Item=Item, Error=Err>,
|
||||||
|
Item: Responder + 'static,
|
||||||
|
Err: Into<Error>,
|
||||||
|
State: 'static,
|
||||||
|
{
|
||||||
|
fn create(self) -> WithAsync<($($T,)+), State, Res, Item, Err> {
|
||||||
|
WithAsync::new(move |($($n,)+)| (self)($($n,)+), ($($T::Config::default(),)+))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_with_config(self, cfg: ($($T::Config,)+)) -> WithAsync<($($T,)+), State, Res, Item, Err> {
|
||||||
|
WithAsync::new(move |($($n,)+)| (self)($($n,)+), cfg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
with_factory_tuple!((a, A));
|
||||||
|
with_factory_tuple!((a, A), (b, B));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H));
|
||||||
|
with_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H), (i, I));
|
||||||
|
|
||||||
|
with_async_factory_tuple!((a, A));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H));
|
||||||
|
with_async_factory_tuple!((a, A), (b, B), (c, C), (d, D), (e, E), (f, F), (g, G), (h, H), (i, I));
|
||||||
|
@ -208,7 +208,7 @@ fn test_form_extractor2() {
|
|||||||
r.route().with_config(
|
r.route().with_config(
|
||||||
|form: Form<FormData>| format!("{}", form.username),
|
|form: Form<FormData>| format!("{}", form.username),
|
||||||
|cfg| {
|
|cfg| {
|
||||||
cfg.error_handler(|err, _| {
|
cfg.0.error_handler(|err, _| {
|
||||||
error::InternalError::from_response(
|
error::InternalError::from_response(
|
||||||
err,
|
err,
|
||||||
HttpResponse::Conflict().finish(),
|
HttpResponse::Conflict().finish(),
|
||||||
@ -423,7 +423,7 @@ fn test_path_and_query_extractor2_async3() {
|
|||||||
let mut srv = test::TestServer::new(|app| {
|
let mut srv = test::TestServer::new(|app| {
|
||||||
app.resource("/{username}/index.html", |r| {
|
app.resource("/{username}/index.html", |r| {
|
||||||
r.route().with(
|
r.route().with(
|
||||||
|(data, p, _q): (Json<Value>, Path<PParam>, Query<PParam>)| {
|
|data: Json<Value>, p: Path<PParam>, _: Query<PParam>| {
|
||||||
Delay::new(Instant::now() + Duration::from_millis(10))
|
Delay::new(Instant::now() + Duration::from_millis(10))
|
||||||
.and_then(move |_| {
|
.and_then(move |_| {
|
||||||
Ok(format!("Welcome {} - {}!", p.username, data.0))
|
Ok(format!("Welcome {} - {}!", p.username, data.0))
|
||||||
|
@ -13,8 +13,8 @@ extern crate tokio_reactor;
|
|||||||
extern crate tokio_tcp;
|
extern crate tokio_tcp;
|
||||||
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::sync::{mpsc, Arc};
|
use std::sync::Arc;
|
||||||
use std::{net, thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
#[cfg(feature = "brotli")]
|
#[cfg(feature = "brotli")]
|
||||||
use brotli2::write::{BrotliDecoder, BrotliEncoder};
|
use brotli2::write::{BrotliDecoder, BrotliEncoder};
|
||||||
@ -32,7 +32,6 @@ use tokio::executor::current_thread;
|
|||||||
use tokio::runtime::current_thread::Runtime;
|
use tokio::runtime::current_thread::Runtime;
|
||||||
use tokio_tcp::TcpStream;
|
use tokio_tcp::TcpStream;
|
||||||
|
|
||||||
use actix::System;
|
|
||||||
use actix_web::*;
|
use actix_web::*;
|
||||||
|
|
||||||
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
||||||
@ -60,11 +59,13 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn test_start() {
|
fn test_start() {
|
||||||
|
use std::{mpsc, net};
|
||||||
|
|
||||||
let _ = test::TestServer::unused_addr();
|
let _ = test::TestServer::unused_addr();
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
thread::spawn(|| {
|
thread::spawn(|| {
|
||||||
System::run(move || {
|
actix::System::run(move || {
|
||||||
let srv = server::new(|| {
|
let srv = server::new(|| {
|
||||||
vec![App::new().resource("/", |r| {
|
vec![App::new().resource("/", |r| {
|
||||||
r.method(http::Method::GET).f(|_| HttpResponse::Ok())
|
r.method(http::Method::GET).f(|_| HttpResponse::Ok())
|
||||||
|
Loading…
Reference in New Issue
Block a user