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