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

add Item and Error to FromRequest trait

This commit is contained in:
Nikolay Kim 2017-12-03 14:22:04 -08:00
parent 6bc7d60f52
commit 7c6faaa8e0
14 changed files with 178 additions and 108 deletions

View File

@ -109,7 +109,7 @@ fn main() {
Application::default("/") Application::default("/")
.middleware(middlewares::Logger::default()) // <- register logger middleware .middleware(middlewares::Logger::default()) // <- register logger middleware
.resource("/ws/", |r| r.get(|req| ws::start(req, MyWebSocket))) // <- websocket route .resource("/ws/", |r| r.get(|req| ws::start(req, MyWebSocket))) // <- websocket route
.route("/", StaticFiles::new("examples/static/", true))) // <- server static files .route("/", fs::StaticFiles::new("examples/static/", true))) // <- serve static files
.serve::<_, ()>("127.0.0.1:8080").unwrap(); .serve::<_, ()>("127.0.0.1:8080").unwrap();
Arbiter::system().send(msgs::SystemExit(0)); Arbiter::system().send(msgs::SystemExit(0));

View File

@ -12,8 +12,18 @@ fn main() {
// generates doc tests for `README.md`. // generates doc tests for `README.md`.
skeptic::generate_doc_tests( skeptic::generate_doc_tests(
&["README.md", &["README.md",
"guide/src/qs_1.md",
"guide/src/qs_2.md", "guide/src/qs_2.md",
"guide/src/qs_3.md", "guide/src/qs_3.md",
"guide/src/qs_4.md",
"guide/src/qs_5.md",
"guide/src/qs_6.md",
"guide/src/qs_7.md",
"guide/src/qs_9.md",
"guide/src/qs_10.md",
"guide/src/qs_11.md",
"guide/src/qs_12.md",
"guide/src/qs_13.md",
]); ]);
} else { } else {
let _ = fs::File::create(f); let _ = fs::File::create(f);

View File

@ -89,7 +89,7 @@ fn main() {
} }
}) })
// static files // static files
.route("/static", StaticFiles::new("examples/static/", true))) .route("/static", fs::StaticFiles::new("examples/static/", true)))
.serve::<_, ()>("127.0.0.1:8080").unwrap(); .serve::<_, ()>("127.0.0.1:8080").unwrap();
println!("Started http server: 127.0.0.1:8080"); println!("Started http server: 127.0.0.1:8080");

View File

@ -208,7 +208,7 @@ fn main() {
// websocket // websocket
.resource("/ws/", |r| r.get(chat_route)) .resource("/ws/", |r| r.get(chat_route))
// static resources // static resources
.route("/static", StaticFiles::new("static/", true))) .route("/static", fs::StaticFiles::new("static/", true)))
.serve::<_, ()>("127.0.0.1:8080").unwrap(); .serve::<_, ()>("127.0.0.1:8080").unwrap();
let _ = sys.run(); let _ = sys.run();

View File

@ -67,7 +67,7 @@ fn main() {
// websocket route // websocket route
.resource("/ws/", |r| r.get(ws_index)) .resource("/ws/", |r| r.get(ws_index))
// static files // static files
.route("/", StaticFiles::new("examples/static/", true))) .route("/", fs::StaticFiles::new("examples/static/", true)))
// start http server on 127.0.0.1:8080 // start http server on 127.0.0.1:8080
.serve::<_, ()>("127.0.0.1:8080").unwrap(); .serve::<_, ()>("127.0.0.1:8080").unwrap();

View File

