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