libp2p_swarm/handler/
either.rs

1// Copyright 2021 Protocol Labs.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21use crate::handler::{
22    ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound,
23    InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol,
24};
25use crate::upgrade::SendWrapper;
26use either::Either;
27use futures::future;
28use std::task::{Context, Poll};
29
30impl<LIP, RIP, LIOI, RIOI>
31    FullyNegotiatedInbound<Either<SendWrapper<LIP>, SendWrapper<RIP>>, Either<LIOI, RIOI>>
32where
33    RIP: InboundUpgradeSend,
34    LIP: InboundUpgradeSend,
35{
36    pub(crate) fn transpose(
37        self,
38    ) -> Either<FullyNegotiatedInbound<LIP, LIOI>, FullyNegotiatedInbound<RIP, RIOI>> {
39        match self {
40            FullyNegotiatedInbound {
41                protocol: future::Either::Left(protocol),
42                info: Either::Left(info),
43            } => Either::Left(FullyNegotiatedInbound { protocol, info }),
44            FullyNegotiatedInbound {
45                protocol: future::Either::Right(protocol),
46                info: Either::Right(info),
47            } => Either::Right(FullyNegotiatedInbound { protocol, info }),
48            _ => unreachable!(),
49        }
50    }
51}
52
53impl<LIP, RIP, LIOI, RIOI>
54    ListenUpgradeError<Either<LIOI, RIOI>, Either<SendWrapper<LIP>, SendWrapper<RIP>>>
55where
56    RIP: InboundUpgradeSend,
57    LIP: InboundUpgradeSend,
58{
59    fn transpose(self) -> Either<ListenUpgradeError<LIOI, LIP>, ListenUpgradeError<RIOI, RIP>> {
60        match self {
61            ListenUpgradeError {
62                error: Either::Left(error),
63                info: Either::Left(info),
64            } => Either::Left(ListenUpgradeError { error, info }),
65            ListenUpgradeError {
66                error: Either::Right(error),
67                info: Either::Right(info),
68            } => Either::Right(ListenUpgradeError { error, info }),
69            _ => unreachable!(),
70        }
71    }
72}
73
74/// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`]
75/// implementations.
76impl<L, R> ConnectionHandler for Either<L, R>
77where
78    L: ConnectionHandler,
79    R: ConnectionHandler,
80{
81    type FromBehaviour = Either<L::FromBehaviour, R::FromBehaviour>;
82    type ToBehaviour = Either<L::ToBehaviour, R::ToBehaviour>;
83    #[allow(deprecated)]
84    type Error = Either<L::Error, R::Error>;
85    type InboundProtocol = Either<SendWrapper<L::InboundProtocol>, SendWrapper<R::InboundProtocol>>;
86    type OutboundProtocol =
87        Either<SendWrapper<L::OutboundProtocol>, SendWrapper<R::OutboundProtocol>>;
88    type InboundOpenInfo = Either<L::InboundOpenInfo, R::InboundOpenInfo>;
89    type OutboundOpenInfo = Either<L::OutboundOpenInfo, R::OutboundOpenInfo>;
90
91    fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo> {
92        match self {
93            Either::Left(a) => a
94                .listen_protocol()
95                .map_upgrade(|u| Either::Left(SendWrapper(u)))
96                .map_info(Either::Left),
97            Either::Right(b) => b
98                .listen_protocol()
99                .map_upgrade(|u| Either::Right(SendWrapper(u)))
100                .map_info(Either::Right),
101        }
102    }
103
104    fn on_behaviour_event(&mut self, event: Self::FromBehaviour) {
105        match (self, event) {
106            (Either::Left(handler), Either::Left(event)) => handler.on_behaviour_event(event),
107            (Either::Right(handler), Either::Right(event)) => handler.on_behaviour_event(event),
108            _ => unreachable!(),
109        }
110    }
111
112    fn connection_keep_alive(&self) -> KeepAlive {
113        match self {
114            Either::Left(handler) => handler.connection_keep_alive(),
115            Either::Right(handler) => handler.connection_keep_alive(),
116        }
117    }
118
119    #[allow(deprecated)]
120    fn poll(
121        &mut self,
122        cx: &mut Context<'_>,
123    ) -> Poll<
124        ConnectionHandlerEvent<
125            Self::OutboundProtocol,
126            Self::OutboundOpenInfo,
127            Self::ToBehaviour,
128            Self::Error,
129        >,
130    > {
131        let event = match self {
132            Either::Left(handler) => futures::ready!(handler.poll(cx))
133                .map_custom(Either::Left)
134                .map_close(Either::Left)
135                .map_protocol(|p| Either::Left(SendWrapper(p)))
136                .map_outbound_open_info(Either::Left),
137            Either::Right(handler) => futures::ready!(handler.poll(cx))
138                .map_custom(Either::Right)
139                .map_close(Either::Right)
140                .map_protocol(|p| Either::Right(SendWrapper(p)))
141                .map_outbound_open_info(Either::Right),
142        };
143
144        Poll::Ready(event)
145    }
146
147    fn on_connection_event(
148        &mut self,
149        event: ConnectionEvent<
150            Self::InboundProtocol,
151            Self::OutboundProtocol,
152            Self::InboundOpenInfo,
153            Self::OutboundOpenInfo,
154        >,
155    ) {
156        match event {
157            ConnectionEvent::FullyNegotiatedInbound(fully_negotiated_inbound) => {
158                match (fully_negotiated_inbound.transpose(), self) {
159                    (Either::Left(fully_negotiated_inbound), Either::Left(handler)) => handler
160                        .on_connection_event(ConnectionEvent::FullyNegotiatedInbound(
161                            fully_negotiated_inbound,
162                        )),
163                    (Either::Right(fully_negotiated_inbound), Either::Right(handler)) => handler
164                        .on_connection_event(ConnectionEvent::FullyNegotiatedInbound(
165                            fully_negotiated_inbound,
166                        )),
167                    _ => unreachable!(),
168                }
169            }
170            ConnectionEvent::FullyNegotiatedOutbound(fully_negotiated_outbound) => {
171                match (fully_negotiated_outbound.transpose(), self) {
172                    (Either::Left(fully_negotiated_outbound), Either::Left(handler)) => handler
173                        .on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
174                            fully_negotiated_outbound,
175                        )),
176                    (Either::Right(fully_negotiated_outbound), Either::Right(handler)) => handler
177                        .on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
178                            fully_negotiated_outbound,
179                        )),
180                    _ => unreachable!(),
181                }
182            }
183            ConnectionEvent::DialUpgradeError(dial_upgrade_error) => {
184                match (dial_upgrade_error.transpose(), self) {
185                    (Either::Left(dial_upgrade_error), Either::Left(handler)) => handler
186                        .on_connection_event(ConnectionEvent::DialUpgradeError(dial_upgrade_error)),
187                    (Either::Right(dial_upgrade_error), Either::Right(handler)) => handler
188                        .on_connection_event(ConnectionEvent::DialUpgradeError(dial_upgrade_error)),
189                    _ => unreachable!(),
190                }
191            }
192            ConnectionEvent::ListenUpgradeError(listen_upgrade_error) => {
193                match (listen_upgrade_error.transpose(), self) {
194                    (Either::Left(listen_upgrade_error), Either::Left(handler)) => handler
195                        .on_connection_event(ConnectionEvent::ListenUpgradeError(
196                            listen_upgrade_error,
197                        )),
198                    (Either::Right(listen_upgrade_error), Either::Right(handler)) => handler
199                        .on_connection_event(ConnectionEvent::ListenUpgradeError(
200                            listen_upgrade_error,
201                        )),
202                    _ => unreachable!(),
203                }
204            }
205            ConnectionEvent::AddressChange(address_change) => match self {
206                Either::Left(handler) => {
207                    handler.on_connection_event(ConnectionEvent::AddressChange(address_change))
208                }
209                Either::Right(handler) => {
210                    handler.on_connection_event(ConnectionEvent::AddressChange(address_change))
211                }
212            },
213            ConnectionEvent::LocalProtocolsChange(supported_protocols) => match self {
214                Either::Left(handler) => handler.on_connection_event(
215                    ConnectionEvent::LocalProtocolsChange(supported_protocols),
216                ),
217                Either::Right(handler) => handler.on_connection_event(
218                    ConnectionEvent::LocalProtocolsChange(supported_protocols),
219                ),
220            },
221            ConnectionEvent::RemoteProtocolsChange(supported_protocols) => match self {
222                Either::Left(handler) => handler.on_connection_event(
223                    ConnectionEvent::RemoteProtocolsChange(supported_protocols),
224                ),
225                Either::Right(handler) => handler.on_connection_event(
226                    ConnectionEvent::RemoteProtocolsChange(supported_protocols),
227                ),
228            },
229        }
230    }
231}