feat(lib): update to std::future::Future
				
					
				
			BREAKING CHANGE: All usage of async traits (`Future`, `Stream`, `AsyncRead`, `AsyncWrite`, etc) are updated to newer versions.
This commit is contained in:
		
							
								
								
									
										294
									
								
								src/body/body.rs
									
									
									
									
									
								
							
							
						
						
									
										294
									
								
								src/body/body.rs
									
									
									
									
									
								
							| @@ -3,13 +3,13 @@ use std::error::Error as StdError; | ||||
| use std::fmt; | ||||
|  | ||||
| use bytes::Bytes; | ||||
| use futures::sync::{mpsc, oneshot}; | ||||
| use futures::{Async, Future, Poll, Stream, Sink, AsyncSink, StartSend}; | ||||
| use futures_core::Stream; | ||||
| use futures_channel::{mpsc, oneshot}; | ||||
| use tokio_buf::SizeHint; | ||||
| use h2; | ||||
| use http::HeaderMap; | ||||
|  | ||||
| use crate::common::Never; | ||||
| use crate::common::{Future, Never, Pin, Poll, task}; | ||||
| use super::internal::{FullDataArg, FullDataRet}; | ||||
| use super::{Chunk, Payload}; | ||||
| use crate::upgrade::OnUpgrade; | ||||
| @@ -40,7 +40,7 @@ enum Kind { | ||||
|         content_length: Option<u64>, | ||||
|         recv: h2::RecvStream, | ||||
|     }, | ||||
|     Wrapped(Box<dyn Stream<Item = Chunk, Error = Box<dyn StdError + Send + Sync>> + Send>), | ||||
|     Wrapped(Pin<Box<dyn Stream<Item = Result<Chunk, Box<dyn StdError + Send + Sync>>> + Send>>), | ||||
| } | ||||
|  | ||||
| struct Extra { | ||||
| @@ -119,6 +119,7 @@ impl Body { | ||||
|         (tx, rx) | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|     /// Wrap a futures `Stream` in a box inside `Body`. | ||||
|     /// | ||||
|     /// # Example | ||||
| @@ -148,6 +149,12 @@ impl Body { | ||||
|         let mapped = stream.map(Chunk::from).map_err(Into::into); | ||||
|         Body::new(Kind::Wrapped(Box::new(mapped))) | ||||
|     } | ||||
|     */ | ||||
|  | ||||
|     /// dox | ||||
|     pub async fn next(&mut self) -> Option<crate::Result<Chunk>> { | ||||
|         futures_util::future::poll_fn(|cx| self.poll_eof(cx)).await | ||||
|     } | ||||
|  | ||||
|     /// Converts this `Body` into a `Future` of a pending HTTP upgrade. | ||||
|     /// | ||||
| @@ -200,83 +207,91 @@ impl Body { | ||||
|             })) | ||||
|     } | ||||
|  | ||||
|     fn poll_eof(&mut self) -> Poll<Option<Chunk>, crate::Error> { | ||||
|     fn poll_eof(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Chunk>>> { | ||||
|         match self.take_delayed_eof() { | ||||
|             Some(DelayEof::NotEof(mut delay)) => { | ||||
|                 match self.poll_inner() { | ||||
|                     ok @ Ok(Async::Ready(Some(..))) | | ||||
|                     ok @ Ok(Async::NotReady) => { | ||||
|                 match self.poll_inner(cx) { | ||||
|                     ok @ Poll::Ready(Some(Ok(..))) | | ||||
|                     ok @ Poll::Pending => { | ||||
|                         self.extra_mut().delayed_eof = Some(DelayEof::NotEof(delay)); | ||||
|                         ok | ||||
|                     }, | ||||
|                     Ok(Async::Ready(None)) => match delay.poll() { | ||||
|                         Ok(Async::Ready(never)) => match never {}, | ||||
|                         Ok(Async::NotReady) => { | ||||
|                     Poll::Ready(None) => match Pin::new(&mut delay).poll(cx) { | ||||
|                         Poll::Ready(Ok(never)) => match never {}, | ||||
|                         Poll::Pending => { | ||||
|                             self.extra_mut().delayed_eof = Some(DelayEof::Eof(delay)); | ||||
|                             Ok(Async::NotReady) | ||||
|                             Poll::Pending | ||||
|                         }, | ||||
|                         Err(_done) => { | ||||
|                             Ok(Async::Ready(None)) | ||||
|                         Poll::Ready(Err(_done)) => { | ||||
|                             Poll::Ready(None) | ||||
|                         }, | ||||
|                     }, | ||||
|                     Err(e) => Err(e), | ||||
|                     Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), | ||||
|                 } | ||||
|             }, | ||||
|             Some(DelayEof::Eof(mut delay)) => { | ||||
|                 match delay.poll() { | ||||
|                     Ok(Async::Ready(never)) => match never {}, | ||||
|                     Ok(Async::NotReady) => { | ||||
|                 match Pin::new(&mut delay).poll(cx) { | ||||
|                     Poll::Ready(Ok(never)) => match never {}, | ||||
|                     Poll::Pending => { | ||||
|                         self.extra_mut().delayed_eof = Some(DelayEof::Eof(delay)); | ||||
|                         Ok(Async::NotReady) | ||||
|                         Poll::Pending | ||||
|                     }, | ||||
|                     Err(_done) => { | ||||
|                         Ok(Async::Ready(None)) | ||||
|                     Poll::Ready(Err(_done)) => { | ||||
|                         Poll::Ready(None) | ||||
|                     }, | ||||
|                 } | ||||
|             }, | ||||
|             None => self.poll_inner(), | ||||
|             None => self.poll_inner(cx), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn poll_inner(&mut self) -> Poll<Option<Chunk>, crate::Error> { | ||||
|     fn poll_inner(&mut self, cx: &mut task::Context<'_>) -> Poll<Option<crate::Result<Chunk>>> { | ||||
|         match self.kind { | ||||
|             Kind::Once(ref mut val) => Ok(Async::Ready(val.take())), | ||||
|             Kind::Once(ref mut val) => Poll::Ready(val.take().map(Ok)), | ||||
|             Kind::Chan { | ||||
|                 content_length: ref mut len, | ||||
|                 ref mut rx, | ||||
|                 ref mut abort_rx, | ||||
|             } => { | ||||
|                 if let Ok(Async::Ready(())) = abort_rx.poll() { | ||||
|                     return Err(crate::Error::new_body_write("body write aborted")); | ||||
|                 if let Poll::Ready(Ok(())) = Pin::new(abort_rx).poll(cx) { | ||||
|                     return Poll::Ready(Some(Err(crate::Error::new_body_write("body write aborted")))); | ||||
|                 } | ||||
|  | ||||
|                 match rx.poll().expect("mpsc cannot error") { | ||||
|                     Async::Ready(Some(Ok(chunk))) => { | ||||
|                 match ready!(Pin::new(rx).poll_next(cx)?) { | ||||
|                     Some(chunk) => { | ||||
|                         if let Some(ref mut len) = *len { | ||||
|                             debug_assert!(*len >= chunk.len() as u64); | ||||
|                             *len = *len - chunk.len() as u64; | ||||
|                         } | ||||
|                         Ok(Async::Ready(Some(chunk))) | ||||
|                         Poll::Ready(Some(Ok(chunk))) | ||||
|                     } | ||||
|                     Async::Ready(Some(Err(err))) => Err(err), | ||||
|                     Async::Ready(None) => Ok(Async::Ready(None)), | ||||
|                     Async::NotReady => Ok(Async::NotReady), | ||||
|                     None => Poll::Ready(None), | ||||
|                 } | ||||
|             } | ||||
|             Kind::H2 { | ||||
|                 recv: ref mut h2, .. | ||||
|             } => h2 | ||||
|                 .poll() | ||||
|                 .map(|r#async| { | ||||
|                     r#async.map(|opt| { | ||||
|                         opt.map(|bytes| { | ||||
|                             let _ = h2.release_capacity().release_capacity(bytes.len()); | ||||
|                             Chunk::from(bytes) | ||||
|                 /*recv: ref mut h2,*/ .. | ||||
|             } => { | ||||
|                 unimplemented!("h2.poll_inner"); | ||||
|                 /* | ||||
|                 h2 | ||||
|                     .poll() | ||||
|                     .map(|r#async| { | ||||
|                         r#async.map(|opt| { | ||||
|                             opt.map(|bytes| { | ||||
|                                 let _ = h2.release_capacity().release_capacity(bytes.len()); | ||||
|                                 Chunk::from(bytes) | ||||
|                             }) | ||||
|                         }) | ||||
|                     }) | ||||
|                 }) | ||||
|                 .map_err(crate::Error::new_body), | ||||
|             Kind::Wrapped(ref mut s) => s.poll().map_err(crate::Error::new_body), | ||||
|                     .map_err(crate::Error::new_body) | ||||
|                     */ | ||||
|             } | ||||
|             Kind::Wrapped(ref mut s) => { | ||||
|                 match ready!(s.as_mut().poll_next(cx)) { | ||||
|                     Some(res) => Poll::Ready(Some(res.map_err(crate::Error::new_body))), | ||||
|                     None => Poll::Ready(None), | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -293,16 +308,17 @@ impl Payload for Body { | ||||
|     type Data = Chunk; | ||||
|     type Error = crate::Error; | ||||
|  | ||||
|     fn poll_data(&mut self) -> Poll<Option<Self::Data>, Self::Error> { | ||||
|         self.poll_eof() | ||||
|     fn poll_data(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>> { | ||||
|         self.poll_eof(cx) | ||||
|     } | ||||
|  | ||||
|     fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, Self::Error> { | ||||
|     fn poll_trailers(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<HeaderMap, Self::Error>>> { | ||||
|         match self.kind { | ||||
|             Kind::H2 { | ||||
|                 recv: ref mut h2, .. | ||||
|             } => h2.poll_trailers().map_err(crate::Error::new_h2), | ||||
|             _ => Ok(Async::Ready(None)), | ||||
|             Kind::H2 { /*recv: ref mut h2,*/ .. } => { | ||||
|                 unimplemented!("h2.poll_trailers"); | ||||
|                 //h2.poll_trailers().map_err(crate::Error::new_h2) | ||||
|             }, | ||||
|             _ => Poll::Ready(None), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -334,6 +350,27 @@ impl Payload for Body { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Debug for Body { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         #[derive(Debug)] | ||||
|         struct Streaming; | ||||
|         #[derive(Debug)] | ||||
|         struct Empty; | ||||
|         #[derive(Debug)] | ||||
|         struct Once<'a>(&'a Chunk); | ||||
|  | ||||
|         let mut builder = f.debug_tuple("Body"); | ||||
|         match self.kind { | ||||
|             Kind::Once(None) => builder.field(&Empty), | ||||
|             Kind::Once(Some(ref chunk)) => builder.field(&Once(chunk)), | ||||
|             _ => builder.field(&Streaming), | ||||
|         }; | ||||
|  | ||||
|         builder.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
| impl ::http_body::Body for Body { | ||||
|     type Data = Chunk; | ||||
|     type Error = crate::Error; | ||||
| @@ -363,86 +400,28 @@ impl ::http_body::Body for Body { | ||||
|         hint | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
| impl Stream for Body { | ||||
|     type Item = Chunk; | ||||
|     type Error = crate::Error; | ||||
|     type Item = crate::Result<Chunk>; | ||||
|  | ||||
|     fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { | ||||
|         self.poll_data() | ||||
|     fn poll_next(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Self::Item>> { | ||||
|         self.poll_data(cx) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Debug for Body { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|         #[derive(Debug)] | ||||
|         struct Streaming; | ||||
|         #[derive(Debug)] | ||||
|         struct Empty; | ||||
|         #[derive(Debug)] | ||||
|         struct Once<'a>(&'a Chunk); | ||||
|  | ||||
|         let mut builder = f.debug_tuple("Body"); | ||||
|         match self.kind { | ||||
|             Kind::Once(None) => builder.field(&Empty), | ||||
|             Kind::Once(Some(ref chunk)) => builder.field(&Once(chunk)), | ||||
|             _ => builder.field(&Streaming), | ||||
|         }; | ||||
|  | ||||
|         builder.finish() | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Sender { | ||||
|     /// Check to see if this `Sender` can send more data. | ||||
|     pub fn poll_ready(&mut self) -> Poll<(), crate::Error> { | ||||
|         match self.abort_tx.poll_cancel() { | ||||
|             Ok(Async::Ready(())) | Err(_) => return Err(crate::Error::new_closed()), | ||||
|             Ok(Async::NotReady) => (), | ||||
|         } | ||||
|  | ||||
|         self.tx.poll_ready().map_err(|_| crate::Error::new_closed()) | ||||
|     } | ||||
|  | ||||
|     /// Sends data on this channel. | ||||
|     /// | ||||
|     /// This should be called after `poll_ready` indicated the channel | ||||
|     /// could accept another `Chunk`. | ||||
|     /// | ||||
|     /// Returns `Err(Chunk)` if the channel could not (currently) accept | ||||
|     /// another `Chunk`. | ||||
|     pub fn send_data(&mut self, chunk: Chunk) -> Result<(), Chunk> { | ||||
|         self.tx | ||||
|             .try_send(Ok(chunk)) | ||||
|             .map_err(|err| err.into_inner().expect("just sent Ok")) | ||||
|     } | ||||
|  | ||||
|     /// Aborts the body in an abnormal fashion. | ||||
|     pub fn abort(self) { | ||||
|         let _ = self.abort_tx.send(()); | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn send_error(&mut self, err: crate::Error) { | ||||
|         let _ = self.tx.try_send(Err(err)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Sink for Sender { | ||||
|     type SinkItem = Chunk; | ||||
|     type SinkError = crate::Error; | ||||
|  | ||||
|     fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { | ||||
|         Ok(Async::Ready(())) | ||||
|     } | ||||
|  | ||||
|     fn start_send(&mut self, msg: Chunk) -> StartSend<Self::SinkItem, Self::SinkError> { | ||||
|         match self.poll_ready()? { | ||||
|             Async::Ready(_) => { | ||||
|                 self.send_data(msg).map_err(|_| crate::Error::new_closed())?; | ||||
|                 Ok(AsyncSink::Ready) | ||||
|             } | ||||
|             Async::NotReady => Ok(AsyncSink::NotReady(msg)), | ||||
|         } | ||||
| impl | ||||
|     From<Box<dyn Stream<Item = Result<Chunk, Box<dyn StdError + Send + Sync>>> + Send>> | ||||
|     for Body | ||||
| { | ||||
|     #[inline] | ||||
|     fn from( | ||||
|         stream: Box< | ||||
|             dyn Stream<Item = Result<Chunk, Box<dyn StdError + Send + Sync>>> + Send, | ||||
|         >, | ||||
|     ) -> Body { | ||||
|         Body::new(Kind::Wrapped(stream.into())) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -457,20 +436,6 @@ impl From<Chunk> for Body { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl | ||||
|     From<Box<dyn Stream<Item = Chunk, Error = Box<dyn StdError + Send + Sync>> + Send + 'static>> | ||||
|     for Body | ||||
| { | ||||
|     #[inline] | ||||
|     fn from( | ||||
|         stream: Box< | ||||
|             dyn Stream<Item = Chunk, Error = Box<dyn StdError + Send + Sync>> + Send + 'static, | ||||
|         >, | ||||
|     ) -> Body { | ||||
|         Body::new(Kind::Wrapped(stream)) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl From<Bytes> for Body { | ||||
|     #[inline] | ||||
|     fn from(bytes: Bytes) -> Body { | ||||
| @@ -526,6 +491,61 @@ impl From<Cow<'static, str>> for Body { | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Sender { | ||||
|     /// Check to see if this `Sender` can send more data. | ||||
|     pub fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<crate::Result<()>> { | ||||
|         match self.abort_tx.poll_cancel(cx) { | ||||
|             Poll::Ready(()) => return Poll::Ready(Err(crate::Error::new_closed())), | ||||
|             Poll::Pending => (), // fallthrough | ||||
|         } | ||||
|  | ||||
|         self.tx.poll_ready(cx).map_err(|_| crate::Error::new_closed()) | ||||
|     } | ||||
|  | ||||
|     /// Sends data on this channel. | ||||
|     /// | ||||
|     /// This should be called after `poll_ready` indicated the channel | ||||
|     /// could accept another `Chunk`. | ||||
|     /// | ||||
|     /// Returns `Err(Chunk)` if the channel could not (currently) accept | ||||
|     /// another `Chunk`. | ||||
|     pub fn send_data(&mut self, chunk: Chunk) -> Result<(), Chunk> { | ||||
|         self.tx | ||||
|             .try_send(Ok(chunk)) | ||||
|             .map_err(|err| err.into_inner().expect("just sent Ok")) | ||||
|     } | ||||
|  | ||||
|     /// Aborts the body in an abnormal fashion. | ||||
|     pub fn abort(self) { | ||||
|         let _ = self.abort_tx.send(()); | ||||
|     } | ||||
|  | ||||
|     pub(crate) fn send_error(&mut self, err: crate::Error) { | ||||
|         let _ = self.tx.try_send(Err(err)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
| impl Sink for Sender { | ||||
|     type SinkItem = Chunk; | ||||
|     type SinkError = crate::Error; | ||||
|  | ||||
|     fn poll_complete(&mut self) -> Poll<(), Self::SinkError> { | ||||
|         Poll::Ready(Ok(())) | ||||
|     } | ||||
|  | ||||
|     fn start_send(&mut self, msg: Chunk) -> StartSend<Self::SinkItem, Self::SinkError> { | ||||
|         match self.poll_ready()? { | ||||
|             Async::Ready(_) => { | ||||
|                 self.send_data(msg).map_err(|_| crate::Error::new_closed())?; | ||||
|                 Ok(AsyncSink::Ready) | ||||
|             } | ||||
|             Async::NotReady => Ok(AsyncSink::NotReady(msg)), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
| #[test] | ||||
| fn test_body_stream_concat() { | ||||
|     let body = Body::from("hello world"); | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| use std::error::Error as StdError; | ||||
|  | ||||
| use bytes::Buf; | ||||
| use futures::{Async, Poll}; | ||||
| use http::HeaderMap; | ||||
|  | ||||
| use crate::common::{Pin, Poll, task}; | ||||
| use super::internal::{FullDataArg, FullDataRet}; | ||||
|  | ||||
| /// This trait represents a streaming body of a `Request` or `Response`. | ||||
| @@ -21,15 +21,15 @@ pub trait Payload: Send + 'static { | ||||
|     /// | ||||
|     /// Similar to `Stream::poll_next`, this yields `Some(Data)` until | ||||
|     /// the body ends, when it yields `None`. | ||||
|     fn poll_data(&mut self) -> Poll<Option<Self::Data>, Self::Error>; | ||||
|     fn poll_data(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>>; | ||||
|  | ||||
|     /// Poll for an optional **single** `HeaderMap` of trailers. | ||||
|     /// | ||||
|     /// This should **only** be called after `poll_data` has ended. | ||||
|     /// | ||||
|     /// Note: Trailers aren't currently used for HTTP/1, only for HTTP/2. | ||||
|     fn poll_trailers(&mut self) -> Poll<Option<HeaderMap>, Self::Error> { | ||||
|         Ok(Async::Ready(None)) | ||||
|     fn poll_trailers(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Option<Result<HeaderMap, Self::Error>>> { | ||||
|         Poll::Ready(None) | ||||
|     } | ||||
|  | ||||
|     /// A hint that the `Body` is complete, and doesn't need to be polled more. | ||||
| @@ -70,6 +70,7 @@ pub trait Payload: Send + 'static { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
| impl<E: Payload> Payload for Box<E> { | ||||
|     type Data = E::Data; | ||||
|     type Error = E::Error; | ||||
| @@ -95,5 +96,6 @@ impl<E: Payload> Payload for Box<E> { | ||||
|         (**self).__hyper_full_data(arg) | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user