1use crate::behaviour::{self, NetworkBehaviour, 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) {
126 match self {
127 Either::Left(b) => b.on_swarm_event(event),
128 Either::Right(b) => b.on_swarm_event(event),
129 }
130 }
131
132 fn on_connection_handler_event(
133 &mut self,
134 peer_id: PeerId,
135 connection_id: ConnectionId,
136 event: THandlerOutEvent<Self>,
137 ) {
138 match (self, event) {
139 (Either::Left(left), Either::Left(event)) => {
140 left.on_connection_handler_event(peer_id, connection_id, event);
141 }
142 (Either::Right(right), Either::Right(event)) => {
143 right.on_connection_handler_event(peer_id, connection_id, event);
144 }
145 _ => unreachable!(),
146 }
147 }
148
149 fn poll(
150 &mut self,
151 cx: &mut Context<'_>,
152 ) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
153 let event = match self {
154 Either::Left(behaviour) => futures::ready!(behaviour.poll(cx))
155 .map_out(Either::Left)
156 .map_in(Either::Left),
157 Either::Right(behaviour) => futures::ready!(behaviour.poll(cx))
158 .map_out(Either::Right)
159 .map_in(Either::Right),
160 };
161
162 Poll::Ready(event)
163 }
164}