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

@ -3,30 +3,26 @@
//! 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
//! `AsyncRead + AsyncWrite` traits.
use pin_project::{pin_project, project};
use std::pin::Pin;
use std::task::{Context, Poll};
use futures::io::{AsyncRead, AsyncWrite};
/// Stream, either plain TCP or TLS.
#[pin_project]
pub enum Stream<S, T> {
/// Unencrypted socket stream.
Plain(#[pin] S),
Plain(S),
/// Encrypted socket stream.
Tls(#[pin] T),
Tls(T),
}
impl<S: AsyncRead + Unpin, T: AsyncRead + Unpin> AsyncRead for Stream<S, T> {
#[project]
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<std::io::Result<usize>> {
#[project]
match self.project() {
match self.get_mut() {
Stream::Plain(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> {
#[project]
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, std::io::Error>> {
#[project]
match self.project() {
match self.get_mut() {
Stream::Plain(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>> {
#[project]
match self.project() {
match self.get_mut() {
Stream::Plain(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>> {
#[project]
match self.project() {
match self.get_mut() {
Stream::Plain(ref mut s) => Pin::new(s).poll_close(cx),
Stream::Tls(ref mut s) => Pin::new(s).poll_close(cx),
}

Loading…
Cancel
Save