Don't project if you require Unpin.

This doesn't make sense. For Unpin types, Pin does nothing, so Pin::new() is sufficient.

However Pin::new is only implemented for `Pin<P> where <P as Deref>::Target: Unpin`, so if it weren't Unpin,
you would have to use unsafe { Pin::new_unchecked(s) }, `Pin::new()` wouldn't compile.

Thus project and Pin::new together is always a code smell.
pull/13/head
Naja Melan 5 years ago committed by Sebastian Dröge
parent a65c53b6cd
commit bfbb94030a
  1. 13
      src/handshake.rs
  2. 22
      src/stream.rs

@ -2,7 +2,6 @@ use crate::compat::{AllowStd, SetWaker};
use crate::WebSocketStream; use crate::WebSocketStream;
use futures::io::{AsyncRead, AsyncWrite}; use futures::io::{AsyncRead, AsyncWrite};
use log::*; use log::*;
use pin_project::pin_project;
use std::future::Future; use std::future::Future;
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::pin::Pin; use std::pin::Pin;
@ -51,7 +50,6 @@ where
} }
} }
#[pin_project]
struct MidHandshake<Role: HandshakeRole>(Option<WsHandshake<Role>>); struct MidHandshake<Role: HandshakeRole>(Option<WsHandshake<Role>>);
enum StartedHandshake<Role: HandshakeRole> { enum StartedHandshake<Role: HandshakeRole> {
@ -68,7 +66,7 @@ struct StartedHandshakeFutureInner<F, S> {
async fn handshake<Role, F, S>(stream: S, f: F) -> Result<Role::FinalResult, Error<Role>> async fn handshake<Role, F, S>(stream: S, f: F) -> Result<Role::FinalResult, Error<Role>>
where where
Role: HandshakeRole + Unpin, Role: HandshakeRole + Unpin,
Role::InternalStream: SetWaker, Role::InternalStream: SetWaker + Unpin,
F: FnOnce(AllowStd<S>) -> Result<Role::FinalResult, Error<Role>> + Unpin, F: FnOnce(AllowStd<S>) -> Result<Role::FinalResult, Error<Role>> + Unpin,
S: AsyncRead + AsyncWrite + Unpin, S: AsyncRead + AsyncWrite + Unpin,
{ {
@ -145,13 +143,12 @@ where
impl<Role> Future for MidHandshake<Role> impl<Role> Future for MidHandshake<Role>
where where
Role: HandshakeRole + Unpin, Role: HandshakeRole + Unpin,
Role::InternalStream: SetWaker, Role::InternalStream: SetWaker + Unpin,
{ {
type Output = Result<Role::FinalResult, Error<Role>>; type Output = Result<Role::FinalResult, Error<Role>>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project(); let mut s = self.as_mut().0.take().expect("future polled after completion");
let mut s = this.0.take().expect("future polled after completion");
let machine = s.get_mut(); let machine = s.get_mut();
trace!("Setting context in handshake"); trace!("Setting context in handshake");
@ -161,7 +158,7 @@ where
Ok(stream) => Poll::Ready(Ok(stream)), Ok(stream) => Poll::Ready(Ok(stream)),
Err(Error::Failure(e)) => Poll::Ready(Err(Error::Failure(e))), Err(Error::Failure(e)) => Poll::Ready(Err(Error::Failure(e))),
Err(Error::Interrupted(mid)) => { Err(Error::Interrupted(mid)) => {
*this.0 = Some(mid); self.0 = Some(mid);
Poll::Pending Poll::Pending
} }
} }

@ -3,30 +3,26 @@
//! There is no dependency on actual TLS implementations. Everything like //! There is no dependency on actual TLS implementations. Everything like
//! `native_tls` or `openssl` will work as long as there is a TLS stream supporting standard //! `native_tls` or `openssl` will work as long as there is a TLS stream supporting standard
//! `AsyncRead + AsyncWrite` traits. //! `AsyncRead + AsyncWrite` traits.
use pin_project::{pin_project, project};
use std::pin::Pin; use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use futures::io::{AsyncRead, AsyncWrite}; use futures::io::{AsyncRead, AsyncWrite};
/// Stream, either plain TCP or TLS. /// Stream, either plain TCP or TLS.
#[pin_project]
pub enum Stream<S, T> { pub enum Stream<S, T> {
/// Unencrypted socket stream. /// Unencrypted socket stream.
Plain(#[pin] S), Plain(S),
/// Encrypted socket stream. /// Encrypted socket stream.
Tls(#[pin] T), Tls(T),
} }
impl<S: AsyncRead + Unpin, T: AsyncRead + Unpin> AsyncRead for Stream<S, T> { impl<S: AsyncRead + Unpin, T: AsyncRead + Unpin> AsyncRead for Stream<S, T> {
#[project]
fn poll_read( fn poll_read(
self: Pin<&mut Self>, self: Pin<&mut Self>,
cx: &mut Context<'_>, cx: &mut Context<'_>,
buf: &mut [u8], buf: &mut [u8],
) -> Poll<std::io::Result<usize>> { ) -> Poll<std::io::Result<usize>> {
#[project] match self.get_mut() {
match self.project() {
Stream::Plain(ref mut s) => Pin::new(s).poll_read(cx, buf), Stream::Plain(ref mut s) => Pin::new(s).poll_read(cx, buf),
Stream::Tls(ref mut s) => Pin::new(s).poll_read(cx, buf), Stream::Tls(ref mut s) => Pin::new(s).poll_read(cx, buf),
} }
@ -34,32 +30,26 @@ impl<S: AsyncRead + Unpin, T: AsyncRead + Unpin> AsyncRead for Stream<S, T> {
} }
impl<S: AsyncWrite + Unpin, T: AsyncWrite + Unpin> AsyncWrite for Stream<S, T> { impl<S: AsyncWrite + Unpin, T: AsyncWrite + Unpin> AsyncWrite for Stream<S, T> {
#[project]
fn poll_write( fn poll_write(
self: Pin<&mut Self>, self: Pin<&mut Self>,
cx: &mut Context<'_>, cx: &mut Context<'_>,
buf: &[u8], buf: &[u8],
) -> Poll<Result<usize, std::io::Error>> { ) -> Poll<Result<usize, std::io::Error>> {
#[project] match self.get_mut() {
match self.project() {
Stream::Plain(ref mut s) => Pin::new(s).poll_write(cx, buf), Stream::Plain(ref mut s) => Pin::new(s).poll_write(cx, buf),
Stream::Tls(ref mut s) => Pin::new(s).poll_write(cx, buf), Stream::Tls(ref mut s) => Pin::new(s).poll_write(cx, buf),
} }
} }
#[project]
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> { fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
#[project] match self.get_mut() {
match self.project() {
Stream::Plain(ref mut s) => Pin::new(s).poll_flush(cx), Stream::Plain(ref mut s) => Pin::new(s).poll_flush(cx),
Stream::Tls(ref mut s) => Pin::new(s).poll_flush(cx), Stream::Tls(ref mut s) => Pin::new(s).poll_flush(cx),
} }
} }
#[project]
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> { fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
#[project] match self.get_mut() {
match self.project() {
Stream::Plain(ref mut s) => Pin::new(s).poll_close(cx), Stream::Plain(ref mut s) => Pin::new(s).poll_close(cx),
Stream::Tls(ref mut s) => Pin::new(s).poll_close(cx), Stream::Tls(ref mut s) => Pin::new(s).poll_close(cx),
} }

Loading…
Cancel
Save