1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-24 07:53:00 +01:00

rename filter to guard

This commit is contained in:
Nikolay Kim 2019-03-03 12:09:38 -08:00
parent b81ae899f6
commit 237677be15
4 changed files with 145 additions and 290 deletions

View File

@ -1,47 +1,48 @@
//! Route match predicates //! Route match guards.
#![allow(non_snake_case)] #![allow(non_snake_case)]
use actix_http::http::{self, header, HttpTryFrom}; use actix_http::http::{self, header, HttpTryFrom};
use actix_http::RequestHead; use actix_http::RequestHead;
/// Trait defines resource predicate. /// Trait defines resource guards. Guards are used for routes selection.
/// Predicate can modify request object. It is also possible to ///
/// Guard can not modify request object. But it is possible to
/// to store extra attributes on request by using `Extensions` container, /// to store extra attributes on request by using `Extensions` container,
/// Extensions container available via `HttpRequest::extensions()` method. /// Extensions container available via `RequestHead::extensions()` method.
pub trait Filter { pub trait Guard {
/// Check if request matches predicate /// Check if request matches predicate
fn check(&self, request: &RequestHead) -> bool; fn check(&self, request: &RequestHead) -> bool;
} }
/// Return filter that matches if any of supplied filters. /// Return guard that matches if any of supplied guards.
/// ///
/// ```rust /// ```rust
/// use actix_web::{web, filter, App, HttpResponse}; /// use actix_web::{web, guard, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// App::new().resource("/index.html", |r| /// App::new().resource("/index.html", |r|
/// r.route( /// r.route(
/// web::route() /// web::route()
/// .filter(filter::Any(filter::Get()).or(filter::Post())) /// .guard(guard::Any(guard::Get()).or(guard::Post()))
/// .to(|| HttpResponse::MethodNotAllowed())) /// .to(|| HttpResponse::MethodNotAllowed()))
/// ); /// );
/// } /// }
/// ``` /// ```
pub fn Any<F: Filter + 'static>(filter: F) -> AnyFilter { pub fn Any<F: Guard + 'static>(guard: F) -> AnyGuard {
AnyFilter(vec![Box::new(filter)]) AnyGuard(vec![Box::new(guard)])
} }
/// Matches if any of supplied filters matche. /// Matches if any of supplied guards matche.
pub struct AnyFilter(Vec<Box<Filter>>); pub struct AnyGuard(Vec<Box<Guard>>);
impl AnyFilter { impl AnyGuard {
/// Add filter to a list of filters to check /// Add guard to a list of guards to check
pub fn or<F: Filter + 'static>(mut self, filter: F) -> Self { pub fn or<F: Guard + 'static>(mut self, guard: F) -> Self {
self.0.push(Box::new(filter)); self.0.push(Box::new(guard));
self self
} }
} }
impl Filter for AnyFilter { impl Guard for AnyGuard {
fn check(&self, req: &RequestHead) -> bool { fn check(&self, req: &RequestHead) -> bool {
for p in &self.0 { for p in &self.0 {
if p.check(req) { if p.check(req) {
@ -52,37 +53,37 @@ impl Filter for AnyFilter {
} }
} }
/// Return filter that matches if all of supplied filters match. /// Return guard that matches if all of the supplied guards.
/// ///
/// ```rust /// ```rust
/// # extern crate actix_web; /// # extern crate actix_web;
/// use actix_web::{filter, web, App, HttpResponse}; /// use actix_web::{guard, web, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// App::new().resource("/index.html", |r| { /// App::new().resource("/index.html", |r| {
/// r.route(web::route() /// r.route(web::route()
/// .filter( /// .guard(
/// filter::All(filter::Get()).and(filter::Header("content-type", "text/plain"))) /// guard::All(guard::Get()).and(guard::Header("content-type", "text/plain")))
/// .to(|| HttpResponse::MethodNotAllowed())) /// .to(|| HttpResponse::MethodNotAllowed()))
/// }); /// });
/// } /// }
/// ``` /// ```
pub fn All<F: Filter + 'static>(filter: F) -> AllFilter { pub fn All<F: Guard + 'static>(guard: F) -> AllGuard {
AllFilter(vec![Box::new(filter)]) AllGuard(vec![Box::new(guard)])
} }
/// Matches if all of supplied filters matche. /// Matches if all of supplied guards.
pub struct AllFilter(Vec<Box<Filter>>); pub struct AllGuard(Vec<Box<Guard>>);
impl AllFilter { impl AllGuard {
/// Add new predicate to list of predicates to check /// Add new guard to the list of guards to check
pub fn and<F: Filter + 'static>(mut self, filter: F) -> Self { pub fn and<F: Guard + 'static>(mut self, guard: F) -> Self {
self.0.push(Box::new(filter)); self.0.push(Box::new(guard));
self self
} }
} }
impl Filter for AllFilter { impl Guard for AllGuard {
fn check(&self, request: &RequestHead) -> bool { fn check(&self, request: &RequestHead) -> bool {
for p in &self.0 { for p in &self.0 {
if !p.check(request) { if !p.check(request) {
@ -93,93 +94,93 @@ impl Filter for AllFilter {
} }
} }
/// Return predicate that matches if supplied predicate does not match. /// Return guard that matches if supplied guard does not match.
pub fn Not<F: Filter + 'static>(filter: F) -> NotFilter { pub fn Not<F: Guard + 'static>(guard: F) -> NotGuard {
NotFilter(Box::new(filter)) NotGuard(Box::new(guard))
} }
#[doc(hidden)] #[doc(hidden)]
pub struct NotFilter(Box<Filter>); pub struct NotGuard(Box<Guard>);
impl Filter for NotFilter { impl Guard for NotGuard {
fn check(&self, request: &RequestHead) -> bool { fn check(&self, request: &RequestHead) -> bool {
!self.0.check(request) !self.0.check(request)
} }
} }
/// Http method predicate /// Http method guard
#[doc(hidden)] #[doc(hidden)]
pub struct MethodFilter(http::Method); pub struct MethodGuard(http::Method);
impl Filter for MethodFilter { impl Guard for MethodGuard {
fn check(&self, request: &RequestHead) -> bool { fn check(&self, request: &RequestHead) -> bool {
request.method == self.0 request.method == self.0
} }
} }
/// Predicate to match *GET* http method /// Guard to match *GET* http method
pub fn Get() -> MethodFilter { pub fn Get() -> MethodGuard {
MethodFilter(http::Method::GET) MethodGuard(http::Method::GET)
} }
/// Predicate to match *POST* http method /// Predicate to match *POST* http method
pub fn Post() -> MethodFilter { pub fn Post() -> MethodGuard {
MethodFilter(http::Method::POST) MethodGuard(http::Method::POST)
} }
/// Predicate to match *PUT* http method /// Predicate to match *PUT* http method
pub fn Put() -> MethodFilter { pub fn Put() -> MethodGuard {
MethodFilter(http::Method::PUT) MethodGuard(http::Method::PUT)
} }
/// Predicate to match *DELETE* http method /// Predicate to match *DELETE* http method
pub fn Delete() -> MethodFilter { pub fn Delete() -> MethodGuard {
MethodFilter(http::Method::DELETE) MethodGuard(http::Method::DELETE)
} }
/// Predicate to match *HEAD* http method /// Predicate to match *HEAD* http method
pub fn Head() -> MethodFilter { pub fn Head() -> MethodGuard {
MethodFilter(http::Method::HEAD) MethodGuard(http::Method::HEAD)
} }
/// Predicate to match *OPTIONS* http method /// Predicate to match *OPTIONS* http method
pub fn Options() -> MethodFilter { pub fn Options() -> MethodGuard {
MethodFilter(http::Method::OPTIONS) MethodGuard(http::Method::OPTIONS)
} }
/// Predicate to match *CONNECT* http method /// Predicate to match *CONNECT* http method
pub fn Connect() -> MethodFilter { pub fn Connect() -> MethodGuard {
MethodFilter(http::Method::CONNECT) MethodGuard(http::Method::CONNECT)
} }
/// Predicate to match *PATCH* http method /// Predicate to match *PATCH* http method
pub fn Patch() -> MethodFilter { pub fn Patch() -> MethodGuard {
MethodFilter(http::Method::PATCH) MethodGuard(http::Method::PATCH)
} }
/// Predicate to match *TRACE* http method /// Predicate to match *TRACE* http method
pub fn Trace() -> MethodFilter { pub fn Trace() -> MethodGuard {
MethodFilter(http::Method::TRACE) MethodGuard(http::Method::TRACE)
} }
/// Predicate to match specified http method /// Predicate to match specified http method
pub fn Method(method: http::Method) -> MethodFilter { pub fn Method(method: http::Method) -> MethodGuard {
MethodFilter(method) MethodGuard(method)
} }
/// Return predicate that matches if request contains specified header and /// Return predicate that matches if request contains specified header and
/// value. /// value.
pub fn Header(name: &'static str, value: &'static str) -> HeaderFilter { pub fn Header(name: &'static str, value: &'static str) -> HeaderGuard {
HeaderFilter( HeaderGuard(
header::HeaderName::try_from(name).unwrap(), header::HeaderName::try_from(name).unwrap(),
header::HeaderValue::from_static(value), header::HeaderValue::from_static(value),
) )
} }
#[doc(hidden)] #[doc(hidden)]
pub struct HeaderFilter(header::HeaderName, header::HeaderValue); pub struct HeaderGuard(header::HeaderName, header::HeaderValue);
impl Filter for HeaderFilter { impl Guard for HeaderGuard {
fn check(&self, req: &RequestHead) -> bool { fn check(&self, req: &RequestHead) -> bool {
if let Some(val) = req.headers.get(&self.0) { if let Some(val) = req.headers.get(&self.0) {
return val == self.1; return val == self.1;
@ -197,26 +198,26 @@ impl Filter for HeaderFilter {
// /// fn main() { // /// fn main() {
// /// App::new().resource("/index.html", |r| { // /// App::new().resource("/index.html", |r| {
// /// r.route() // /// r.route()
// /// .filter(pred::Host("www.rust-lang.org")) // /// .guard(pred::Host("www.rust-lang.org"))
// /// .f(|_| HttpResponse::MethodNotAllowed()) // /// .f(|_| HttpResponse::MethodNotAllowed())
// /// }); // /// });
// /// } // /// }
// /// ``` // /// ```
// pub fn Host<H: AsRef<str>>(host: H) -> HostFilter { // pub fn Host<H: AsRef<str>>(host: H) -> HostGuard {
// HostFilter(host.as_ref().to_string(), None) // HostGuard(host.as_ref().to_string(), None)
// } // }
// #[doc(hidden)] // #[doc(hidden)]
// pub struct HostFilter(String, Option<String>); // pub struct HostGuard(String, Option<String>);
// impl HostFilter { // impl HostGuard {
// /// Set reuest scheme to match // /// Set reuest scheme to match
// pub fn scheme<H: AsRef<str>>(&mut self, scheme: H) { // pub fn scheme<H: AsRef<str>>(&mut self, scheme: H) {
// self.1 = Some(scheme.as_ref().to_string()) // self.1 = Some(scheme.as_ref().to_string())
// } // }
// } // }
// impl Filter for HostFilter { // impl Guard for HostGuard {
// fn check(&self, _req: &RequestHead) -> bool { // fn check(&self, _req: &RequestHead) -> bool {
// // let info = req.connection_info(); // // let info = req.connection_info();
// // if let Some(ref scheme) = self.1 { // // if let Some(ref scheme) = self.1 {

View File

@ -5,7 +5,7 @@ pub mod extractor;
pub mod handler; pub mod handler;
// mod info; // mod info;
pub mod blocking; pub mod blocking;
pub mod filter; pub mod guard;
pub mod middleware; pub mod middleware;
mod request; mod request;
mod resource; mod resource;

View File

@ -56,22 +56,21 @@ where
InitError = (), InitError = (),
>, >,
{ {
/// Register a new route and return mutable reference to *Route* object. /// Register a new route.
/// *Route* is used for route configuration, i.e. adding predicates, /// *Route* is used for route configuration, i.e. adding guards,
/// setting up handler. /// setting up handler.
/// ///
/// ```rust,ignore /// ```rust
/// use actix_web::*; /// use actix_web::{web, guard, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// let app = App::new() /// let app = App::new()
/// .resource("/", |r| { /// .resource("/", |r| {
/// r.route() /// r.route(web::route()
/// .filter(pred::Any(pred::Get()).or(pred::Put())) /// .guard(guard::Any(guard::Get()).or(guard::Put()))
/// .filter(pred::Header("Content-Type", "text/plain")) /// .guard(guard::Header("Content-Type", "text/plain"))
/// .f(|r| HttpResponse::Ok()) /// .to(|| HttpResponse::Ok()))
/// }) /// });
/// .finish();
/// } /// }
/// ``` /// ```
pub fn route(mut self, route: Route<P>) -> Self { pub fn route(mut self, route: Route<P>) -> Self {
@ -81,21 +80,23 @@ where
/// Register a new route and add handler. /// Register a new route and add handler.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web;
/// use actix_web::*; /// use actix_web::*;
/// fn index(req: HttpRequest) -> HttpResponse { unimplemented!() }
/// ///
/// App::new().resource("/", |r| r.with(index)); /// fn index(req: HttpRequest) -> HttpResponse {
/// unimplemented!()
/// }
///
/// App::new().resource("/", |r| r.to(index));
/// ``` /// ```
/// ///
/// This is shortcut for: /// This is shortcut for:
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web; /// # extern crate actix_web;
/// # use actix_web::*; /// # use actix_web::*;
/// # fn index(req: HttpRequest) -> HttpResponse { unimplemented!() } /// # fn index(req: HttpRequest) -> HttpResponse { unimplemented!() }
/// App::new().resource("/", |r| r.route().with(index)); /// App::new().resource("/", |r| r.route(web::route().to(index)));
/// ``` /// ```
pub fn to<F, I, R>(mut self, handler: F) -> Self pub fn to<F, I, R>(mut self, handler: F) -> Self
where where
@ -109,30 +110,26 @@ where
/// Register a new route and add async handler. /// Register a new route and add async handler.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web;
/// # extern crate futures;
/// use actix_web::*; /// use actix_web::*;
/// use futures::future::Future; /// use futures::future::{ok, Future};
/// ///
/// fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> { /// fn index(req: HttpRequest) -> impl Future<Item=HttpResponse, Error=Error> {
/// unimplemented!() /// ok(HttpResponse::Ok().finish())
/// } /// }
/// ///
/// App::new().resource("/", |r| r.with_async(index)); /// App::new().resource("/", |r| r.to_async(index));
/// ``` /// ```
/// ///
/// This is shortcut for: /// This is shortcut for:
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web;
/// # extern crate futures;
/// # use actix_web::*; /// # use actix_web::*;
/// # use futures::future::Future; /// # use futures::future::Future;
/// # fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> { /// # fn index(req: HttpRequest) -> Box<Future<Item=HttpResponse, Error=Error>> {
/// # unimplemented!() /// # unimplemented!()
/// # } /// # }
/// App::new().resource("/", |r| r.route().with_async(index)); /// App::new().resource("/", |r| r.route(web::route().to_async(index)));
/// ``` /// ```
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
pub fn to_async<F, I, R>(mut self, handler: F) -> Self pub fn to_async<F, I, R>(mut self, handler: F) -> Self

View File

@ -5,7 +5,7 @@ use actix_http::{http::Method, Error, Extensions, Response};
use actix_service::{NewService, Service}; use actix_service::{NewService, Service};
use futures::{Async, Future, IntoFuture, Poll}; use futures::{Async, Future, IntoFuture, Poll};
use crate::filter::{self, Filter}; use crate::guard::{self, Guard};
use crate::handler::{ use crate::handler::{
AsyncFactory, AsyncHandle, ConfigStorage, Extract, ExtractorConfig, Factory, AsyncFactory, AsyncHandle, ConfigStorage, Extract, ExtractorConfig, Factory,
FromRequest, Handle, FromRequest, Handle,
@ -40,7 +40,7 @@ type BoxedRouteNewService<Req, Res> = Box<
/// If handler is not explicitly set, default *404 Not Found* handler is used. /// If handler is not explicitly set, default *404 Not Found* handler is used.
pub struct Route<P> { pub struct Route<P> {
service: BoxedRouteNewService<ServiceRequest<P>, ServiceResponse>, service: BoxedRouteNewService<ServiceRequest<P>, ServiceResponse>,
filters: Rc<Vec<Box<Filter>>>, guards: Rc<Vec<Box<Guard>>>,
config: ConfigStorage, config: ConfigStorage,
config_ref: Rc<RefCell<Option<Rc<Extensions>>>>, config_ref: Rc<RefCell<Option<Rc<Extensions>>>>,
} }
@ -55,7 +55,7 @@ impl<P: 'static> Route<P> {
Handle::new(|| HttpResponse::NotFound()).map_err(|_| panic!()), Handle::new(|| HttpResponse::NotFound()).map_err(|_| panic!()),
), ),
)), )),
filters: Rc::new(Vec::new()), guards: Rc::new(Vec::new()),
config: ConfigStorage::default(), config: ConfigStorage::default(),
config_ref, config_ref,
} }
@ -98,7 +98,7 @@ impl<P> NewService for Route<P> {
fn new_service(&self, _: &()) -> Self::Future { fn new_service(&self, _: &()) -> Self::Future {
CreateRouteService { CreateRouteService {
fut: self.service.new_service(&()), fut: self.service.new_service(&()),
filters: self.filters.clone(), guards: self.guards.clone(),
} }
} }
} }
@ -109,7 +109,7 @@ type RouteFuture<P> = Box<
pub struct CreateRouteService<P> { pub struct CreateRouteService<P> {
fut: RouteFuture<P>, fut: RouteFuture<P>,
filters: Rc<Vec<Box<Filter>>>, guards: Rc<Vec<Box<Guard>>>,
} }
impl<P> Future for CreateRouteService<P> { impl<P> Future for CreateRouteService<P> {
@ -120,7 +120,7 @@ impl<P> Future for CreateRouteService<P> {
match self.fut.poll()? { match self.fut.poll()? {
Async::Ready(service) => Ok(Async::Ready(RouteService { Async::Ready(service) => Ok(Async::Ready(RouteService {
service, service,
filters: self.filters.clone(), guards: self.guards.clone(),
})), })),
Async::NotReady => Ok(Async::NotReady), Async::NotReady => Ok(Async::NotReady),
} }
@ -129,12 +129,12 @@ impl<P> Future for CreateRouteService<P> {
pub struct RouteService<P> { pub struct RouteService<P> {
service: BoxedRouteService<ServiceRequest<P>, ServiceResponse>, service: BoxedRouteService<ServiceRequest<P>, ServiceResponse>,
filters: Rc<Vec<Box<Filter>>>, guards: Rc<Vec<Box<Guard>>>,
} }
impl<P> RouteService<P> { impl<P> RouteService<P> {
pub fn check(&self, req: &mut ServiceRequest<P>) -> bool { pub fn check(&self, req: &mut ServiceRequest<P>) -> bool {
for f in self.filters.iter() { for f in self.guards.iter() {
if !f.check(req.head()) { if !f.check(req.head()) {
return false; return false;
} }
@ -159,45 +159,41 @@ impl<P> Service for RouteService<P> {
} }
impl<P: 'static> Route<P> { impl<P: 'static> Route<P> {
/// Add method match filter to the route. /// Add method guard to the route.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web;
/// # use actix_web::*; /// # use actix_web::*;
/// # fn main() { /// # fn main() {
/// App::new().resource("/path", |r| { /// App::new().resource("/path", |r| {
/// r.route() /// r.route(web::get()
/// .filter(pred::Get()) /// .guard(guard::Get())
/// .filter(pred::Header("content-type", "text/plain")) /// .guard(guard::Header("content-type", "text/plain"))
/// .f(|req| HttpResponse::Ok()) /// .to(|req: HttpRequest| HttpResponse::Ok()))
/// }) /// });
/// # .finish();
/// # } /// # }
/// ``` /// ```
pub fn method(mut self, method: Method) -> Self { pub fn method(mut self, method: Method) -> Self {
Rc::get_mut(&mut self.filters) Rc::get_mut(&mut self.guards)
.unwrap() .unwrap()
.push(Box::new(filter::Method(method))); .push(Box::new(guard::Method(method)));
self self
} }
/// Add filter to the route. /// Add guard to the route.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate actix_web;
/// # use actix_web::*; /// # use actix_web::*;
/// # fn main() { /// # fn main() {
/// App::new().resource("/path", |r| { /// App::new().resource("/path", |r| {
/// r.route() /// r.route(web::route()
/// .filter(pred::Get()) /// .guard(guard::Get())
/// .filter(pred::Header("content-type", "text/plain")) /// .guard(guard::Header("content-type", "text/plain"))
/// .f(|req| HttpResponse::Ok()) /// .to(|req: HttpRequest| HttpResponse::Ok()))
/// }) /// });
/// # .finish();
/// # } /// # }
/// ``` /// ```
pub fn filter<F: Filter + 'static>(mut self, f: F) -> Self { pub fn guard<F: Guard + 'static>(mut self, f: F) -> Self {
Rc::get_mut(&mut self.filters).unwrap().push(Box::new(f)); Rc::get_mut(&mut self.guards).unwrap().push(Box::new(f));
self self
} }
@ -214,19 +210,16 @@ impl<P: 'static> Route<P> {
// { // {
// RouteServiceBuilder { // RouteServiceBuilder {
// service: md.into_new_service(), // service: md.into_new_service(),
// filters: self.filters, // guards: self.guards,
// _t: PhantomData, // _t: PhantomData,
// } // }
// } // }
/// Set handler function, use request extractor for parameters. /// Set handler function, use request extractors for parameters.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive; /// #[macro_use] extern crate serde_derive;
/// use actix_web::{http, App, Path, Result}; /// use actix_web::{web, http, App, Path};
/// ///
/// #[derive(Deserialize)] /// #[derive(Deserialize)]
/// struct Info { /// struct Info {
@ -234,27 +227,24 @@ impl<P: 'static> Route<P> {
/// } /// }
/// ///
/// /// extract path info using serde /// /// extract path info using serde
/// fn index(info: Path<Info>) -> Result<String> { /// fn index(info: Path<Info>) -> String {
/// Ok(format!("Welcome {}!", info.username)) /// format!("Welcome {}!", info.username)
/// } /// }
/// ///
/// fn main() { /// fn main() {
/// let app = App::new().resource( /// let app = App::new().resource(
/// "/{username}/index.html", // <- define path parameters /// "/{username}/index.html", // <- define path parameters
/// |r| r.method(http::Method::GET).with(index), /// |r| r.route(web::get().to(index)), // <- register handler
/// ); // <- use `with` extractor /// );
/// } /// }
/// ``` /// ```
/// ///
/// It is possible to use multiple extractors for one handler function. /// It is possible to use multiple extractors for one handler function.
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use std::collections::HashMap; /// # use std::collections::HashMap;
/// use actix_web::{http, App, Json, Path, Query, Result}; /// # use serde_derive::Deserialize;
/// use actix_web::{web, http, App, Json, Path, Query};
/// ///
/// #[derive(Deserialize)] /// #[derive(Deserialize)]
/// struct Info { /// struct Info {
@ -262,17 +252,15 @@ impl<P: 'static> Route<P> {
/// } /// }
/// ///
/// /// extract path info using serde /// /// extract path info using serde
/// fn index( /// fn index(path: Path<Info>, query: Query<HashMap<String, String>>, body: Json<Info>) -> String {
/// path: Path<Info>, query: Query<HashMap<String, String>>, body: Json<Info>, /// format!("Welcome {}!", path.username)
/// ) -> Result<String> {
/// Ok(format!("Welcome {}!", path.username))
/// } /// }
/// ///
/// fn main() { /// fn main() {
/// let app = App::new().resource( /// let app = App::new().resource(
/// "/{username}/index.html", // <- define path parameters /// "/{username}/index.html", // <- define path parameters
/// |r| r.method(http::Method::GET).with(index), /// |r| r.route(web::method(http::Method::GET).to(index)),
/// ); // <- use `with` extractor /// );
/// } /// }
/// ``` /// ```
pub fn to<F, T, R>(mut self, handler: F) -> Route<P> pub fn to<F, T, R>(mut self, handler: F) -> Route<P>
@ -289,16 +277,13 @@ impl<P: 'static> Route<P> {
self self
} }
/// Set async handler function, use request extractor for parameters. /// Set async handler function, use request extractors for parameters.
/// Also this method needs to be used if your handler function returns /// This method has to be used if your handler function returns `impl Future<>`
/// `impl Future<>`
/// ///
/// ```rust,ignore /// ```rust
/// # extern crate bytes; /// # use futures::future::ok;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive; /// #[macro_use] extern crate serde_derive;
/// use actix_web::{http, App, Error, Path}; /// use actix_web::{web, http, App, Error, Path};
/// use futures::Future; /// use futures::Future;
/// ///
/// #[derive(Deserialize)] /// #[derive(Deserialize)]
@ -307,15 +292,15 @@ impl<P: 'static> Route<P> {
/// } /// }
/// ///
/// /// extract path info using serde /// /// extract path info using serde
/// fn index(info: Path<Info>) -> Box<Future<Item = &'static str, Error = Error>> { /// fn index(info: Path<Info>) -> impl Future<Item = &'static str, Error = Error> {
/// unimplemented!() /// ok("Hello World!")
/// } /// }
/// ///
/// fn main() { /// fn main() {
/// let app = App::new().resource( /// let app = App::new().resource(
/// "/{username}/index.html", // <- define path parameters /// "/{username}/index.html", // <- define path parameters
/// |r| r.method(http::Method::GET).with_async(index), /// |r| r.route(web::get().to_async(index)), // <- register async handler
/// ); // <- use `with` extractor /// );
/// } /// }
/// ``` /// ```
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
@ -363,134 +348,6 @@ impl<P: 'static> Route<P> {
} }
} }
// pub struct RouteServiceBuilder<P, T, U1, U2> {
// service: T,
// filters: Vec<Box<Filter>>,
// _t: PhantomData<(P, U1, U2)>,
// }
// impl<T, S: 'static, U1, U2> RouteServiceBuilder<T, S, U1, U2>
// where
// T: NewService<
// Request = HandlerRequest<S, U1>,
// Response = HandlerRequest<S, U2>,
// Error = Error,
// InitError = (),
// >,
// {
// pub fn new<F: IntoNewService<T>>(factory: F) -> Self {
// RouteServiceBuilder {
// service: factory.into_new_service(),
// filters: Vec::new(),
// _t: PhantomData,
// }
// }
// /// Add method match filter to the route.
// ///
// /// ```rust
// /// # extern crate actix_web;
// /// # use actix_web::*;
// /// # fn main() {
// /// App::new().resource("/path", |r| {
// /// r.route()
// /// .filter(pred::Get())
// /// .filter(pred::Header("content-type", "text/plain"))
// /// .f(|req| HttpResponse::Ok())
// /// })
// /// # .finish();
// /// # }
// /// ```
// pub fn method(mut self, method: Method) -> Self {
// self.filters.push(Box::new(filter::Method(method)));
// self
// }
// /// Add filter to the route.
// ///
// /// ```rust
// /// # extern crate actix_web;
// /// # use actix_web::*;
// /// # fn main() {
// /// App::new().resource("/path", |r| {
// /// r.route()
// /// .filter(pred::Get())
// /// .filter(pred::Header("content-type", "text/plain"))
// /// .f(|req| HttpResponse::Ok())
// /// })
// /// # .finish();
// /// # }
// /// ```
// pub fn filter<F: Filter<S> + 'static>(&mut self, f: F) -> &mut Self {
// self.filters.push(Box::new(f));
// self
// }
// pub fn map<T1, U3, F: IntoNewService<T1>>(
// self,
// md: F,
// ) -> RouteServiceBuilder<
// impl NewService<
// Request = HandlerRequest<S, U1>,
// Response = HandlerRequest<S, U3>,
// Error = Error,
// InitError = (),
// >,
// S,
// U1,
// U2,
// >
// where
// T1: NewService<
// Request = HandlerRequest<S, U2>,
// Response = HandlerRequest<S, U3>,
// InitError = (),
// >,
// T1::Error: Into<Error>,
// {
// RouteServiceBuilder {
// service: self
// .service
// .and_then(md.into_new_service().map_err(|e| e.into())),
// filters: self.filters,
// _t: PhantomData,
// }
// }
// pub fn to_async<F, P, R>(self, handler: F) -> Route<S>
// where
// F: AsyncFactory<S, U2, P, R>,
// P: FromRequest<S> + 'static,
// R: IntoFuture,
// R::Item: Into<Response>,
// R::Error: Into<Error>,
// {
// Route {
// service: self
// .service
// .and_then(Extract::new(P::Config::default()))
// .then(AsyncHandle::new(handler)),
// filters: Rc::new(self.filters),
// }
// }
// pub fn to<F, P, R>(self, handler: F) -> Route<S>
// where
// F: Factory<S, U2, P, R> + 'static,
// P: FromRequest<S> + 'static,
// R: Responder<S> + 'static,
// {
// Route {
// service: Box::new(RouteNewService::new(
// self.service
// .and_then(Extract::new(P::Config::default()))
// .and_then(Handle::new(handler)),
// )),
// filters: Rc::new(self.filters),
// }
// }
// }
struct RouteNewService<P, T> struct RouteNewService<P, T>
where where
T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceFromRequest<P>)>, T: NewService<Request = ServiceRequest<P>, Error = (Error, ServiceFromRequest<P>)>,