Skip to content

Commit 2cdb83f

Browse files
taiki-ecramertj
authored andcommitted
impl some traits for Either
1 parent 8a7af69 commit 2cdb83f

File tree

1 file changed

+178
-6
lines changed

1 file changed

+178
-6
lines changed

futures-util/src/future/either.rs

+178-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::pin::Pin;
22
use core::task::{Context, Poll};
3-
use futures_core::future::Future;
4-
use futures_core::stream::Stream;
3+
use futures_core::future::{FusedFuture, Future};
4+
use futures_core::stream::{FusedStream, Stream};
55
use futures_sink::Sink;
66

77
/// Combines two different futures, streams, or sinks having the same associated types into a single
@@ -58,13 +58,26 @@ where
5858
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<A::Output> {
5959
unsafe {
6060
match self.get_unchecked_mut() {
61-
Either::Left(a) => Pin::new_unchecked(a).poll(cx),
62-
Either::Right(b) => Pin::new_unchecked(b).poll(cx),
61+
Either::Left(x) => Pin::new_unchecked(x).poll(cx),
62+
Either::Right(x) => Pin::new_unchecked(x).poll(cx),
6363
}
6464
}
6565
}
6666
}
6767

68+
impl<A, B> FusedFuture for Either<A, B>
69+
where
70+
A: FusedFuture,
71+
B: FusedFuture,
72+
{
73+
fn is_terminated(&self) -> bool {
74+
match self {
75+
Either::Left(x) => x.is_terminated(),
76+
Either::Right(x) => x.is_terminated(),
77+
}
78+
}
79+
}
80+
6881
impl<A, B> Stream for Either<A, B>
6982
where
7083
A: Stream,
@@ -75,13 +88,26 @@ where
7588
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<A::Item>> {
7689
unsafe {
7790
match self.get_unchecked_mut() {
78-
Either::Left(a) => Pin::new_unchecked(a).poll_next(cx),
79-
Either::Right(b) => Pin::new_unchecked(b).poll_next(cx),
91+
Either::Left(x) => Pin::new_unchecked(x).poll_next(cx),
92+
Either::Right(x) => Pin::new_unchecked(x).poll_next(cx),
8093
}
8194
}
8295
}
8396
}
8497

