use std::fmt; use std::io; use std::io::IoSlice; use std::pin::Pin; use std::task::{Context, Poll}; use hyper::client::connect::{Connected, Connection}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; pub use tokio_native_tls::TlsStream; /// A stream that might be protected with TLS. pub enum MaybeHttpsStream { /// A stream over plain text. Http(T), /// A stream protected with TLS. Https(TlsStream), } // ===== impl MaybeHttpsStream ===== impl fmt::Debug for MaybeHttpsStream { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { MaybeHttpsStream::Http(s) => f.debug_tuple("Http").field(s).finish(), MaybeHttpsStream::Https(s) => f.debug_tuple("Https").field(s).finish(), } } } impl From for MaybeHttpsStream { fn from(inner: T) -> Self { MaybeHttpsStream::Http(inner) } } impl From> for MaybeHttpsStream { fn from(inner: TlsStream) -> Self { MaybeHttpsStream::Https(inner) } } impl AsyncRead for MaybeHttpsStream { #[inline] fn poll_read( self: Pin<&mut Self>, cx: &mut Context, buf: &mut ReadBuf, ) -> Poll> { match Pin::get_mut(self) { MaybeHttpsStream::Http(s) => Pin::new(s).poll_read(cx, buf), MaybeHttpsStream::Https(s) => Pin::new(s).poll_read(cx, buf), } } } impl AsyncWrite for MaybeHttpsStream { #[inline] fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll> { match Pin::get_mut(self) { MaybeHttpsStream::Http(s) => Pin::new(s).poll_write(cx, buf), MaybeHttpsStream::Https(s) => Pin::new(s).poll_write(cx, buf), } } fn poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>], ) -> Poll> { match Pin::get_mut(self) { MaybeHttpsStream::Http(s) => Pin::new(s).poll_write_vectored(cx, bufs), MaybeHttpsStream::Https(s) => Pin::new(s).poll_write_vectored(cx, bufs), } } fn is_write_vectored(&self) -> bool { match self { MaybeHttpsStream::Http(s) => s.is_write_vectored(), MaybeHttpsStream::Https(s) => s.is_write_vectored(), } } #[inline] fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match Pin::get_mut(self) { MaybeHttpsStream::Http(s) => Pin::new(s).poll_flush(cx), MaybeHttpsStream::Https(s) => Pin::new(s).poll_flush(cx), } } #[inline] fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match Pin::get_mut(self) { MaybeHttpsStream::Http(s) => Pin::new(s).poll_shutdown(cx), MaybeHttpsStream::Https(s) => Pin::new(s).poll_shutdown(cx), } } } impl Connection for MaybeHttpsStream { fn connected(&self) -> Connected { match self { MaybeHttpsStream::Http(s) => s.connected(), MaybeHttpsStream::Https(s) => s.get_ref().get_ref().get_ref().connected(), } } }