1use crate::muxing::StreamMuxerEvent;
22use crate::{
23 muxing::StreamMuxer,
24 transport::{ListenerId, Transport, TransportError, TransportEvent},
25 Multiaddr,
26};
27use either::Either;
28use futures::prelude::*;
29use pin_project::pin_project;
30use std::{pin::Pin, task::Context, task::Poll};
31
32impl<A, B> StreamMuxer for future::Either<A, B>
33where
34 A: StreamMuxer,
35 B: StreamMuxer,
36{
37 type Substream = future::Either<A::Substream, B::Substream>;
38 type Error = Either<A::Error, B::Error>;
39
40 fn poll_inbound(
41 self: Pin<&mut Self>,
42 cx: &mut Context<'_>,
43 ) -> Poll<Result<Self::Substream, Self::Error>> {
44 match self.as_pin_mut() {
45 future::Either::Left(inner) => inner
46 .poll_inbound(cx)
47 .map_ok(future::Either::Left)
48 .map_err(Either::Left),
49 future::Either::Right(inner) => inner
50 .poll_inbound(cx)
51 .map_ok(future::Either::Right)
52 .map_err(Either::Right),
53 }
54 }
55
56 fn poll_outbound(
57 self: Pin<&mut Self>,
58 cx: &mut Context<'_>,
59 ) -> Poll<Result<Self::Substream, Self::Error>> {
60 match self.as_pin_mut() {
61 future::Either::Left(inner) => inner
62 .poll_outbound(cx)
63 .map_ok(future::Either::Left)
64 .map_err(Either::Left),
65 future::Either::Right(inner) => inner
66 .poll_outbound(cx)
67 .map_ok(future::Either::Right)
68 .map_err(Either::Right),
69 }
70 }
71
72 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
73 match self.as_pin_mut() {
74 future::Either::Left(inner) => inner.poll_close(cx).map_err(Either::Left),
75 future::Either::Right(inner) => inner.poll_close(cx).map_err(Either::Right),
76 }
77 }
78
79 fn poll(
80 self: Pin<&mut Self>,
81 cx: &mut Context<'_>,
82 ) -> Poll<Result<StreamMuxerEvent, Self::Error>> {
83 match self.as_pin_mut() {
84 future::Either::Left(inner) => inner.poll(cx).map_err(Either::Left),
85 future::Either::Right(inner) => inner.poll(cx).map_err(Either::Right),
86 }
87 }
88}
89
90#[pin_project(project = EitherFutureProj)]
92#[derive(Debug, Copy, Clone)]
93#[must_use = "futures do nothing unless polled"]
94pub enum EitherFuture<A, B> {
95 First(#[pin] A),
96 Second(#[pin] B),
97}
98
99impl<AFuture, BFuture, AInner, BInner> Future for EitherFuture<AFuture, BFuture>
100where
101 AFuture: TryFuture<Ok = AInner>,
102 BFuture: TryFuture<Ok = BInner>,
103{
104 type Output = Result<future::Either<AInner, BInner>, Either<AFuture::Error, BFuture::Error>>;
105
106 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
107 match self.project() {
108 EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
109 .map_ok(future::Either::Left)
110 .map_err(Either::Left),
111 EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
112 .map_ok(future::Either::Right)
113 .map_err(Either::Right),
114 }
115 }
116}
117
118impl<A, B> Transport for Either<A, B>
119where
120 B: Transport,
121 A: Transport,
122{
123 type Output = future::Either<A::Output, B::Output>;
124 type Error = Either<A::Error, B::Error>;
125 type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
126 type Dial = EitherFuture<A::Dial, B::Dial>;
127
128 fn poll(
129 self: Pin<&mut Self>,
130 cx: &mut Context<'_>,
131 ) -> Poll<TransportEvent<Self::ListenerUpgrade, Self::Error>> {
132 match self.as_pin_mut() {
133 Either::Left(a) => match a.poll(cx) {
134 Poll::Pending => Poll::Pending,
135 Poll::Ready(event) => {
136 Poll::Ready(event.map_upgrade(EitherFuture::First).map_err(Either::Left))
137 }
138 },
139 Either::Right(b) => match b.poll(cx) {
140 Poll::Pending => Poll::Pending,
141 Poll::Ready(event) => Poll::Ready(
142 event
143 .map_upgrade(EitherFuture::Second)
144 .map_err(Either::Right),
145 ),
146 },
147 }
148 }
149
150 fn remove_listener(&mut self, id: ListenerId) -> bool {
151 match self {
152 Either::Left(t) => t.remove_listener(id),
153 Either::Right(t) => t.remove_listener(id),
154 }
155 }
156
157 fn listen_on(
158 &mut self,
159 id: ListenerId,
160 addr: Multiaddr,
161 ) -> Result<(), TransportError<Self::Error>> {
162 use TransportError::*;
163 match self {
164 Either::Left(a) => a.listen_on(id, addr).map_err(|e| match e {
165 MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
166 Other(err) => Other(Either::Left(err)),
167 }),
168 Either::Right(b) => b.listen_on(id, addr).map_err(|e| match e {
169 MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
170 Other(err) => Other(Either::Right(err)),
171 }),
172 }
173 }
174
175 fn dial(&mut self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
176 use TransportError::*;
177 match self {
178 Either::Left(a) => match a.dial(addr) {
179 Ok(connec) => Ok(EitherFuture::First(connec)),
180 Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
181 Err(Other(err)) => Err(Other(Either::Left(err))),
182 },
183 Either::Right(b) => match b.dial(addr) {
184 Ok(connec) => Ok(EitherFuture::Second(connec)),
185 Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
186 Err(Other(err)) => Err(Other(Either::Right(err))),
187 },
188 }
189 }
190
191 fn dial_as_listener(
192 &mut self,
193 addr: Multiaddr,
194 ) -> Result<Self::Dial, TransportError<Self::Error>>
195 where
196 Self: Sized,
197 {
198 use TransportError::*;
199 match self {
200 Either::Left(a) => match a.dial_as_listener(addr) {
201 Ok(connec) => Ok(EitherFuture::First(connec)),
202 Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
203 Err(Other(err)) => Err(Other(Either::Left(err))),
204 },
205 Either::Right(b) => match b.dial_as_listener(addr) {
206 Ok(connec) => Ok(EitherFuture::Second(connec)),
207 Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
208 Err(Other(err)) => Err(Other(Either::Right(err))),
209 },
210 }
211 }
212
213 fn address_translation(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
214 match self {
215 Either::Left(a) => a.address_translation(server, observed),
216 Either::Right(b) => b.address_translation(server, observed),
217 }
218 }
219}