mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-24 16:02:59 +01:00
update api docs
This commit is contained in:
parent
e50d4c5e0e
commit
360082f99f
@ -245,8 +245,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure that follows the builder pattern for building application
|
/// Application router builder - Structure that follows the builder pattern
|
||||||
/// instances.
|
/// for building application instances.
|
||||||
pub struct AppRouter<C, P, B, T> {
|
pub struct AppRouter<C, P, B, T> {
|
||||||
chain: C,
|
chain: C,
|
||||||
services: Vec<(ResourceDef, HttpNewService<P>)>,
|
services: Vec<(ResourceDef, HttpNewService<P>)>,
|
||||||
|
168
src/extract.rs
168
src/extract.rs
@ -165,17 +165,63 @@ impl<T> From<T> for Path<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract typed information from the request's path.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_web::{web, http, App, extract::Path};
|
||||||
|
///
|
||||||
|
/// /// extract path info from "/{username}/{count}/index.html" url
|
||||||
|
/// /// {username} - deserializes to a String
|
||||||
|
/// /// {count} - - deserializes to a u32
|
||||||
|
/// fn index(info: Path<(String, u32)>) -> String {
|
||||||
|
/// format!("Welcome {}! {}", info.0, info.1)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource(
|
||||||
|
/// "/{username}/{count}/index.html", // <- define path parameters
|
||||||
|
/// |r| r.route(web::get().to(index)) // <- register handler with `Path` extractor
|
||||||
|
/// );
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// It is possible to extract path information to a specific type that
|
||||||
|
/// implements `Deserialize` trait from *serde*.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #[macro_use] extern crate serde_derive;
|
||||||
|
/// use actix_web::{web, App, extract::Path, Error};
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// struct Info {
|
||||||
|
/// username: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// extract `Info` from a path using serde
|
||||||
|
/// fn index(info: Path<Info>) -> Result<String, Error> {
|
||||||
|
/// Ok(format!("Welcome {}!", info.username))
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource(
|
||||||
|
/// "/{username}/index.html", // <- define path parameters
|
||||||
|
/// |r| r.route(web::get().to(index)) // <- use handler with Path` extractor
|
||||||
|
/// );
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
impl<T, P> FromRequest<P> for Path<T>
|
impl<T, P> FromRequest<P> for Path<T>
|
||||||
where
|
where
|
||||||
T: DeserializeOwned,
|
T: DeserializeOwned,
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = Result<Self, Error>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
Self::extract(req).map_err(ErrorNotFound).into_future()
|
Self::extract(req).map_err(ErrorNotFound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,17 +246,17 @@ impl<T: fmt::Display> fmt::Display for Path<T> {
|
|||||||
/// #[macro_use] extern crate serde_derive;
|
/// #[macro_use] extern crate serde_derive;
|
||||||
/// use actix_web::{web, extract, App};
|
/// use actix_web::{web, extract, App};
|
||||||
///
|
///
|
||||||
///#[derive(Debug, Deserialize)]
|
/// #[derive(Debug, Deserialize)]
|
||||||
///pub enum ResponseType {
|
/// pub enum ResponseType {
|
||||||
/// Token,
|
/// Token,
|
||||||
/// Code
|
/// Code
|
||||||
///}
|
/// }
|
||||||
///
|
///
|
||||||
///#[derive(Deserialize)]
|
/// #[derive(Deserialize)]
|
||||||
///pub struct AuthRequest {
|
/// pub struct AuthRequest {
|
||||||
/// id: u64,
|
/// id: u64,
|
||||||
/// response_type: ResponseType,
|
/// response_type: ResponseType,
|
||||||
///}
|
/// }
|
||||||
///
|
///
|
||||||
/// // Use `Query` extractor for query information.
|
/// // Use `Query` extractor for query information.
|
||||||
/// // This handler get called only if request's query contains `username` field
|
/// // This handler get called only if request's query contains `username` field
|
||||||
@ -248,19 +294,52 @@ impl<T> Query<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract typed information from from the request's query.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #[macro_use] extern crate serde_derive;
|
||||||
|
/// use actix_web::{web, extract, App};
|
||||||
|
///
|
||||||
|
/// #[derive(Debug, Deserialize)]
|
||||||
|
/// pub enum ResponseType {
|
||||||
|
/// Token,
|
||||||
|
/// Code
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// pub struct AuthRequest {
|
||||||
|
/// id: u64,
|
||||||
|
/// response_type: ResponseType,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Use `Query` extractor for query information.
|
||||||
|
/// // This handler get called only if request's query contains `username` field
|
||||||
|
/// // The correct request for this handler would be `/index.html?id=64&response_type=Code"`
|
||||||
|
/// fn index(info: extract::Query<AuthRequest>) -> String {
|
||||||
|
/// format!("Authorization request for client with id={} and type={:?}!", info.id, info.response_type)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource(
|
||||||
|
/// "/index.html",
|
||||||
|
/// |r| r.route(web::get().to(index))); // <- use `Query` extractor
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
impl<T, P> FromRequest<P> for Query<T>
|
impl<T, P> FromRequest<P> for Query<T>
|
||||||
where
|
where
|
||||||
T: de::DeserializeOwned,
|
T: de::DeserializeOwned,
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = Result<Self, Error>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
serde_urlencoded::from_str::<T>(req.query_string())
|
serde_urlencoded::from_str::<T>(req.query_string())
|
||||||
.map(|val| ok(Query(val)))
|
.map(|val| Ok(Query(val)))
|
||||||
.unwrap_or_else(|e| err(e.into()))
|
.unwrap_or_else(|e| Err(e.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +361,7 @@ impl<T: fmt::Display> fmt::Display for Query<T> {
|
|||||||
/// To extract typed information from request's body, the type `T` must
|
/// To extract typed information from request's body, the type `T` must
|
||||||
/// implement the `Deserialize` trait from *serde*.
|
/// implement the `Deserialize` trait from *serde*.
|
||||||
///
|
///
|
||||||
/// [**FormConfig**](dev/struct.FormConfig.html) allows to configure extraction
|
/// [**FormConfig**](struct.FormConfig.html) allows to configure extraction
|
||||||
/// process.
|
/// process.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
@ -436,7 +515,7 @@ impl Default for FormConfig {
|
|||||||
/// To extract typed information from request's body, the type `T` must
|
/// To extract typed information from request's body, the type `T` must
|
||||||
/// implement the `Deserialize` trait from *serde*.
|
/// implement the `Deserialize` trait from *serde*.
|
||||||
///
|
///
|
||||||
/// [**JsonConfig**](dev/struct.JsonConfig.html) allows to configure extraction
|
/// [**JsonConfig**](struct.JsonConfig.html) allows to configure extraction
|
||||||
/// process.
|
/// process.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
@ -526,20 +605,51 @@ where
|
|||||||
|
|
||||||
impl<T: Serialize> Responder for Json<T> {
|
impl<T: Serialize> Responder for Json<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<Response, Error>;
|
type Future = Result<Response, Error>;
|
||||||
|
|
||||||
fn respond_to(self, _: &HttpRequest) -> Self::Future {
|
fn respond_to(self, _: &HttpRequest) -> Self::Future {
|
||||||
let body = match serde_json::to_string(&self.0) {
|
let body = match serde_json::to_string(&self.0) {
|
||||||
Ok(body) => body,
|
Ok(body) => body,
|
||||||
Err(e) => return err(e.into()),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
ok(Response::build(StatusCode::OK)
|
Ok(Response::build(StatusCode::OK)
|
||||||
.content_type("application/json")
|
.content_type("application/json")
|
||||||
.body(body))
|
.body(body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Json extractor. Allow to extract typed information from request's
|
||||||
|
/// payload.
|
||||||
|
///
|
||||||
|
/// To extract typed information from request's body, the type `T` must
|
||||||
|
/// implement the `Deserialize` trait from *serde*.
|
||||||
|
///
|
||||||
|
/// [**JsonConfig**](struct.JsonConfig.html) allows to configure extraction
|
||||||
|
/// process.
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// #[macro_use] extern crate serde_derive;
|
||||||
|
/// use actix_web::{web, extract, App};
|
||||||
|
///
|
||||||
|
/// #[derive(Deserialize)]
|
||||||
|
/// struct Info {
|
||||||
|
/// username: String,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// /// deserialize `Info` from request's body
|
||||||
|
/// fn index(info: extract::Json<Info>) -> String {
|
||||||
|
/// format!("Welcome {}!", info.username)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource(
|
||||||
|
/// "/index.html",
|
||||||
|
/// |r| r.route(web::post().to(index)));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
impl<T, P> FromRequest<P> for Json<T>
|
impl<T, P> FromRequest<P> for Json<T>
|
||||||
where
|
where
|
||||||
T: DeserializeOwned + 'static,
|
T: DeserializeOwned + 'static,
|
||||||
@ -632,7 +742,7 @@ impl Default for JsonConfig {
|
|||||||
///
|
///
|
||||||
/// Loads request's payload and construct Bytes instance.
|
/// Loads request's payload and construct Bytes instance.
|
||||||
///
|
///
|
||||||
/// [**PayloadConfig**](dev/struct.PayloadConfig.html) allows to configure
|
/// [**PayloadConfig**](struct.PayloadConfig.html) allows to configure
|
||||||
/// extraction process.
|
/// extraction process.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
@ -677,7 +787,7 @@ where
|
|||||||
///
|
///
|
||||||
/// Text extractor automatically decode body according to the request's charset.
|
/// Text extractor automatically decode body according to the request's charset.
|
||||||
///
|
///
|
||||||
/// [**PayloadConfig**](dev/struct.PayloadConfig.html) allows to configure
|
/// [**PayloadConfig**](struct.PayloadConfig.html) allows to configure
|
||||||
/// extraction process.
|
/// extraction process.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
@ -931,6 +1041,17 @@ impl Default for PayloadConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
impl<P> FromRequest<P> for () {
|
||||||
|
type Error = Error;
|
||||||
|
type Future = FutureResult<(), Error>;
|
||||||
|
type Config = ();
|
||||||
|
|
||||||
|
fn from_request(_req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
|
ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! tuple_config ({ $($T:ident),+} => {
|
macro_rules! tuple_config ({ $($T:ident),+} => {
|
||||||
impl<$($T,)+> ExtractorConfig for ($($T,)+)
|
impl<$($T,)+> ExtractorConfig for ($($T,)+)
|
||||||
where $($T: ExtractorConfig + Clone,)+
|
where $($T: ExtractorConfig + Clone,)+
|
||||||
@ -944,6 +1065,7 @@ macro_rules! tuple_config ({ $($T:ident),+} => {
|
|||||||
macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
||||||
|
|
||||||
/// FromRequest implementation for tuple
|
/// FromRequest implementation for tuple
|
||||||
|
#[doc(hidden)]
|
||||||
impl<P, $($T: FromRequest<P> + 'static),+> FromRequest<P> for ($($T,)+)
|
impl<P, $($T: FromRequest<P> + 'static),+> FromRequest<P> for ($($T,)+)
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
@ -995,16 +1117,6 @@ macro_rules! tuple_from_req ({$fut_type:ident, $(($n:tt, $T:ident)),+} => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
impl<P> FromRequest<P> for () {
|
|
||||||
type Error = Error;
|
|
||||||
type Future = FutureResult<(), Error>;
|
|
||||||
type Config = ();
|
|
||||||
|
|
||||||
fn from_request(_req: &mut ServiceFromRequest<P>) -> Self::Future {
|
|
||||||
ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
mod m {
|
mod m {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
11
src/lib.rs
11
src/lib.rs
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
pub mod extract;
|
pub mod extract;
|
||||||
pub mod handler;
|
mod handler;
|
||||||
// mod info;
|
// mod info;
|
||||||
pub mod blocking;
|
pub mod blocking;
|
||||||
pub mod guard;
|
pub mod guard;
|
||||||
@ -19,7 +19,7 @@ pub mod test;
|
|||||||
pub use actix_http::Response as HttpResponse;
|
pub use actix_http::Response as HttpResponse;
|
||||||
pub use actix_http::{error, http, Error, HttpMessage, ResponseError, Result};
|
pub use actix_http::{error, http, Error, HttpMessage, ResponseError, Result};
|
||||||
|
|
||||||
pub use crate::app::App;
|
pub use crate::app::{App, AppRouter};
|
||||||
pub use crate::extract::{FromRequest, Json};
|
pub use crate::extract::{FromRequest, Json};
|
||||||
pub use crate::request::HttpRequest;
|
pub use crate::request::HttpRequest;
|
||||||
pub use crate::resource::Resource;
|
pub use crate::resource::Resource;
|
||||||
@ -37,30 +37,37 @@ pub mod web {
|
|||||||
use crate::responder::Responder;
|
use crate::responder::Responder;
|
||||||
use crate::Route;
|
use crate::Route;
|
||||||
|
|
||||||
|
/// Create **route** without configuration.
|
||||||
pub fn route<P: 'static>() -> Route<P> {
|
pub fn route<P: 'static>() -> Route<P> {
|
||||||
Route::new()
|
Route::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** with `GET` method guard.
|
||||||
pub fn get<P: 'static>() -> Route<P> {
|
pub fn get<P: 'static>() -> Route<P> {
|
||||||
Route::get()
|
Route::get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** with `POST` method guard.
|
||||||
pub fn post<P: 'static>() -> Route<P> {
|
pub fn post<P: 'static>() -> Route<P> {
|
||||||
Route::post()
|
Route::post()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** with `PUT` method guard.
|
||||||
pub fn put<P: 'static>() -> Route<P> {
|
pub fn put<P: 'static>() -> Route<P> {
|
||||||
Route::put()
|
Route::put()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** with `DELETE` method guard.
|
||||||
pub fn delete<P: 'static>() -> Route<P> {
|
pub fn delete<P: 'static>() -> Route<P> {
|
||||||
Route::delete()
|
Route::delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** with `HEAD` method guard.
|
||||||
pub fn head<P: 'static>() -> Route<P> {
|
pub fn head<P: 'static>() -> Route<P> {
|
||||||
Route::new().method(Method::HEAD)
|
Route::new().method(Method::HEAD)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create **route** and add method guard.
|
||||||
pub fn method<P: 'static>(method: Method) -> Route<P> {
|
pub fn method<P: 'static>(method: Method) -> Route<P> {
|
||||||
Route::new().method(method)
|
Route::new().method(method)
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@ use std::rc::Rc;
|
|||||||
use actix_http::http::{HeaderMap, Method, Uri, Version};
|
use actix_http::http::{HeaderMap, Method, Uri, Version};
|
||||||
use actix_http::{Error, Extensions, HttpMessage, Message, Payload, RequestHead};
|
use actix_http::{Error, Extensions, HttpMessage, Message, Payload, RequestHead};
|
||||||
use actix_router::{Path, Url};
|
use actix_router::{Path, Url};
|
||||||
use futures::future::{ok, FutureResult};
|
|
||||||
|
|
||||||
use crate::extract::FromRequest;
|
use crate::extract::FromRequest;
|
||||||
use crate::service::ServiceFromRequest;
|
use crate::service::ServiceFromRequest;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
/// An HTTP Request
|
||||||
pub struct HttpRequest {
|
pub struct HttpRequest {
|
||||||
pub(crate) head: Message<RequestHead>,
|
pub(crate) head: Message<RequestHead>,
|
||||||
pub(crate) path: Path<Url>,
|
pub(crate) path: Path<Url>,
|
||||||
@ -20,7 +20,7 @@ pub struct HttpRequest {
|
|||||||
|
|
||||||
impl HttpRequest {
|
impl HttpRequest {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub(crate) fn new(
|
||||||
head: Message<RequestHead>,
|
head: Message<RequestHead>,
|
||||||
path: Path<Url>,
|
path: Path<Url>,
|
||||||
extensions: Rc<Extensions>,
|
extensions: Rc<Extensions>,
|
||||||
@ -140,14 +140,33 @@ impl HttpMessage for HttpRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// It is possible to get `HttpRequest` as an extractor handler parameter
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #[macro_use] extern crate serde_derive;
|
||||||
|
/// use actix_web::{web, App, HttpRequest};
|
||||||
|
///
|
||||||
|
/// /// extract `Thing` from request
|
||||||
|
/// fn index(req: HttpRequest) -> String {
|
||||||
|
/// format!("Got thing: {:?}", req)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new().resource("/users/:first", |r| {
|
||||||
|
/// r.route(web::get().to(index))
|
||||||
|
/// });
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
impl<P> FromRequest<P> for HttpRequest {
|
impl<P> FromRequest<P> for HttpRequest {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = Result<Self, Error>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
ok(req.clone())
|
Ok(req.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,24 @@ use crate::service::{ServiceRequest, ServiceResponse};
|
|||||||
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, ()>;
|
||||||
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
type HttpNewService<P> = BoxedNewService<(), ServiceRequest<P>, ServiceResponse, (), ()>;
|
||||||
|
|
||||||
/// Resource route definition
|
/// *Resource* is an entry in route table which corresponds to requested URL.
|
||||||
///
|
///
|
||||||
/// Route uses builder-like pattern for configuration.
|
/// Resource in turn has at least one route.
|
||||||
/// If handler is not explicitly set, default *404 Not Found* handler is used.
|
/// Route consists of an handlers objects and list of guards
|
||||||
|
/// (objects that implement `Guard` trait).
|
||||||
|
/// Resources and rouets uses builder-like pattern for configuration.
|
||||||
|
/// During request handling, resource object iterate through all routes
|
||||||
|
/// and check guards for specific route, if request matches all
|
||||||
|
/// guards, route considered matched and route handler get called.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_web::{web, App, HttpResponse};
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new()
|
||||||
|
/// .resource(
|
||||||
|
/// "/", |r| r.route(web::get().to(|| HttpResponse::Ok())));
|
||||||
|
/// }
|
||||||
pub struct Resource<P, T = ResourceEndpoint<P>> {
|
pub struct Resource<P, T = ResourceEndpoint<P>> {
|
||||||
routes: Vec<Route<P>>,
|
routes: Vec<Route<P>>,
|
||||||
endpoint: T,
|
endpoint: T,
|
||||||
@ -58,8 +72,6 @@ where
|
|||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
/// Register a new route.
|
/// Register a new route.
|
||||||
/// *Route* is used for route configuration, i.e. adding guards,
|
|
||||||
/// setting up handler.
|
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_web::{web, guard, App, HttpResponse};
|
/// use actix_web::{web, guard, App, HttpResponse};
|
||||||
@ -74,12 +86,31 @@ where
|
|||||||
/// });
|
/// });
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// Multiple routes could be added to a resource.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use actix_web::{web, guard, App, HttpResponse};
|
||||||
|
///
|
||||||
|
/// fn main() {
|
||||||
|
/// let app = App::new()
|
||||||
|
/// .resource("/container/", |r| {
|
||||||
|
/// r.route(web::get().to(get_handler))
|
||||||
|
/// .route(web::post().to(post_handler))
|
||||||
|
/// .route(web::delete().to(delete_handler))
|
||||||
|
/// });
|
||||||
|
/// }
|
||||||
|
/// # fn get_handler() {}
|
||||||
|
/// # fn post_handler() {}
|
||||||
|
/// # fn delete_handler() {}
|
||||||
|
/// ```
|
||||||
pub fn route(mut self, route: Route<P>) -> Self {
|
pub fn route(mut self, route: Route<P>) -> Self {
|
||||||
self.routes.push(route.finish());
|
self.routes.push(route.finish());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Register a new route and add handler.
|
/// Register a new route and add handler. This route get called for all
|
||||||
|
/// requests.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use actix_web::*;
|
/// use actix_web::*;
|
||||||
@ -148,7 +179,8 @@ where
|
|||||||
/// Register a resource middleware
|
/// Register a resource middleware
|
||||||
///
|
///
|
||||||
/// This is similar to `App's` middlewares, but
|
/// This is similar to `App's` middlewares, but
|
||||||
/// middlewares get invoked on resource level.
|
/// middleware is not allowed to change response type (i.e modify response's body).
|
||||||
|
/// Middleware get invoked on resource level.
|
||||||
pub fn middleware<M, F>(
|
pub fn middleware<M, F>(
|
||||||
self,
|
self,
|
||||||
mw: F,
|
mw: F,
|
||||||
|
48
src/state.rs
48
src/state.rs
@ -3,7 +3,6 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use actix_http::error::{Error, ErrorInternalServerError};
|
use actix_http::error::{Error, ErrorInternalServerError};
|
||||||
use actix_http::Extensions;
|
use actix_http::Extensions;
|
||||||
use futures::future::{err, ok, FutureResult};
|
|
||||||
use futures::{Async, Future, IntoFuture, Poll};
|
use futures::{Async, Future, IntoFuture, Poll};
|
||||||
|
|
||||||
use crate::extract::FromRequest;
|
use crate::extract::FromRequest;
|
||||||
@ -19,60 +18,61 @@ pub(crate) trait StateFactoryResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Application state
|
/// Application state
|
||||||
pub struct State<S>(Rc<S>);
|
pub struct State<T>(Rc<T>);
|
||||||
|
|
||||||
impl<S> State<S> {
|
impl<T> State<T> {
|
||||||
pub fn new(state: S) -> State<S> {
|
pub(crate) fn new(state: T) -> State<T> {
|
||||||
State(Rc::new(state))
|
State(Rc::new(state))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ref(&self) -> &S {
|
/// Get referecnce to inner state type.
|
||||||
|
pub fn get_ref(&self) -> &T {
|
||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Deref for State<S> {
|
impl<T> Deref for State<T> {
|
||||||
type Target = S;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &S {
|
fn deref(&self) -> &T {
|
||||||
self.0.as_ref()
|
self.0.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> Clone for State<S> {
|
impl<T> Clone for State<T> {
|
||||||
fn clone(&self) -> State<S> {
|
fn clone(&self) -> State<T> {
|
||||||
State(self.0.clone())
|
State(self.0.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static, P> FromRequest<P> for State<S> {
|
impl<T: 'static, P> FromRequest<P> for State<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Future = FutureResult<Self, Error>;
|
type Future = Result<Self, Error>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
|
||||||
if let Some(st) = req.app_extensions().get::<State<S>>() {
|
if let Some(st) = req.app_extensions().get::<State<T>>() {
|
||||||
ok(st.clone())
|
Ok(st.clone())
|
||||||
} else {
|
} else {
|
||||||
err(ErrorInternalServerError(
|
Err(ErrorInternalServerError(
|
||||||
"State is not configured, use App::state()",
|
"State is not configured, to configure use App::state()",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static> StateFactory for State<S> {
|
impl<T: 'static> StateFactory for State<T> {
|
||||||
fn construct(&self) -> Box<StateFactoryResult> {
|
fn construct(&self) -> Box<StateFactoryResult> {
|
||||||
Box::new(StateFut { st: self.clone() })
|
Box::new(StateFut { st: self.clone() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StateFut<S> {
|
struct StateFut<T> {
|
||||||
st: State<S>,
|
st: State<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static> StateFactoryResult for StateFut<S> {
|
impl<T: 'static> StateFactoryResult for StateFut<T> {
|
||||||
fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
|
fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
|
||||||
extensions.insert(self.st.clone());
|
extensions.insert(self.st.clone());
|
||||||
Ok(Async::Ready(()))
|
Ok(Async::Ready(()))
|
||||||
@ -92,17 +92,17 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StateFactoryFut<S, F>
|
struct StateFactoryFut<T, F>
|
||||||
where
|
where
|
||||||
F: Future<Item = S>,
|
F: Future<Item = T>,
|
||||||
F::Error: std::fmt::Debug,
|
F::Error: std::fmt::Debug,
|
||||||
{
|
{
|
||||||
fut: F,
|
fut: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: 'static, F> StateFactoryResult for StateFactoryFut<S, F>
|
impl<T: 'static, F> StateFactoryResult for StateFactoryFut<T, F>
|
||||||
where
|
where
|
||||||
F: Future<Item = S>,
|
F: Future<Item = T>,
|
||||||
F::Error: std::fmt::Debug,
|
F::Error: std::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
|
fn poll_result(&mut self, extensions: &mut Extensions) -> Poll<(), ()> {
|
||||||
|
Loading…
Reference in New Issue
Block a user