1use core::pin::Pin;
2use core::task::{Context, Poll};
3use futures_core::future::{FusedFuture, Future};
4use futures_core::stream::{FusedStream, Stream};
5#[cfg(feature = "sink")]
6use futures_sink::Sink;
7
8#[derive(Debug, Clone)]
28pub enum Either<A, B> {
29 Left(A),
31 Right(B),
33}
34
35impl<A, B> Either<A, B> {
36 pub fn as_pin_ref(self: Pin<&Self>) -> Either<Pin<&A>, Pin<&B>> {
39 unsafe {
42 match self.get_ref() {
43 Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
44 Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
45 }
46 }
47 }
48
49 pub fn as_pin_mut(self: Pin<&mut Self>) -> Either<Pin<&mut A>, Pin<&mut B>> {
52 unsafe {
58 match self.get_unchecked_mut() {
59 Self::Left(inner) => Either::Left(Pin::new_unchecked(inner)),
60 Self::Right(inner) => Either::Right(Pin::new_unchecked(inner)),
61 }
62 }
63 }
64}
65
66impl<A, B, T> Either<(T, A), (T, B)> {
67 pub fn factor_first(self) -> (T, Either<A, B>) {
71 match self {
72 Self::Left((x, a)) => (x, Either::Left(a)),
73 Self::Right((x, b)) => (x, Either::Right(b)),
74 }
75 }
76}
77
78impl<A, B, T> Either<(A, T), (B, T)> {
79 pub fn factor_second(self) -> (Either<A, B>, T) {
83 match self {
84 Self::Left((a, x)) => (Either::Left(a), x),
85 Self::Right((b, x)) => (Either::Right(b), x),
86 }
87 }
88}
89
90impl<T> Either<T, T> {
91 pub fn into_inner(self) -> T {
93 match self {
94 Self::Left(x) | Self::Right(x) => x,
95 }
96 }
97}
98
99impl<A, B> Future for Either<A, B>
100where
101 A: Future,
102 B: Future<Output = A::Output>,
103{
104 type Output = A::Output;
105
106 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
107 match self.as_pin_mut() {
108 Either::Left(x) => x.poll(cx),
109 Either::Right(x) => x.poll(cx),
110 }
111 }
112}
113
114impl<A, B> FusedFuture for Either<A, B>
115where
116 A: FusedFuture,
117 B: FusedFuture<Output = A::Output>,
118{
119 fn is_terminated(&self) -> bool {
120 match self {
121 Self::Left(x) => x.is_terminated(),
122 Self::Right(x) => x.is_terminated(),
123 }
124 }
125}
126
127impl<A, B> Stream for Either<A, B>
128where
129 A: Stream,
130 B: Stream<Item = A::Item>,
131{
132 type Item = A::Item;
133
134 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
135 match self.as_pin_mut() {
136 Either::Left(x) => x.poll_next(cx),
137 Either::Right(x) => x.poll_next(cx),
138 }
139 }
140
141 fn size_hint(&self) -> (usize, Option<usize>) {
142 match self {
143 Self::Left(x) => x.size_hint(),
144 Self::Right(x) => x.size_hint(),
145 }
146 }
147}
148
149impl<A, B> FusedStream for Either<A, B>
150where
151 A: FusedStream,
152 B: FusedStream<Item = A::Item>,
153{
154 fn is_terminated(&self) -> bool {
155 match self {
156 Self::Left(x) => x.is_terminated(),
157 Self::Right(x) => x.is_terminated(),
158 }
159 }
160}
161
162#[cfg(feature = "sink")]
163impl<A, B, Item> Sink<Item> for Either<A, B>
164where
165 A: Sink<Item>,
166 B: Sink<Item, Error = A::Error>,
167{
168 type Error = A::Error;
169
170 fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
171 match self.as_pin_mut() {
172 Either::Left(x) => x.poll_ready(cx),
173 Either::Right(x) => x.poll_ready(cx),
174 }
175 }
176
177 fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
178 match self.as_pin_mut() {
179 Either::Left(x) => x.start_send(item),
180 Either::Right(x) => x.start_send(item),
181 }
182 }
183
184 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
185 match self.as_pin_mut() {
186 Either::Left(x) => x.poll_flush(cx),
187 Either::Right(x) => x.poll_flush(cx),
188 }
189 }
190
191 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
192 match self.as_pin_mut() {
193 Either::Left(x) => x.poll_close(cx),
194 Either::Right(x) => x.poll_close(cx),
195 }
196 }
197}
198
199#[cfg(feature = "io")]
200#[cfg(feature = "std")]
201mod if_std {
202 use super::*;
203
204 use futures_io::{
205 AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, IoSlice, IoSliceMut, Result, SeekFrom,
206 };
207
208 impl<A, B> AsyncRead for Either<A, B>
209 where
210 A: AsyncRead,
211 B: AsyncRead,
212 {
213 fn poll_read(
214 self: Pin<&mut Self>,
215 cx: &mut Context<'_>,
216 buf: &mut [u8],
217 ) -> Poll<Result<usize>> {
218 match self.as_pin_mut() {
219 Either::Left(x) => x.poll_read(cx, buf),
220 Either::Right(x) => x.poll_read(cx, buf),
221 }
222 }
223
224 fn poll_read_vectored(
225 self: Pin<&mut Self>,
226 cx: &mut Context<'_>,
227 bufs: &mut [IoSliceMut<'_>],
228 ) -> Poll<Result<usize>> {
229 match self.as_pin_mut() {
230 Either::Left(x) => x.poll_read_vectored(cx, bufs),
231 Either::Right(x) => x.poll_read_vectored(cx, bufs),
232 }
233 }
234 }
235
236 impl<A, B> AsyncWrite for Either<A, B>
237 where
238 A: AsyncWrite,
239 B: AsyncWrite,
240 {
241 fn poll_write(
242 self: Pin<&mut Self>,
243 cx: &mut Context<'_>,
244 buf: &[u8],
245 ) -> Poll<Result<usize>> {
246 match self.as_pin_mut() {
247 Either::Left(x) => x.poll_write(cx, buf),
248 Either::Right(x) => x.poll_write(cx, buf),
249 }
250 }
251
252 fn poll_write_vectored(
253 self: Pin<&mut Self>,
254 cx: &mut Context<'_>,
255 bufs: &[IoSlice<'_>],
256 ) -> Poll<Result<usize>> {
257 match self.as_pin_mut() {
258 Either::Left(x) => x.poll_write_vectored(cx, bufs),
259 Either::Right(x) => x.poll_write_vectored(cx, bufs),
260 }
261 }
262
263 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
264 match self.as_pin_mut() {
265 Either::Left(x) => x.poll_flush(cx),
266 Either::Right(x) => x.poll_flush(cx),
267 }
268 }
269
270 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
271 match self.as_pin_mut() {
272 Either::Left(x) => x.poll_close(cx),
273 Either::Right(x) => x.poll_close(cx),
274 }
275 }
276 }
277
278 impl<A, B> AsyncSeek for Either<A, B>
279 where
280 A: AsyncSeek,
281 B: AsyncSeek,
282 {
283 fn poll_seek(
284 self: Pin<&mut Self>,
285 cx: &mut Context<'_>,
286 pos: SeekFrom,
287 ) -> Poll<Result<u64>> {
288 match self.as_pin_mut() {
289 Either::Left(x) => x.poll_seek(cx, pos),
290 Either::Right(x) => x.poll_seek(cx, pos),
291 }
292 }
293 }
294
295 impl<A, B> AsyncBufRead for Either<A, B>
296 where
297 A: AsyncBufRead,
298 B: AsyncBufRead,
299 {
300 fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
301 match self.as_pin_mut() {
302 Either::Left(x) => x.poll_fill_buf(cx),
303 Either::Right(x) => x.poll_fill_buf(cx),
304 }
305 }
306
307 fn consume(self: Pin<&mut Self>, amt: usize) {
308 match self.as_pin_mut() {
309 Either::Left(x) => x.consume(amt),
310 Either::Right(x) => x.consume(amt),
311 }
312 }
313 }
314}