#[allow(deprecated)]
use crate::handler::IntoConnectionHandler;
use crate::handler::{
ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound,
InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol,
};
use crate::upgrade::SendWrapper;
use crate::ConnectionHandlerUpgrErr;
use either::Either;
use futures::future;
use libp2p_core::{ConnectedPoint, UpgradeError};
use libp2p_identity::PeerId;
use std::task::{Context, Poll};
pub enum IntoEitherHandler<L, R> {
Left(L),
Right(R),
}
#[allow(deprecated)]
impl<L, R> IntoConnectionHandler for IntoEitherHandler<L, R>
where
L: IntoConnectionHandler,
R: IntoConnectionHandler,
{
type Handler = Either<L::Handler, R::Handler>;
fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler {
match self {
IntoEitherHandler::Left(into_handler) => Either::Left(into_handler.into_handler(p, c)),
IntoEitherHandler::Right(into_handler) => {
Either::Right(into_handler.into_handler(p, c))
}
}
}
fn inbound_protocol(&self) -> <Self::Handler as ConnectionHandler>::InboundProtocol {
match self {
IntoEitherHandler::Left(into_handler) => {
Either::Left(SendWrapper(into_handler.inbound_protocol()))
}
IntoEitherHandler::Right(into_handler) => {
Either::Right(SendWrapper(into_handler.inbound_protocol()))
}
}
}
}
impl<L, R> IntoEitherHandler<L, R> {
pub fn unwrap_left(self) -> L {
match self {
IntoEitherHandler::Left(l) => l,
IntoEitherHandler::Right(_) => {
panic!("called `IntoEitherHandler::unwrap_left()` on a `Right` value.",)
}
}
}
pub fn unwrap_right(self) -> R {
match self {
IntoEitherHandler::Right(r) => r,
IntoEitherHandler::Left(_) => {
panic!("called `IntoEitherHandler::unwrap_right()` on a `Left` value.",)
}
}
}
}
impl<LIP, RIP, LIOI, RIOI>
FullyNegotiatedInbound<Either<SendWrapper<LIP>, SendWrapper<RIP>>, Either<LIOI, RIOI>>
where
RIP: InboundUpgradeSend,
LIP: InboundUpgradeSend,
{
pub(crate) fn transpose(
self,
) -> Either<FullyNegotiatedInbound<LIP, LIOI>, FullyNegotiatedInbound<RIP, RIOI>> {
match self {
FullyNegotiatedInbound {
protocol: future::Either::Left(protocol),
info: Either::Left(info),
} => Either::Left(FullyNegotiatedInbound { protocol, info }),
FullyNegotiatedInbound {
protocol: future::Either::Right(protocol),
info: Either::Right(info),
} => Either::Right(FullyNegotiatedInbound { protocol, info }),
_ => unreachable!(),
}
}
}
impl<LIP, RIP, LIOI, RIOI>
ListenUpgradeError<Either<LIOI, RIOI>, Either<SendWrapper<LIP>, SendWrapper<RIP>>>
where
RIP: InboundUpgradeSend,
LIP: InboundUpgradeSend,
{
fn transpose(self) -> Either<ListenUpgradeError<LIOI, LIP>, ListenUpgradeError<RIOI, RIP>> {
match self {
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(error))),
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(error))),
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info,
}),
_ => unreachable!(),
}
}
}
impl<L, R> ConnectionHandler for Either<L, R>
where
L: ConnectionHandler,
R: ConnectionHandler,
{
type InEvent = Either<L::InEvent, R::InEvent>;
type OutEvent = Either<L::OutEvent, R::OutEvent>;
type Error = Either<L::Error, R::Error>;
type InboundProtocol = Either<SendWrapper<L::InboundProtocol>, SendWrapper<R::InboundProtocol>>;
type OutboundProtocol =
Either<SendWrapper<L::OutboundProtocol>, SendWrapper<R::OutboundProtocol>>;
type InboundOpenInfo = Either<L::InboundOpenInfo, R::InboundOpenInfo>;
type OutboundOpenInfo = Either<L::OutboundOpenInfo, R::OutboundOpenInfo>;
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo> {
match self {
Either::Left(a) => a
.listen_protocol()
.map_upgrade(|u| Either::Left(SendWrapper(u)))
.map_info(Either::Left),
Either::Right(b) => b
.listen_protocol()
.map_upgrade(|u| Either::Right(SendWrapper(u)))
.map_info(Either::Right),
}
}
fn on_behaviour_event(&mut self, event: Self::InEvent) {
match (self, event) {
(Either::Left(handler), Either::Left(event)) => handler.on_behaviour_event(event),
(Either::Right(handler), Either::Right(event)) => handler.on_behaviour_event(event),
_ => unreachable!(),
}
}
fn connection_keep_alive(&self) -> KeepAlive {
match self {
Either::Left(handler) => handler.connection_keep_alive(),
Either::Right(handler) => handler.connection_keep_alive(),
}
}
fn poll(
&mut self,
cx: &mut Context<'_>,
) -> Poll<
ConnectionHandlerEvent<
Self::OutboundProtocol,
Self::OutboundOpenInfo,
Self::OutEvent,
Self::Error,
>,
> {
let event = match self {
Either::Left(handler) => futures::ready!(handler.poll(cx))
.map_custom(Either::Left)
.map_close(Either::Left)
.map_protocol(|p| Either::Left(SendWrapper(p)))
.map_outbound_open_info(Either::Left),
Either::Right(handler) => futures::ready!(handler.poll(cx))
.map_custom(Either::Right)
.map_close(Either::Right)
.map_protocol(|p| Either::Right(SendWrapper(p)))
.map_outbound_open_info(Either::Right),
};
Poll::Ready(event)
}
fn on_connection_event(
&mut self,
event: ConnectionEvent<
Self::InboundProtocol,
Self::OutboundProtocol,
Self::InboundOpenInfo,
Self::OutboundOpenInfo,
>,
) {
match event {
ConnectionEvent::FullyNegotiatedInbound(fully_negotiated_inbound) => {
match (fully_negotiated_inbound.transpose(), self) {
(Either::Left(fully_negotiated_inbound), Either::Left(handler)) => handler
.on_connection_event(ConnectionEvent::FullyNegotiatedInbound(
fully_negotiated_inbound,
)),
(Either::Right(fully_negotiated_inbound), Either::Right(handler)) => handler
.on_connection_event(ConnectionEvent::FullyNegotiatedInbound(
fully_negotiated_inbound,
)),
_ => unreachable!(),
}
}
ConnectionEvent::FullyNegotiatedOutbound(fully_negotiated_outbound) => {
match (fully_negotiated_outbound.transpose(), self) {
(Either::Left(fully_negotiated_outbound), Either::Left(handler)) => handler
.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
fully_negotiated_outbound,
)),
(Either::Right(fully_negotiated_outbound), Either::Right(handler)) => handler
.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
fully_negotiated_outbound,
)),
_ => unreachable!(),
}
}
ConnectionEvent::DialUpgradeError(dial_upgrade_error) => {
match (dial_upgrade_error.transpose(), self) {
(Either::Left(dial_upgrade_error), Either::Left(handler)) => handler
.on_connection_event(ConnectionEvent::DialUpgradeError(dial_upgrade_error)),
(Either::Right(dial_upgrade_error), Either::Right(handler)) => handler
.on_connection_event(ConnectionEvent::DialUpgradeError(dial_upgrade_error)),
_ => unreachable!(),
}
}
ConnectionEvent::ListenUpgradeError(listen_upgrade_error) => {
match (listen_upgrade_error.transpose(), self) {
(Either::Left(listen_upgrade_error), Either::Left(handler)) => handler
.on_connection_event(ConnectionEvent::ListenUpgradeError(
listen_upgrade_error,
)),
(Either::Right(listen_upgrade_error), Either::Right(handler)) => handler
.on_connection_event(ConnectionEvent::ListenUpgradeError(
listen_upgrade_error,
)),
_ => unreachable!(),
}
}
ConnectionEvent::AddressChange(address_change) => match self {
Either::Left(handler) => {
handler.on_connection_event(ConnectionEvent::AddressChange(address_change))
}
Either::Right(handler) => {
handler.on_connection_event(ConnectionEvent::AddressChange(address_change))
}
},
}
}
}