@ -6,14 +6,14 @@ A request handler can by any object that implements
By default actix provdes several `Handler` implementations: By default actix provdes several `Handler` implementations:
* Simple function that accepts `HttpRequest` and returns any object that * Simple function that accepts `HttpRequest` and returns any object that
can be converted to `HttpResponse` implements `FromRequest` trait
* Function that accepts `HttpRequest` and returns `Result<Reply, Into<Error>>` object. * Function that accepts `HttpRequest` and returns `Result<Reply, Into<Error>>` object.
* Function that accepts `HttpRequest` and return actor that has `HttpContext<A>`as a context. * Function that accepts `HttpRequest` and return actor that has `HttpContext<A>`as a context.
Actix provides response conversion into `HttpResponse` for some standard types, Actix provides response `FromRequest` implementation for some standard types,
like `&'static str`, `String`, etc. like `&'static str`, `String`, etc.
For complete list of implementations check For complete list of implementations check
[HttpResponse documentation](../actix_web/struct.HttpResponse.html#implementations). [FromRequest documentation](../actix_web/trait.FromRequest.html#foreign-impls).
Examples: Examples:
@ -58,19 +58,18 @@ struct MyObj {
name: String, name: String,
} }
/// we have to convert Error into HttpResponse as well, but with /// we have to convert Error into HttpResponse as well
/// specialization this could be handled genericly. impl FromRequest for MyObj {
impl Into<HttpResponse> for MyObj { type Item = HttpResponse;
fn into(self) -> HttpResponse { type Error = Error;
let body = match serde_json::to_string(&self) {
Err(err) => return Error::from(err).into(), fn from_request(self, req: HttpRequest) -> Result<HttpResponse> {
Ok(body) => body, let body = serde_json::to_string(&self)?;
};
// Create response and set content type // Create response and set content type
HttpResponse::Ok() Ok(HttpResponse::Ok()
.content_type("application/json") .content_type("application/json")
.body(body).unwrap() .body(body)?)
} }
} }
@ -90,20 +89,6 @@ fn main() {
} }
``` ```
If `specialization` is enabled, conversion could be simplier:
```rust,ignore
impl Into<Result<HttpResponse>> for MyObj {
fn into(self) -> Result<HttpResponse> {
let body = serde_json::to_string(&self)?;
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(body)?)
}
}
```
## Async handlers ## Async handlers
There are two different types of async handlers. There are two different types of async handlers.

View File