98+
impl<A, B> FusedStream for Either<A, B>
99+
where
100+
A: FusedStream,
101+
B: FusedStream,
102+
{
103+
fn is_terminated(&self) -> bool {
104+
match self {
105+
Either::Left(x) => x.is_terminated(),
106+
Either::Right(x) => x.is_terminated(),
107+
}
108+
}
109+
}
110+
85111
impl<A, B, Item> Sink<Item> for Either<A, B>
86112
where
87113
A: Sink<Item>,
@@ -125,3 +151,149 @@ where
125151
}
126152
}
127153
}
154+
155+
#[cfg(feature = "std")]
156+
mod if_std {
157+
use super::Either;
158+
use core::pin::Pin;
159+
use core::task::{Context, Poll};
160+
use futures_io::{
161+
AsyncBufRead, AsyncRead, AsyncSeek, AsyncWrite, Initializer, IoSlice, IoSliceMut, Result,
162+
SeekFrom,
163+
};
164+
165+
impl<A, B> AsyncRead for Either<A, B>
166+
where
167+
A: AsyncRead,
168+
B: AsyncRead,
169+
{
170+
unsafe fn initializer(&self) -> Initializer {
171+
match self {
172+
Either::Left(x) => x.initializer(),
173+
Either::Right(x) => x.initializer(),
174+
}
175+
}
176+
177+
fn poll_read(
178+
self: Pin<&mut Self>,
179+
cx: &mut Context<'_>,
180+
buf: &mut [u8],
181+
) -> Poll<Result<usize>> {
182+
unsafe {
183+
match self.get_unchecked_mut() {
184+
Either::Left(x) => Pin::new_unchecked(x).poll_read(cx, buf),
185+
Either::Right(x) => Pin::new_unchecked(x).poll_read(cx, buf),
186+
}
187+
}
188+
}
189+
190+
fn poll_read_vectored(
191+
self: Pin<&mut Self>,
192+
cx: &mut Context<'_>,
193+
bufs: &mut [IoSliceMut<'_>],
194+
) -> Poll<Result<usize>> {
195+
unsafe {
196+
match self.get_unchecked_mut() {
197+
Either::Left(x) => Pin::new_unchecked(x).poll_read_vectored(cx, bufs),
198+
Either::Right(x) => Pin::new_unchecked(x).poll_read_vectored(cx, bufs),
199+
}
200+
}
201+
}
202+
}
203+
204+
impl<A, B> AsyncWrite for Either<A, B>
205+
where
206+
A: AsyncWrite,
207+
B: AsyncWrite,
208+
{
209+
fn poll_write(
210+
self: Pin<&mut Self>,
211+
cx: &mut Context<'_>,
212+
buf: &[u8],
213+
) -> Poll<Result<usize>> {
214+
unsafe {
215+
match self.get_unchecked_mut() {
216+
Either::Left(x) => Pin::new_unchecked(x).poll_write(cx, buf),
217+
Either::Right(x) => Pin::new_unchecked(x).poll_write(cx, buf),
218+
}
219+
}
220+
}
221+
222+
fn poll_write_vectored(
223+
self: Pin<&mut Self>,
224+
cx: &mut Context<'_>,
225+
bufs: &[IoSlice<'_>],
226+
) -> Poll<Result<usize>> {
227+
unsafe {
228+
match self.get_unchecked_mut() {
229+
Either::Left(x) => Pin::new_unchecked(x).poll_write_vectored(cx, bufs),
230+
Either::Right(x) => Pin::new_unchecked(x).poll_write_vectored(cx, bufs),
231+
}
232+
}
233+
}
234+
235+
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
236+
unsafe {
237+
match self.get_unchecked_mut() {
238+
Either::Left(x) => Pin::new_unchecked(x).poll_flush(cx),
239+
Either::Right(x) => Pin::new_unchecked(x).poll_flush(cx),
240+
}
241+
}
242+
}
243+
244+
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
245+
unsafe {
246+
match self.get_unchecked_mut() {
247+
Either::Left(x) => Pin::new_unchecked(x).poll_close(cx),
248+
Either::Right(x) => Pin::new_unchecked(x).poll_close(cx),
249+
}
250+
}
251+
}
252+
}
253+
254+
impl<A, B> AsyncSeek for Either<A, B>
255+
where
256+
A: AsyncSeek,
257+
B: AsyncSeek,
258+
{
259+
fn poll_seek(
260+
self: Pin<&mut Self>,
261+
cx: &mut Context<'_>,
262+
pos: SeekFrom,
263+
) -> Poll<Result<u64>> {
264+
unsafe {
265+
match self.get_unchecked_mut() {
266+
Either::Left(x) => Pin::new_unchecked(x).poll_seek(cx, pos),
267+
Either::Right(x) => Pin::new_unchecked(x).poll_seek(cx, pos),
268+
}
269+
}
270+
}
271+
}
272+
273+
impl<A, B> AsyncBufRead for Either<A, B>
274+
where
275+
A: AsyncBufRead,
276+
B: AsyncBufRead,
277+
{
278+
fn poll_fill_buf<'a>(
279+
self: Pin<&'a mut Self>,
280+
cx: &mut Context<'_>,
281+
) -> Poll<Result<&'a [u8]>> {
282+
unsafe {
283+
match self.get_unchecked_mut() {
284+
Either::Left(x) => Pin::new_unchecked(x).poll_fill_buf(cx),
285+
Either::Right(x) => Pin::new_unchecked(x).poll_fill_buf(cx),
286+
}
287+
}
288+
}
289+
290+
fn consume(self: Pin<&mut Self>, amt: usize) {
291+
unsafe {
292+
match self.get_unchecked_mut() {
293+
Either::Left(x) => Pin::new_unchecked(x).consume(amt),
294+
Either::Right(x) => Pin::new_unchecked(x).consume(amt),
295+
}
296+
}
297+
}
298+
}
299+
}

0 commit comments

Comments
 (0)