diff --git a/src/handler.rs b/src/handler.rs index dae80e9ff..15f975b6e 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -1,8 +1,10 @@ -use futures::future::{err, ok, Future}; -use futures::Poll; use std::marker::PhantomData; +use std::mem; use std::ops::Deref; +use futures::future::{err, ok, Future}; +use futures::{Async, Poll}; + use error::Error; use httprequest::HttpRequest; use httpresponse::HttpResponse; @@ -185,7 +187,31 @@ where /// * Future - reply process completes in the future pub struct Reply(ReplyItem); +impl Future for Reply { + type Item = T; + type Error = Error; + + fn poll(&mut self) -> Poll { + let item = mem::replace(&mut self.0, ReplyItem::None); + + match item { + ReplyItem::Error(err) => Err(err), + ReplyItem::Message(msg) => Ok(Async::Ready(msg)), + ReplyItem::Future(mut fut) => match fut.poll() { + Ok(Async::NotReady) => { + self.0 = ReplyItem::Future(fut); + Ok(Async::NotReady) + } + Ok(Async::Ready(msg)) => Ok(Async::Ready(msg)), + Err(err) => Err(err), + }, + ReplyItem::None => panic!("use after resolve"), + } + } +} + pub(crate) enum ReplyItem { + None, Error(Error), Message(T), Future(Box>), diff --git a/src/pipeline.rs b/src/pipeline.rs index cea02073f..398738e61 100644 --- a/src/pipeline.rs +++ b/src/pipeline.rs @@ -331,6 +331,7 @@ impl WaitingResponse { _s: PhantomData, _h: PhantomData, }), + ReplyItem::None => panic!("use after resolve"), } } diff --git a/src/route.rs b/src/route.rs index 7d39cc107..d5137c575 100644 --- a/src/route.rs +++ b/src/route.rs @@ -423,6 +423,7 @@ impl WaitingResponse { fut, _s: PhantomData, }), + ReplyItem::None => panic!("use after resolve"), } } diff --git a/src/scope.rs b/src/scope.rs index 38e6c0624..23c95e682 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -529,6 +529,7 @@ impl WaitingResponse { fut, _s: PhantomData, }), + ReplyItem::None => panic!("use after resolve"), } } diff --git a/src/test.rs b/src/test.rs index 0de7f6340..6b62a5ceb 100644 --- a/src/test.rs +++ b/src/test.rs @@ -604,6 +604,7 @@ impl TestRequest { ReplyItem::Message(resp) => Ok(resp), ReplyItem::Error(err) => Ok(err.into()), ReplyItem::Future(_) => panic!("Async handler is not supported."), + ReplyItem::None => panic!("use after resolve"), }, Err(err) => Err(err), } diff --git a/src/with.rs b/src/with.rs index a3b07ac0b..bf0d77d2a 100644 --- a/src/with.rs +++ b/src/with.rs @@ -142,6 +142,7 @@ where self.fut1 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), } } else { match self.fut1.as_mut().unwrap().poll()? { @@ -163,6 +164,7 @@ where self.fut2 = Some(fut); self.poll() } + ReplyItem::None => panic!("use after resolve"), } } } @@ -274,6 +276,7 @@ where self.fut1 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let reply = T2::from_request(&mut self.req, self.cfg2.as_ref()).into(); @@ -285,6 +288,7 @@ where self.fut2 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; @@ -296,6 +300,7 @@ where self.fut3 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }, Err(e) => return Err(e.into()), } @@ -314,6 +319,7 @@ where self.fut2 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; @@ -325,6 +331,7 @@ where self.fut3 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }, Err(e) => return Err(e.into()), } @@ -350,6 +357,7 @@ where ReplyItem::Error(err) => return Err(err), ReplyItem::Message(resp) => return Ok(Async::Ready(resp)), ReplyItem::Future(fut) => self.fut3 = Some(fut), + ReplyItem::None => panic!("use after resolve"), } self.poll() @@ -480,6 +488,7 @@ where self.fut1 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let reply = T2::from_request(&mut self.req, self.cfg2.as_ref()).into(); @@ -491,6 +500,7 @@ where self.fut2 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let reply = T3::from_request(&mut self.req, self.cfg3.as_ref()).into(); @@ -503,6 +513,7 @@ where self.fut3 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; @@ -514,6 +525,7 @@ where self.fut4 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }, Err(e) => return Err(e.into()), } @@ -533,6 +545,7 @@ where self.fut2 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let reply = @@ -545,6 +558,7 @@ where self.fut3 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; match (*hnd)(self.item1.take().unwrap(), item2, item3) @@ -557,6 +571,7 @@ where self.fut4 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }, Err(e) => return Err(e.into()), } @@ -579,6 +594,7 @@ where self.fut3 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }; let hnd: &mut F = unsafe { &mut *self.hnd.get() }; match (*hnd)(self.item1.take().unwrap(), item, item3) @@ -591,6 +607,7 @@ where self.fut4 = Some(fut); return self.poll(); } + ReplyItem::None => panic!("use after resolve"), }, Err(e) => return Err(e.into()), } @@ -619,6 +636,7 @@ where ReplyItem::Error(err) => return Ok(Async::Ready(err.into())), ReplyItem::Message(resp) => return Ok(Async::Ready(resp)), ReplyItem::Future(fut) => self.fut4 = Some(fut), + ReplyItem::None => panic!("use after resolve"), } self.poll()