@ -65,11 +65,11 @@ used later in a request handler to access the matched value for that part. This
done by looking up the identifier in the `HttpRequest.match_info` object: done by looking up the identifier in the `HttpRequest.match_info` object:
```rust ```rust
extern crate actix; extern crate actix_web;
use actix_web::*; use actix_web::*;
fn index(req: Httprequest) -> String { fn index(req: HttpRequest) -> String {
format!("Hello, {}", req.match_info["name"]) format!("Hello, {}", &req.match_info()["name"])
} }
fn main() { fn main() {
@ -96,13 +96,13 @@ implements `FromParam` trait. For example most of standard integer types
implements `FromParam` trait. i.e.: implements `FromParam` trait. i.e.:
```rust ```rust
extern crate actix; extern crate actix_web;
use actix_web::*; use actix_web::*;
fn index(req: Httprequest) -> String { fn index(req: HttpRequest) -> Result<String> {
let v1: u8 = req.match_info().query("v1")?; let v1: u8 = req.match_info().query("v1")?;
let v2: u8 = req.match_info().query("v2")?; let v2: u8 = req.match_info().query("v2")?;
format!("Values {} {}", v1, v2) Ok(format!("Values {} {}", v1, v2))
} }
fn main() { fn main() {
@ -146,18 +146,18 @@ safe to interpolate within, or use as a suffix of, a path without additional
checks. checks.
```rust ```rust
extern crate actix; extern crate actix_web;
use actix_web::*; use actix_web::*;
use std::path::PathBuf; use std::path::PathBuf;
fn index(req: Httprequest) -> String { fn index(req: HttpRequest) -> Result<String> {
let path: PathBuf = req.match_info().query("tail")?; let path: PathBuf = req.match_info().query("tail")?;
format!("Path {:?}", path) Ok(format!("Path {:?}", path))
} }
fn main() { fn main() {
Application::default("/") Application::default("/")
.resource(r"/a/{tail:**}", |r| r.get(index)) .resource(r"/a/{tail:*}", |r| r.get(index))
.finish(); .finish();
} }
``` ```

View File

@ -9,8 +9,8 @@
//! ``` //! ```
// dev specific // dev specific
pub use route::Handler;
pub use pipeline::Pipeline; pub use pipeline::Pipeline;
pub use route::{Handler, FromRequest};
pub use channel::{HttpChannel, HttpHandler}; pub use channel::{HttpChannel, HttpHandler};
pub use recognizer::{FromParam, RouteRecognizer}; pub use recognizer::{FromParam, RouteRecognizer};

View File

@ -31,7 +31,7 @@ use httpcodes::{HTTPBadRequest, HTTPMethodNotAllowed, HTTPExpectationFailed};
pub type Result<T> = result::Result<T, Error>; pub type Result<T> = result::Result<T, Error>;
/// General purpose actix web error /// General purpose actix web error
#[derive(Debug)] #[derive(Fail, Debug)]
pub struct Error { pub struct Error {
cause: Box<ResponseError>, cause: Box<ResponseError>,
} }

View File

@ -1,6 +1,6 @@
//! Static files support. //! Static files support.
//!
//! TODO: needs to re-implement actual files handling, current impl blocks // //! TODO: needs to re-implement actual files handling, current impl blocks
use std::io; use std::io;
use std::io::Read; use std::io::Read;
use std::fmt::Write; use std::fmt::Write;
@ -19,11 +19,10 @@ use httpcodes::{HTTPOk, HTTPNotFound};
/// ///
/// ```rust /// ```rust
/// extern crate actix_web; /// extern crate actix_web;
/// use actix_web::*;
/// ///
/// fn main() { /// fn main() {
/// let app = Application::default("/") /// let app = actix_web::Application::default("/")
/// .route("/static", StaticFiles::new(".", true)) /// .route("/static", actix_web::fs::StaticFiles::new(".", true))
/// .finish(); /// .finish();
/// } /// }
/// ``` /// ```
@ -39,6 +38,7 @@ impl StaticFiles {
/// Create new `StaticFiles` instance /// Create new `StaticFiles` instance
/// ///
/// `dir` - base directory /// `dir` - base directory
///
/// `index` - show index for directory /// `index` - show index for directory
pub fn new<D: Into<PathBuf>>(dir: D, index: bool) -> StaticFiles { pub fn new<D: Into<PathBuf>>(dir: D, index: bool) -> StaticFiles {
let dir = dir.into(); let dir = dir.into();

View File

@ -1,6 +1,6 @@
//! Basic http responses //! Basic http responses
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
use http::StatusCode; use http::{StatusCode, Error as HttpError};
use body::Body; use body::Body;
use route::{Reply, RouteHandler, FromRequest}; use route::{Reply, RouteHandler, FromRequest};
@ -74,8 +74,11 @@ impl<S> RouteHandler<S> for StaticResponse {
} }
impl FromRequest for StaticResponse { impl FromRequest for StaticResponse {
fn from_request(self, _: HttpRequest) -> Reply { type Item = HttpResponse;
Reply::response(HttpResponse::new(self.0, Body::Empty)) type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
self.build().body(Body::Empty)
} }
} }

View File

@ -8,11 +8,10 @@ use http::{StatusCode, Version, HeaderMap, HttpTryFrom, Error as HttpError};
use http::header::{self, HeaderName, HeaderValue}; use http::header::{self, HeaderName, HeaderValue};
use serde_json; use serde_json;
use serde::Serialize; use serde::Serialize;
use Cookie; use Cookie;
use body::Body; use body::Body;
use error::Error; use error::Error;
use route::{Reply, FromRequest}; use route::FromRequest;
use encoding::ContentEncoding; use encoding::ContentEncoding;
use httprequest::HttpRequest; use httprequest::HttpRequest;
@ -461,8 +460,11 @@ impl From<HttpResponseBuilder> for HttpResponse {
} }
impl FromRequest for HttpResponseBuilder { impl FromRequest for HttpResponseBuilder {
fn from_request(self, _: HttpRequest) -> Reply { type Item = HttpResponse;
Reply::response(self) type Error = HttpError;
fn from_request(mut self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
self.finish()
} }
} }
@ -476,11 +478,13 @@ impl From<&'static str> for HttpResponse {
} }
impl FromRequest for &'static str { impl FromRequest for &'static str {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8") .content_type("text/plain; charset=utf-8")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -494,11 +498,13 @@ impl From<&'static [u8]> for HttpResponse {
} }
impl FromRequest for &'static [u8] { impl FromRequest for &'static [u8] {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("application/octet-stream") .content_type("application/octet-stream")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -512,11 +518,13 @@ impl From<String> for HttpResponse {
} }
impl FromRequest for String { impl FromRequest for String {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8") .content_type("text/plain; charset=utf-8")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -530,11 +538,13 @@ impl<'a> From<&'a String> for HttpResponse {
} }
impl<'a> FromRequest for &'a String { impl<'a> FromRequest for &'a String {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8") .content_type("text/plain; charset=utf-8")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -548,11 +558,13 @@ impl From<Bytes> for HttpResponse {
} }
impl FromRequest for Bytes { impl FromRequest for Bytes {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("application/octet-stream") .content_type("application/octet-stream")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -566,11 +578,13 @@ impl From<BytesMut> for HttpResponse {
} }
impl FromRequest for BytesMut { impl FromRequest for BytesMut {
fn from_request(self, req: HttpRequest) -> Reply { type Item = HttpResponse;
type Error = HttpError;
fn from_request(self, _: HttpRequest) -> Result<HttpResponse, HttpError> {
HttpResponse::build(StatusCode::OK) HttpResponse::build(StatusCode::OK)
.content_type("application/octet-stream") .content_type("application/octet-stream")
.body(self) .body(self)
.from_request(req)
} }
} }
@ -650,6 +664,8 @@ mod tests {
#[test] #[test]
fn test_into_response() { fn test_into_response() {
let req = HttpRequest::default();
let resp: HttpResponse = "test".into(); let resp: HttpResponse = "test".into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
@ -657,6 +673,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test")); assert_eq!(resp.body().binary().unwrap(), &Binary::from("test"));
let resp: HttpResponse = "test".from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("text/plain; charset=utf-8"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test"));
let resp: HttpResponse = b"test".as_ref().into(); let resp: HttpResponse = b"test".as_ref().into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
@ -664,6 +687,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(b"test".as_ref())); assert_eq!(resp.body().binary().unwrap(), &Binary::from(b"test".as_ref()));
let resp: HttpResponse = b"test".as_ref().from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("application/octet-stream"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(b"test".as_ref()));
let resp: HttpResponse = "test".to_owned().into(); let resp: HttpResponse = "test".to_owned().into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
@ -671,6 +701,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test".to_owned())); assert_eq!(resp.body().binary().unwrap(), &Binary::from("test".to_owned()));
let resp: HttpResponse = "test".to_owned().from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("text/plain; charset=utf-8"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from("test".to_owned()));
let resp: HttpResponse = (&"test".to_owned()).into(); let resp: HttpResponse = (&"test".to_owned()).into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(), assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
@ -678,6 +715,13 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from((&"test".to_owned()))); assert_eq!(resp.body().binary().unwrap(), &Binary::from((&"test".to_owned())));
let resp: HttpResponse = (&"test".to_owned()).from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("text/plain; charset=utf-8"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from((&"test".to_owned())));
let b = Bytes::from_static(b"test"); let b = Bytes::from_static(b"test");
let resp: HttpResponse = b.into(); let resp: HttpResponse = b.into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
@ -686,6 +730,14 @@ mod tests {
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(Bytes::from_static(b"test"))); assert_eq!(resp.body().binary().unwrap(), &Binary::from(Bytes::from_static(b"test")));
let b = Bytes::from_static(b"test");
let resp: HttpResponse = b.from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("application/octet-stream"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(Bytes::from_static(b"test")));
let b = BytesMut::from("test"); let b = BytesMut::from("test");
let resp: HttpResponse = b.into(); let resp: HttpResponse = b.into();
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
@ -693,5 +745,13 @@ mod tests {
header::HeaderValue::from_static("application/octet-stream")); header::HeaderValue::from_static("application/octet-stream"));
assert_eq!(resp.status(), StatusCode::OK); assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(BytesMut::from("test"))); assert_eq!(resp.body().binary().unwrap(), &Binary::from(BytesMut::from("test")));
let b = BytesMut::from("test");
let resp: HttpResponse = b.from_request(req.clone()).ok().unwrap();
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.headers().get(header::CONTENT_TYPE).unwrap(),
header::HeaderValue::from_static("application/octet-stream"));
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(resp.body().binary().unwrap(), &Binary::from(BytesMut::from("test")));
} }
} }

View File

@ -58,7 +58,6 @@ mod resource;
mod recognizer; mod recognizer;
mod route; mod route;
mod pipeline; mod pipeline;
mod fs;
mod server; mod server;
mod channel; mod channel;
mod wsframe; mod wsframe;
@ -68,6 +67,7 @@ mod h2;
mod h1writer; mod h1writer;
mod h2writer; mod h2writer;
pub mod fs;
pub mod ws; pub mod ws;
pub mod dev; pub mod dev;
pub mod error; pub mod error;
@ -81,12 +81,11 @@ pub use application::Application;
pub use httprequest::{HttpRequest, UrlEncoded}; pub use httprequest::{HttpRequest, UrlEncoded};
pub use httpresponse::HttpResponse; pub use httpresponse::HttpResponse;
pub use payload::{Payload, PayloadItem}; pub use payload::{Payload, PayloadItem};
pub use route::Reply; pub use route::{Reply, FromRequest};
pub use resource::Resource; pub use resource::Resource;
pub use recognizer::Params; pub use recognizer::Params;
pub use server::HttpServer; pub use server::HttpServer;
pub use context::HttpContext; pub use context::HttpContext;
pub use fs::StaticFiles;
// re-exports // re-exports
pub use http::{Method, StatusCode, Version}; pub use http::{Method, StatusCode, Version};

