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