diff --git a/core/Cargo.toml b/core/Cargo.toml
index 8884097cbc2..2e1b18cb52f 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -25,6 +25,7 @@ multiaddr = { package = "parity-multiaddr", version = "0.6.0", path = "../misc/m
multihash = { package = "parity-multihash", version = "0.2.0", path = "../misc/multihash" }
multistream-select = { version = "0.6.0", path = "../misc/multistream-select" }
parking_lot = "0.9.0"
+pin-project = "0.4.6"
protobuf = "2.8"
quick-error = "1.2"
rand = "0.7"
diff --git a/core/src/either.rs b/core/src/either.rs
index f1b69e41bc6..0d0fc794a7b 100644
--- a/core/src/either.rs
+++ b/core/src/either.rs
@@ -20,7 +20,8 @@
use crate::{muxing::StreamMuxer, ProtocolName, transport::ListenerEvent};
use futures::prelude::*;
-use std::{fmt, io::{Error as IoError, Read, Write}, pin::Pin, task::Context, task::Poll};
+use pin_project::{pin_project, project};
+use std::{fmt, io::{Error as IoError}, pin::Pin, task::Context, task::Poll};
#[derive(Debug, Copy, Clone)]
pub enum EitherError {
@@ -56,99 +57,75 @@ where
/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
/// either `First` or `Second`.
+#[pin_project]
#[derive(Debug, Copy, Clone)]
pub enum EitherOutput {
- First(A),
- Second(B),
+ First(#[pin] A),
+ Second(#[pin] B),
}
impl AsyncRead for EitherOutput
where
- A: AsyncRead + Unpin,
- B: AsyncRead + Unpin,
+ A: AsyncRead,
+ B: AsyncRead,
{
- fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll> {
- match &mut *self {
- EitherOutput::First(a) => AsyncRead::poll_read(Pin::new(a), cx, buf),
- EitherOutput::Second(b) => AsyncRead::poll_read(Pin::new(b), cx, buf),
- }
- }
-}
-
-// TODO: remove?
-impl Read for EitherOutput
-where
- A: Read,
- B: Read,
-{
- fn read(&mut self, buf: &mut [u8]) -> Result {
- match self {
- EitherOutput::First(a) => a.read(buf),
- EitherOutput::Second(b) => b.read(buf),
+ #[project]
+ fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll> {
+ #[project]
+ match self.project() {
+ EitherOutput::First(a) => AsyncRead::poll_read(a, cx, buf),
+ EitherOutput::Second(b) => AsyncRead::poll_read(b, cx, buf),
}
}
}
impl AsyncWrite for EitherOutput
where
- A: AsyncWrite + Unpin,
- B: AsyncWrite + Unpin,
+ A: AsyncWrite,
+ B: AsyncWrite,
{
- fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll> {
- match &mut *self {
- EitherOutput::First(a) => AsyncWrite::poll_write(Pin::new(a), cx, buf),
- EitherOutput::Second(b) => AsyncWrite::poll_write(Pin::new(b), cx, buf),
- }
- }
-
- fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> {
- match &mut *self {
- EitherOutput::First(a) => AsyncWrite::poll_flush(Pin::new(a), cx),
- EitherOutput::Second(b) => AsyncWrite::poll_flush(Pin::new(b), cx),
+ #[project]
+ fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll> {
+ #[project]
+ match self.project() {
+ EitherOutput::First(a) => AsyncWrite::poll_write(a, cx, buf),
+ EitherOutput::Second(b) => AsyncWrite::poll_write(b, cx, buf),
}
}
- fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> {
- match &mut *self {
- EitherOutput::First(a) => AsyncWrite::poll_close(Pin::new(a), cx),
- EitherOutput::Second(b) => AsyncWrite::poll_close(Pin::new(b), cx),
+ #[project]
+ fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll> {
+ #[project]
+ match self.project() {
+ EitherOutput::First(a) => AsyncWrite::poll_flush(a, cx),
+ EitherOutput::Second(b) => AsyncWrite::poll_flush(b, cx),
}
}
-}
-// TODO: remove?
-impl Write for EitherOutput
-where
- A: Write,
- B: Write,
-{
- fn write(&mut self, buf: &[u8]) -> Result {
- match self {
- EitherOutput::First(a) => a.write(buf),
- EitherOutput::Second(b) => b.write(buf),
- }
- }
-
- fn flush(&mut self) -> Result<(), IoError> {
- match self {
- EitherOutput::First(a) => a.flush(),
- EitherOutput::Second(b) => b.flush(),
+ #[project]
+ fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll> {
+ #[project]
+ match self.project() {
+ EitherOutput::First(a) => AsyncWrite::poll_close(a, cx),
+ EitherOutput::Second(b) => AsyncWrite::poll_close(b, cx),
}
}
}
impl Stream for EitherOutput
where
- A: TryStream + Unpin,
- B: TryStream + Unpin,
+ A: TryStream,
+ B: TryStream,
{
type Item = Result>;
- fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll