2018-05-02 11:50:48 +02:00
|
|
|
// Copyright 2017 Parity Technologies (UK) Ltd.
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2020-02-10 18:35:51 +01:00
|
|
|
use crate::{
|
2020-06-30 17:10:53 +02:00
|
|
|
muxing::{StreamMuxer, StreamMuxerEvent},
|
2021-08-11 13:12:12 +02:00
|
|
|
transport::{ListenerEvent, Transport, TransportError},
|
|
|
|
Multiaddr, ProtocolName,
|
|
|
|
};
|
|
|
|
use futures::{
|
|
|
|
io::{IoSlice, IoSliceMut},
|
|
|
|
prelude::*,
|
2020-02-10 18:35:51 +01:00
|
|
|
};
|
2020-06-10 01:01:57 +09:00
|
|
|
use pin_project::pin_project;
|
2021-08-11 13:12:12 +02:00
|
|
|
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
|
2018-11-15 17:41:11 +01:00
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub enum EitherError<A, B> {
|
|
|
|
A(A),
|
2021-08-11 13:12:12 +02:00
|
|
|
B(B),
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<A, B> fmt::Display for EitherError<A, B>
|
|
|
|
where
|
|
|
|
A: fmt::Display,
|
2021-08-11 13:12:12 +02:00
|
|
|
B: fmt::Display,
|
2018-11-15 17:41:11 +01:00
|
|
|
{
|
2019-02-11 14:58:15 +01:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
2018-11-15 17:41:11 +01:00
|
|
|
match self {
|
|
|
|
EitherError::A(a) => a.fmt(f),
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherError::B(b) => b.fmt(f),
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<A, B> std::error::Error for EitherError<A, B>
|
|
|
|
where
|
2019-06-04 13:08:37 +02:00
|
|
|
A: std::error::Error,
|
2021-08-11 13:12:12 +02:00
|
|
|
B: std::error::Error,
|
2018-11-15 17:41:11 +01:00
|
|
|
{
|
2018-12-20 13:41:11 +01:00
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
2018-11-15 17:41:11 +01:00
|
|
|
match self {
|
2018-12-20 13:41:11 +01:00
|
|
|
EitherError::A(a) => a.source(),
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherError::B(b) => b.source(),
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
|
|
|
|
/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
|
|
|
|
/// either `First` or `Second`.
|
2020-06-10 01:01:57 +09:00
|
|
|
#[pin_project(project = EitherOutputProj)]
|
2018-05-02 11:50:48 +02:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2018-05-23 11:45:35 +02:00
|
|
|
pub enum EitherOutput<A, B> {
|
2019-12-10 11:46:30 +01:00
|
|
|
First(#[pin] A),
|
|
|
|
Second(#[pin] B),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
|
2018-05-23 11:45:35 +02:00
|
|
|
impl<A, B> AsyncRead for EitherOutput<A, B>
|
2018-05-02 11:50:48 +02:00
|
|
|
where
|
2019-12-10 11:46:30 +01:00
|
|
|
A: AsyncRead,
|
|
|
|
B: AsyncRead,
|
2018-05-02 11:50:48 +02:00
|
|
|
{
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_read(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
buf: &mut [u8],
|
|
|
|
) -> Poll<Result<usize, IoError>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncRead::poll_read(a, cx, buf),
|
|
|
|
EitherOutputProj::Second(b) => AsyncRead::poll_read(b, cx, buf),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
2020-01-02 12:59:10 +01:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_read_vectored(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
bufs: &mut [IoSliceMut<'_>],
|
|
|
|
) -> Poll<Result<usize, IoError>> {
|
2020-01-02 12:59:10 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncRead::poll_read_vectored(a, cx, bufs),
|
|
|
|
EitherOutputProj::Second(b) => AsyncRead::poll_read_vectored(b, cx, bufs),
|
2020-01-02 12:59:10 +01:00
|
|
|
}
|
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
|
2018-05-23 11:45:35 +02:00
|
|
|
impl<A, B> AsyncWrite for EitherOutput<A, B>
|
2018-05-02 11:50:48 +02:00
|
|
|
where
|
2019-12-10 11:46:30 +01:00
|
|
|
A: AsyncWrite,
|
|
|
|
B: AsyncWrite,
|
2018-05-02 11:50:48 +02:00
|
|
|
{
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_write(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
buf: &[u8],
|
|
|
|
) -> Poll<Result<usize, IoError>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncWrite::poll_write(a, cx, buf),
|
|
|
|
EitherOutputProj::Second(b) => AsyncWrite::poll_write(b, cx, buf),
|
2019-09-16 11:08:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_write_vectored(
|
|
|
|
self: Pin<&mut Self>,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
bufs: &[IoSlice<'_>],
|
|
|
|
) -> Poll<Result<usize, IoError>> {
|
2020-01-02 12:59:10 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncWrite::poll_write_vectored(a, cx, bufs),
|
|
|
|
EitherOutputProj::Second(b) => AsyncWrite::poll_write_vectored(b, cx, bufs),
|
2020-01-02 12:59:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), IoError>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncWrite::poll_flush(a, cx),
|
|
|
|
EitherOutputProj::Second(b) => AsyncWrite::poll_flush(b, cx),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), IoError>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => AsyncWrite::poll_close(a, cx),
|
|
|
|
EitherOutputProj::Second(b) => AsyncWrite::poll_close(b, cx),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-05 16:07:13 +02:00
|
|
|
impl<A, B, I> Stream for EitherOutput<A, B>
|
|
|
|
where
|
2019-12-10 11:46:30 +01:00
|
|
|
A: TryStream<Ok = I>,
|
|
|
|
B: TryStream<Ok = I>,
|
2019-06-05 16:07:13 +02:00
|
|
|
{
|
2019-09-16 11:08:44 +02:00
|
|
|
type Item = Result<I, EitherError<A::Error, B::Error>>;
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherOutputProj::First(a) => {
|
|
|
|
TryStream::try_poll_next(a, cx).map(|v| v.map(|r| r.map_err(EitherError::A)))
|
|
|
|
}
|
|
|
|
EitherOutputProj::Second(b) => {
|
|
|
|
TryStream::try_poll_next(b, cx).map(|v| v.map(|r| r.map_err(EitherError::B)))
|
|
|
|
}
|
2019-06-05 16:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-16 11:08:44 +02:00
|
|
|
impl<A, B, I> Sink<I> for EitherOutput<A, B>
|
2019-06-05 16:07:13 +02:00
|
|
|
where
|
2020-01-14 12:03:10 +01:00
|
|
|
A: Sink<I>,
|
|
|
|
B: Sink<I>,
|
2019-06-05 16:07:13 +02:00
|
|
|
{
|
2019-09-16 11:08:44 +02:00
|
|
|
type Error = EitherError<A::Error, B::Error>;
|
2019-06-05 16:07:13 +02:00
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => Sink::poll_ready(a, cx).map_err(EitherError::A),
|
|
|
|
EitherOutputProj::Second(b) => Sink::poll_ready(b, cx).map_err(EitherError::B),
|
2019-06-05 16:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-10 11:46:30 +01:00
|
|
|
fn start_send(self: Pin<&mut Self>, item: I) -> Result<(), Self::Error> {
|
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => Sink::start_send(a, item).map_err(EitherError::A),
|
|
|
|
EitherOutputProj::Second(b) => Sink::start_send(b, item).map_err(EitherError::B),
|
2019-06-05 16:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => Sink::poll_flush(a, cx).map_err(EitherError::A),
|
|
|
|
EitherOutputProj::Second(b) => Sink::poll_flush(b, cx).map_err(EitherError::B),
|
2019-09-16 11:08:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherOutputProj::First(a) => Sink::poll_close(a, cx).map_err(EitherError::A),
|
|
|
|
EitherOutputProj::Second(b) => Sink::poll_close(b, cx).map_err(EitherError::B),
|
2019-06-05 16:07:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-23 11:45:35 +02:00
|
|
|
impl<A, B> StreamMuxer for EitherOutput<A, B>
|
2018-05-02 11:50:48 +02:00
|
|
|
where
|
|
|
|
A: StreamMuxer,
|
|
|
|
B: StreamMuxer,
|
|
|
|
{
|
2018-05-23 11:45:35 +02:00
|
|
|
type Substream = EitherOutput<A::Substream, B::Substream>;
|
2018-05-14 14:49:29 +02:00
|
|
|
type OutboundSubstream = EitherOutbound<A, B>;
|
2019-04-28 14:42:18 +03:00
|
|
|
type Error = IoError;
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_event(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
|
2018-10-17 10:17:40 +01:00
|
|
|
match self {
|
2020-06-30 17:10:53 +02:00
|
|
|
EitherOutput::First(inner) => inner.poll_event(cx).map(|result| {
|
2021-08-11 13:12:12 +02:00
|
|
|
result.map_err(|e| e.into()).map(|event| match event {
|
|
|
|
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
|
|
|
StreamMuxerEvent::InboundSubstream(substream) => {
|
|
|
|
StreamMuxerEvent::InboundSubstream(EitherOutput::First(substream))
|
2020-06-30 17:10:53 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}),
|
|
|
|
EitherOutput::Second(inner) => inner.poll_event(cx).map(|result| {
|
2021-08-11 13:12:12 +02:00
|
|
|
result.map_err(|e| e.into()).map(|event| match event {
|
|
|
|
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
|
|
|
|
StreamMuxerEvent::InboundSubstream(substream) => {
|
|
|
|
StreamMuxerEvent::InboundSubstream(EitherOutput::Second(substream))
|
2020-06-30 17:10:53 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-31 10:31:34 +02:00
|
|
|
fn open_outbound(&self) -> Self::OutboundSubstream {
|
2018-10-17 10:17:40 +01:00
|
|
|
match self {
|
|
|
|
EitherOutput::First(inner) => EitherOutbound::A(inner.open_outbound()),
|
|
|
|
EitherOutput::Second(inner) => EitherOutbound::B(inner.open_outbound()),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn poll_outbound(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
substream: &mut Self::OutboundSubstream,
|
|
|
|
) -> Poll<Result<Self::Substream, Self::Error>> {
|
2018-08-31 10:31:34 +02:00
|
|
|
match (self, substream) {
|
2021-08-11 13:12:12 +02:00
|
|
|
(EitherOutput::First(ref inner), EitherOutbound::A(ref mut substream)) => inner
|
|
|
|
.poll_outbound(cx, substream)
|
|
|
|
.map(|p| p.map(EitherOutput::First))
|
|
|
|
.map_err(|e| e.into()),
|
|
|
|
(EitherOutput::Second(ref inner), EitherOutbound::B(ref mut substream)) => inner
|
|
|
|
.poll_outbound(cx, substream)
|
|
|
|
.map(|p| p.map(EitherOutput::Second))
|
|
|
|
.map_err(|e| e.into()),
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2018-08-31 10:31:34 +02:00
|
|
|
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
2018-10-17 10:17:40 +01:00
|
|
|
match self {
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherOutput::First(inner) => match substream {
|
|
|
|
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
},
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherOutput::Second(inner) => match substream {
|
|
|
|
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn read_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
sub: &mut Self::Substream,
|
|
|
|
buf: &mut [u8],
|
|
|
|
) -> Poll<Result<usize, Self::Error>> {
|
2018-10-11 10:35:14 +02:00
|
|
|
match (self, sub) {
|
|
|
|
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
2018-10-11 10:35:14 +02:00
|
|
|
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn write_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
sub: &mut Self::Substream,
|
|
|
|
buf: &[u8],
|
|
|
|
) -> Poll<Result<usize, Self::Error>> {
|
2018-10-11 10:35:14 +02:00
|
|
|
match (self, sub) {
|
|
|
|
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
2018-10-11 10:35:14 +02:00
|
|
|
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn flush_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
sub: &mut Self::Substream,
|
|
|
|
) -> Poll<Result<(), Self::Error>> {
|
2018-10-11 10:35:14 +02:00
|
|
|
match (self, sub) {
|
|
|
|
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.flush_substream(cx, sub).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
2018-10-11 10:35:14 +02:00
|
|
|
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.flush_substream(cx, sub).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
fn shutdown_substream(
|
|
|
|
&self,
|
|
|
|
cx: &mut Context<'_>,
|
|
|
|
sub: &mut Self::Substream,
|
|
|
|
) -> Poll<Result<(), Self::Error>> {
|
2018-10-11 10:35:14 +02:00
|
|
|
match (self, sub) {
|
|
|
|
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
2018-10-11 10:35:14 +02:00
|
|
|
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
|
2019-09-16 11:08:44 +02:00
|
|
|
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
|
2021-08-11 13:12:12 +02:00
|
|
|
}
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn destroy_substream(&self, substream: Self::Substream) {
|
2018-10-17 10:17:40 +01:00
|
|
|
match self {
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherOutput::First(inner) => match substream {
|
|
|
|
EitherOutput::First(substream) => inner.destroy_substream(substream),
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
},
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherOutput::Second(inner) => match substream {
|
|
|
|
EitherOutput::Second(substream) => inner.destroy_substream(substream),
|
|
|
|
_ => panic!("Wrong API usage"),
|
2018-08-31 10:31:34 +02:00
|
|
|
},
|
2018-05-14 14:49:29 +02:00
|
|
|
}
|
|
|
|
}
|
2018-09-14 13:18:10 +02:00
|
|
|
|
2022-05-29 16:27:40 +02:00
|
|
|
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
2018-10-17 10:17:40 +01:00
|
|
|
match self {
|
2022-05-29 16:27:40 +02:00
|
|
|
EitherOutput::First(inner) => inner.poll_close(cx).map_err(|e| e.into()),
|
|
|
|
EitherOutput::Second(inner) => inner.poll_close(cx).map_err(|e| e.into()),
|
2018-09-14 13:18:10 +02:00
|
|
|
}
|
|
|
|
}
|
2018-05-14 14:49:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
2018-09-04 18:30:57 +08:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-05-14 14:49:29 +02:00
|
|
|
pub enum EitherOutbound<A: StreamMuxer, B: StreamMuxer> {
|
|
|
|
A(A::OutboundSubstream),
|
|
|
|
B(B::OutboundSubstream),
|
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
|
|
|
|
/// Implements `Stream` and dispatches all method calls to either `First` or `Second`.
|
2020-06-10 01:01:57 +09:00
|
|
|
#[pin_project(project = EitherListenStreamProj)]
|
2018-05-02 11:50:48 +02:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2018-09-04 18:30:57 +08:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-05-02 11:50:48 +02:00
|
|
|
pub enum EitherListenStream<A, B> {
|
2019-12-10 11:46:30 +01:00
|
|
|
First(#[pin] A),
|
|
|
|
Second(#[pin] B),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
|
2021-08-11 13:12:12 +02:00
|
|
|
impl<AStream, BStream, AInner, BInner, AError, BError> Stream
|
|
|
|
for EitherListenStream<AStream, BStream>
|
2018-05-02 11:50:48 +02:00
|
|
|
where
|
2020-02-13 12:05:45 +01:00
|
|
|
AStream: TryStream<Ok = ListenerEvent<AInner, AError>, Error = AError>,
|
|
|
|
BStream: TryStream<Ok = ListenerEvent<BInner, BError>, Error = BError>,
|
2018-05-02 11:50:48 +02:00
|
|
|
{
|
2021-08-11 13:12:12 +02:00
|
|
|
type Item = Result<
|
|
|
|
ListenerEvent<EitherFuture<AInner, BInner>, EitherError<AError, BError>>,
|
|
|
|
EitherError<AError, BError>,
|
|
|
|
>;
|
2019-09-16 11:08:44 +02:00
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherListenStreamProj::First(a) => match TryStream::try_poll_next(a, cx) {
|
2019-09-16 11:08:44 +02:00
|
|
|
Poll::Pending => Poll::Pending,
|
|
|
|
Poll::Ready(None) => Poll::Ready(None),
|
2021-08-11 13:12:12 +02:00
|
|
|
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
|
|
|
|
.map(EitherFuture::First)
|
|
|
|
.map_err(EitherError::A)))),
|
2019-09-16 11:08:44 +02:00
|
|
|
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::A(err)))),
|
|
|
|
},
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherListenStreamProj::Second(a) => match TryStream::try_poll_next(a, cx) {
|
2019-09-16 11:08:44 +02:00
|
|
|
Poll::Pending => Poll::Pending,
|
|
|
|
Poll::Ready(None) => Poll::Ready(None),
|
2021-08-11 13:12:12 +02:00
|
|
|
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
|
|
|
|
.map(EitherFuture::Second)
|
|
|
|
.map_err(EitherError::B)))),
|
2019-09-16 11:08:44 +02:00
|
|
|
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::B(err)))),
|
|
|
|
},
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-17 10:17:40 +01:00
|
|
|
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
|
2020-06-10 01:01:57 +09:00
|
|
|
#[pin_project(project = EitherFutureProj)]
|
2018-05-02 11:50:48 +02:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2018-09-04 18:30:57 +08:00
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2018-10-17 10:17:40 +01:00
|
|
|
pub enum EitherFuture<A, B> {
|
2019-12-10 11:46:30 +01:00
|
|
|
First(#[pin] A),
|
|
|
|
Second(#[pin] B),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
|
2018-10-17 10:17:40 +01:00
|
|
|
impl<AFuture, BFuture, AInner, BInner> Future for EitherFuture<AFuture, BFuture>
|
2018-05-02 11:50:48 +02:00
|
|
|
where
|
2019-12-10 11:46:30 +01:00
|
|
|
AFuture: TryFuture<Ok = AInner>,
|
|
|
|
BFuture: TryFuture<Ok = BInner>,
|
2018-05-02 11:50:48 +02:00
|
|
|
{
|
2019-09-16 11:08:44 +02:00
|
|
|
type Output = Result<EitherOutput<AInner, BInner>, EitherError<AFuture::Error, BFuture::Error>>;
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
|
2021-08-11 13:12:12 +02:00
|
|
|
.map_ok(EitherOutput::First)
|
|
|
|
.map_err(EitherError::A),
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
|
2021-08-11 13:12:12 +02:00
|
|
|
.map_ok(EitherOutput::Second)
|
|
|
|
.map_err(EitherError::B),
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-20 15:09:59 +01:00
|
|
|
|
2020-06-10 01:01:57 +09:00
|
|
|
#[pin_project(project = EitherFuture2Proj)]
|
2018-11-20 15:09:59 +01:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
#[must_use = "futures do nothing unless polled"]
|
2021-08-11 13:12:12 +02:00
|
|
|
pub enum EitherFuture2<A, B> {
|
|
|
|
A(#[pin] A),
|
|
|
|
B(#[pin] B),
|
|
|
|
}
|
2018-11-20 15:09:59 +01:00
|
|
|
|
|
|
|
impl<AFut, BFut, AItem, BItem, AError, BError> Future for EitherFuture2<AFut, BFut>
|
|
|
|
where
|
2020-01-14 12:03:10 +01:00
|
|
|
AFut: TryFuture<Ok = AItem, Error = AError>,
|
|
|
|
BFut: TryFuture<Ok = BItem, Error = BError>,
|
2018-11-20 15:09:59 +01:00
|
|
|
{
|
2019-09-16 11:08:44 +02:00
|
|
|
type Output = Result<EitherOutput<AItem, BItem>, EitherError<AError, BError>>;
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
2019-12-10 11:46:30 +01:00
|
|
|
match self.project() {
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherFuture2Proj::A(a) => TryFuture::try_poll(a, cx)
|
2021-08-11 13:12:12 +02:00
|
|
|
.map_ok(EitherOutput::First)
|
|
|
|
.map_err(EitherError::A),
|
2020-06-10 01:01:57 +09:00
|
|
|
EitherFuture2Proj::B(a) => TryFuture::try_poll(a, cx)
|
2021-08-11 13:12:12 +02:00
|
|
|
.map_ok(EitherOutput::Second)
|
|
|
|
.map_err(EitherError::B),
|
2018-11-20 15:09:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-11 15:13:10 +01:00
|
|
|
#[derive(Debug, Clone)]
|
2021-08-11 13:12:12 +02:00
|
|
|
pub enum EitherName<A, B> {
|
|
|
|
A(A),
|
|
|
|
B(B),
|
|
|
|
}
|
2018-12-11 15:13:10 +01:00
|
|
|
|
|
|
|
impl<A: ProtocolName, B: ProtocolName> ProtocolName for EitherName<A, B> {
|
|
|
|
fn protocol_name(&self) -> &[u8] {
|
|
|
|
match self {
|
|
|
|
EitherName::A(a) => a.protocol_name(),
|
2021-08-11 13:12:12 +02:00
|
|
|
EitherName::B(b) => b.protocol_name(),
|
2018-12-11 15:13:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-10 18:35:51 +01:00
|
|
|
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
pub enum EitherTransport<A, B> {
|
|
|
|
Left(A),
|
|
|
|
Right(B),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<A, B> Transport for EitherTransport<A, B>
|
|
|
|
where
|
|
|
|
B: Transport,
|
|
|
|
A: Transport,
|
|
|
|
{
|
|
|
|
type Output = EitherOutput<A::Output, B::Output>;
|
|
|
|
type Error = EitherError<A::Error, B::Error>;
|
|
|
|
type Listener = EitherListenStream<A::Listener, B::Listener>;
|
|
|
|
type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
|
|
|
|
type Dial = EitherFuture<A::Dial, B::Dial>;
|
|
|
|
|
2022-04-06 20:23:16 +02:00
|
|
|
fn listen_on(
|
|
|
|
&mut self,
|
|
|
|
addr: Multiaddr,
|
|
|
|
) -> Result<Self::Listener, TransportError<Self::Error>> {
|
2020-02-10 18:35:51 +01:00
|
|
|
use TransportError::*;
|
|
|
|
match self {
|
|
|
|
EitherTransport::Left(a) => match a.listen_on(addr) {
|
|
|
|
Ok(listener) => Ok(EitherListenStream::First(listener)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::A(err))),
|
|
|
|
},
|
|
|
|
EitherTransport::Right(b) => match b.listen_on(addr) {
|
|
|
|
Ok(listener) => Ok(EitherListenStream::Second(listener)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::B(err))),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-06 20:23:16 +02:00
|
|
|
fn dial(&mut self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
|
2020-02-10 18:35:51 +01:00
|
|
|
use TransportError::*;
|
|
|
|
match self {
|
|
|
|
EitherTransport::Left(a) => match a.dial(addr) {
|
|
|
|
Ok(connec) => Ok(EitherFuture::First(connec)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::A(err))),
|
|
|
|
},
|
|
|
|
EitherTransport::Right(b) => match b.dial(addr) {
|
|
|
|
Ok(connec) => Ok(EitherFuture::Second(connec)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::B(err))),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2021-01-12 13:35:11 +01:00
|
|
|
|
2022-04-06 20:23:16 +02:00
|
|
|
fn dial_as_listener(
|
|
|
|
&mut self,
|
|
|
|
addr: Multiaddr,
|
|
|
|
) -> Result<Self::Dial, TransportError<Self::Error>>
|
2022-01-17 16:35:14 +01:00
|
|
|
where
|
|
|
|
Self: Sized,
|
|
|
|
{
|
|
|
|
use TransportError::*;
|
|
|
|
match self {
|
|
|
|
EitherTransport::Left(a) => match a.dial_as_listener(addr) {
|
|
|
|
Ok(connec) => Ok(EitherFuture::First(connec)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::A(err))),
|
|
|
|
},
|
|
|
|
EitherTransport::Right(b) => match b.dial_as_listener(addr) {
|
|
|
|
Ok(connec) => Ok(EitherFuture::Second(connec)),
|
|
|
|
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
|
|
|
|
Err(Other(err)) => Err(Other(EitherError::B(err))),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-12 13:35:11 +01:00
|
|
|
fn address_translation(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
|
|
|
match self {
|
|
|
|
EitherTransport::Left(a) => a.address_translation(server, observed),
|
|
|
|
EitherTransport::Right(b) => b.address_translation(server, observed),
|
|
|
|
}
|
|
|
|
}
|
2020-02-10 18:35:51 +01:00
|
|
|
}
|