View File

@ -1,5 +1,4 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::result::Result as StdResult;
use actix::Actor; use actix::Actor;
use futures::Future; use futures::Future;
@ -21,7 +20,13 @@ pub trait Handler<S>: 'static {
} }
pub trait FromRequest { pub trait FromRequest {
fn from_request(self, req: HttpRequest) -> Reply; /// The associated item which can be returned.
type Item: Into<Reply>;
/// The associated error which can be returned.
type Error: Into<Error>;
fn from_request(self, req: HttpRequest) -> Result<Self::Item, Self::Error>;
} }
/// Handler<S> for Fn() /// Handler<S> for Fn()
@ -72,46 +77,53 @@ impl Reply {
} }
impl FromRequest for Reply { impl FromRequest for Reply {
fn from_request(self, _: HttpRequest) -> Reply { type Item = Reply;
self type Error = Error;
fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
Ok(self)
} }
} }
impl FromRequest for HttpResponse { impl FromRequest for HttpResponse {
fn from_request(self, _: HttpRequest) -> Reply { type Item = Reply;
Reply(ReplyItem::Message(self)) type Error = Error;
fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
Ok(Reply(ReplyItem::Message(self)))
} }
} }
#[cfg(actix_nightly)] impl From<HttpResponse> for Reply {
default impl<T: FromRequest> FromRequest for T
{ fn from(resp: HttpResponse) -> Reply {
fn from_request(self, req: HttpRequest) -> Reply { Reply(ReplyItem::Message(resp))
self.from_request(req)
} }
} }
#[cfg(actix_nightly)] impl<T: Into<HttpResponse>, E: Into<Error>> FromRequest for Result<T, E> {
default impl<T: Into<HttpResponse>, E: Into<Error>> FromRequest for StdResult<T, E> { type Item = Reply;
fn from_request(self, req: HttpRequest) -> Reply { type Error = E;
fn from_request(self, _: HttpRequest) -> Result<Reply, Self::Error> {
match self { match self {
Ok(val) => Reply(ReplyItem::Message(val.into())), //val.from_request(req), Ok(val) => Ok(Reply(ReplyItem::Message(val.into()))),
Err(err) => Reply(ReplyItem::Message(err.into().into())), Err(err) => Err(err),
} }
} }
} }
impl<E: Into<Error>> FromRequest for StdResult<Reply, E> { impl<E: Into<Error>> FromRequest for Result<Reply, E> {
fn from_request(self, _: HttpRequest) -> Reply { type Item = Reply;
match self { type Error = E;
Ok(val) => val,
Err(err) => Reply(ReplyItem::Message(err.into().into())), fn from_request(self, _: HttpRequest) -> Result<Reply, E> {
} self
} }
} }
impl<E: Into<Error>> From<StdResult<Reply, E>> for Reply { impl<E: Into<Error>> From<Result<Reply, E>> for Reply {
fn from(res: StdResult<Reply, E>) -> Self { fn from(res: Result<Reply, E>) -> Self {
match res { match res {
Ok(val) => val, Ok(val) => val,
Err(err) => Reply(ReplyItem::Message(err.into().into())), Err(err) => Reply(ReplyItem::Message(err.into().into())),
@ -119,23 +131,18 @@ impl<E: Into<Error>> From<StdResult<Reply, E>> for Reply {
} }
} }
impl<E: Into<Error>> FromRequest for StdResult<HttpResponse, E> {
fn from_request(self, _: HttpRequest) -> Reply {
match self {
Ok(val) => Reply(ReplyItem::Message(val)),
Err(err) => Reply(ReplyItem::Message(err.into().into())),
}
}
}
impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> FromRequest for HttpContext<A, S> impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> FromRequest for HttpContext<A, S>
{ {
fn from_request(self, _: HttpRequest) -> Reply { type Item = Reply;
Reply(ReplyItem::Actor(Box::new(self))) type Error = Error;
fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
Ok(Reply(ReplyItem::Actor(Box::new(self))))
} }
} }
impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> for Reply { impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> for Reply {
fn from(ctx: HttpContext<A, S>) -> Reply { fn from(ctx: HttpContext<A, S>) -> Reply {
Reply(ReplyItem::Actor(Box::new(ctx))) Reply(ReplyItem::Actor(Box::new(ctx)))
} }
@ -143,8 +150,11 @@ impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> fo
impl FromRequest for Box<Future<Item=HttpResponse, Error=Error>> impl FromRequest for Box<Future<Item=HttpResponse, Error=Error>>
{ {
fn from_request(self, _: HttpRequest) -> Reply { type Item = Reply;
Reply(ReplyItem::Future(self)) type Error = Error;
fn from_request(self, _: HttpRequest) -> Result<Reply, Error> {
Ok(Reply(ReplyItem::Future(self)))
} }
} }
@ -181,7 +191,10 @@ impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
{ {
fn handle(&self, req: HttpRequest<S>) -> Reply { fn handle(&self, req: HttpRequest<S>) -> Reply {
let req2 = req.clone_without_state(); let req2 = req.clone_without_state();
self.h.handle(req).from_request(req2) match self.h.handle(req).from_request(req2) {
Ok(reply) => reply.into(),
Err(err) => Reply::response(err.into()),
}
} }
} }