From c14e6c9008fc163fb9e8cee2e08a588129797128 Mon Sep 17 00:00:00 2001
From: Nikolay Kim <fafhrd91@gmail.com>
Date: Fri, 3 Nov 2017 13:35:34 -0700
Subject: [PATCH] make possible to use async handler

---
 CHANGES.md          |  6 +++++-
 examples/basic.rs   | 16 ++++++++++++++++
 src/body.rs         |  7 +++++++
 src/httpresponse.rs |  7 +++++++
 src/lib.rs          |  2 +-
 src/route.rs        |  6 ++++++
 6 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 2c3ca287d..8821796af 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,10 +1,14 @@
 # Changes
 
 
-## 0.2.1 (2017-11-xx)
+## 0.2.1 (2017-11-03)
 
 * Allow to start tls server with `HttpServer::serve_tls`
 
+* Export `Frame` enum
+
+* Add conversion impl from `HttpResponse` and `BinaryBody` to a `Frame`
+
 ## 0.2.0 (2017-10-30)
 
 * Do not use `http::Uri` as it can not parse some valid paths
diff --git a/examples/basic.rs b/examples/basic.rs
index 0339335e0..0a6aecb56 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -2,8 +2,10 @@
 extern crate actix;
 extern crate actix_web;
 extern crate env_logger;
+extern crate futures;
 
 use actix_web::*;
+use futures::stream::{once, Once};
 
 /// somple handle
 fn index(req: &mut HttpRequest, _payload: Payload, state: &()) -> HttpResponse {
@@ -11,6 +13,18 @@ fn index(req: &mut HttpRequest, _payload: Payload, state: &()) -> HttpResponse {
     httpcodes::HTTPOk.into()
 }
 
+/// somple handle
+fn index_async(req: &mut HttpRequest, _payload: Payload, state: &()) -> Once<actix_web::Frame, ()>
+{
+    println!("{:?}", req);
+
+    once(Ok(HttpResponse::builder(StatusCode::OK)
+            .content_type("text/html")
+            .body(format!("Hello {}!", req.match_info().get("name").unwrap()))
+            .unwrap()
+            .into()))
+}
+
 /// handle with path parameters like `/name/{name}/`
 fn with_param(req: &mut HttpRequest, _payload: Payload, state: &())
               -> HandlerResult<HttpResponse>
@@ -35,6 +49,8 @@ fn main() {
             .handler("/index.html", index)
             // with path parameters
             .resource("/user/{name}/", |r| r.handler(Method::GET, with_param))
+            // async handler
+            .resource("/async/{name}", |r| r.async(Method::GET, index_async))
             // redirect
             .resource("/", |r| r.handler(Method::GET, |req, _, _| {
                 println!("{:?}", req);
diff --git a/src/body.rs b/src/body.rs
index 70da53cdd..3454a6cfc 100644
--- a/src/body.rs
+++ b/src/body.rs
@@ -2,6 +2,8 @@ use std::rc::Rc;
 use std::sync::Arc;
 use bytes::{Bytes, BytesMut};
 
+use route::Frame;
+
 
 /// Represents various types of http message body.
 #[derive(Debug)]
@@ -185,6 +187,11 @@ impl AsRef<[u8]> for BinaryBody {
     }
 }
 
+impl From<BinaryBody> for Frame {
+    fn from(b: BinaryBody) -> Frame {
+        Frame::Payload(Some(b))
+    }
+}
 
 #[cfg(test)]
 mod tests {
diff --git a/src/httpresponse.rs b/src/httpresponse.rs
index dcc45bcd7..46074e897 100644
--- a/src/httpresponse.rs
+++ b/src/httpresponse.rs
@@ -9,6 +9,7 @@ use http::header::{self, HeaderName, HeaderValue};
 
 use Cookie;
 use body::Body;
+use route::Frame;
 
 
 /// Represents various types of connection
@@ -196,6 +197,12 @@ impl<I: Into<HttpResponse>, E: Into<HttpResponse>> From<Result<I, E>> for HttpRe
     }
 }
 
+impl From<HttpResponse> for Frame {
+    fn from(resp: HttpResponse) -> Frame {
+        Frame::Message(resp)
+    }
+}
+
 #[derive(Debug)]
 struct Parts {
     version: Option<Version>,
diff --git a/src/lib.rs b/src/lib.rs
index f064676a7..79e193dae 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -56,7 +56,7 @@ pub use application::{Application, ApplicationBuilder, Middleware};
 pub use httprequest::{HttpRequest, UrlEncoded};
 pub use httpresponse::{HttpResponse, HttpResponseBuilder};
 pub use payload::{Payload, PayloadItem, PayloadError};
-pub use route::{Route, RouteFactory, RouteHandler, RouteResult};
+pub use route::{Frame, Route, RouteFactory, RouteHandler, RouteResult};
 pub use resource::{Reply, Resource, HandlerResult};
 pub use recognizer::{Params, RouteRecognizer};
 pub use logger::Logger;
diff --git a/src/route.rs b/src/route.rs
index e242a5e8f..c2f7e83ff 100644
--- a/src/route.rs
+++ b/src/route.rs
@@ -25,6 +25,12 @@ pub enum Frame {
     Drain(Rc<RefCell<DrainFut>>),
 }
 
+impl Frame {
+    pub fn eof() -> Frame {
+        Frame::Payload(None)
+    }
+}
+
 /// Trait defines object that could be regestered as resource route
 #[allow(unused_variables)]
 pub trait RouteHandler<S>: 'static {