1use crate::behaviour::{self, NetworkBehaviour, ToSwarm};
22use crate::connection::ConnectionId;
23use crate::{ConnectionDenied, THandler, THandlerInEvent, THandlerOutEvent};
24use either::Either;
25use libp2p_core::transport::PortUse;
26use libp2p_core::{Endpoint, Multiaddr};
27use libp2p_identity::PeerId;
28use std::{task::Context, task::Poll};
29
30impl<L, R> NetworkBehaviour for Either<L, R>
32where
33 L: NetworkBehaviour,
34 R: NetworkBehaviour,
35{
36 type ConnectionHandler = Either<THandler<L>, THandler<R>>;
37 type ToSwarm = Either<L::ToSwarm, R::ToSwarm>;
38
39 fn handle_pending_inbound_connection(
40 &mut self,
41 id: ConnectionId,
42 local_addr: &Multiaddr,
43 remote_addr: &Multiaddr,
44 ) -> Result<(), ConnectionDenied> {
45 match self {
46 Either::Left(a) => a.handle_pending_inbound_connection(id, local_addr, remote_addr),
47 Either::Right(b) => b.handle_pending_inbound_connection(id, local_addr, remote_addr),
48 }
49 }
50
51 fn handle_established_inbound_connection(
52 &mut self,
53 connection_id: ConnectionId,
54 peer: PeerId,
55 local_addr: &Multiaddr,
56 remote_addr: &Multiaddr,
57 ) -> Result<THandler<Self>, ConnectionDenied> {
58 let handler = match self {
59 Either::Left(inner) => Either::Left(inner.handle_established_inbound_connection(
60 connection_id,
61 peer,
62 local_addr,
63 remote_addr,
64 )?),
65 Either::Right(inner) => Either::Right(inner.handle_established_inbound_connection(
66 connection_id,
67 peer,
68 local_addr,
69 remote_addr,
70 )?),
71 };
72
73 Ok(handler)
74 }
75
76 fn handle_pending_outbound_connection(
77 &mut self,
78 connection_id: ConnectionId,
79 maybe_peer: Option<PeerId>,
80 addresses: &[Multiaddr],
81 effective_role: Endpoint,
82 ) -> Result<Vec<Multiaddr>, ConnectionDenied> {
83 let addresses = match self {
84 Either::Left(inner) => inner.handle_pending_outbound_connection(
85 connection_id,
86 maybe_peer,
87 addresses,
88 effective_role,
89 )?,
90 Either::Right(inner) => inner.handle_pending_outbound_connection(
91 connection_id,
92 maybe_peer,
93 addresses,
94 effective_role,
95 )?,
96 };
97
98 Ok(addresses)
99 }
100
101 fn handle_established_outbound_connection(
102 &mut self,
103 connection_id: ConnectionId,
104 peer: PeerId,
105 addr: &Multiaddr,
106 role_override: Endpoint,
107 port_use: PortUse,
108 ) -> Result<THandler<Self>, ConnectionDenied> {
109 let handler = match self {
110 Either::Left(inner) => Either::Left(inner.handle_established_outbound_connection(
111 connection_id,
112 peer,
113 addr,
114 role_override,
115 port_use,
116 )?),
117 Either::Right(inner) => Either::Right(inner.handle_established_outbound_connection(
118 connection_id,
119 peer,
120 addr,
121 role_override,
122 port_use,
123 )?),
124 };
125
126 Ok(handler)
127 }
128
129 fn on_swarm_event(&mut self, event: behaviour::FromSwarm) {
130 match self {
131 Either::Left(b) => b.on_swarm_event(event),
132 Either::Right(b) => b.on_swarm_event(event),
133 }
134 }
135
136 fn on_connection_handler_event(
137 &mut self,
138 peer_id: PeerId,
139 connection_id: ConnectionId,
140 event: THandlerOutEvent<Self>,
141 ) {
142 match (self, event) {
143 (Either::Left(left), Either::Left(event)) => {
144 left.on_connection_handler_event(peer_id, connection_id, event);
145 }
146 (Either::Right(right), Either::Right(event)) => {
147 right.on_connection_handler_event(peer_id, connection_id, event);
148 }
149 _ => unreachable!(),
150 }
151 }
152
153 fn poll(
154 &mut self,
155 cx: &mut Context<'_>,
156 ) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
157 let event = match self {
158 Either::Left(behaviour) => futures::ready!(behaviour.poll(cx))
159 .map_out(Either::Left)
160 .map_in(Either::Left),
161 Either::Right(behaviour) => futures::ready!(behaviour.poll(cx))
162 .map_out(Either::Right)
163 .map_in(Either::Right),
164 };
165
166 Poll::Ready(event)
167 }
168}