|
| 1 | +use futures_core::stream::Stream; |
1 | 2 | use futures_io::{self as io, AsyncBufRead, AsyncRead, AsyncWrite};
|
2 | 3 | use pin_utils::{unsafe_pinned, unsafe_unpinned};
|
3 | 4 | use std::{
|
4 | 5 | pin::Pin,
|
5 | 6 | task::{Context, Poll},
|
6 | 7 | };
|
7 | 8 |
|
8 |
| -/// I/O wrapper for interleaving [`Poll::Pending`] in calls to read or write. |
| 9 | +/// Wrapper that interleaves [`Poll::Pending`] in calls to poll. |
9 | 10 | ///
|
10 |
| -/// See the [`interleave_pending`] and [`interleave_pending_write`] methods. |
11 |
| -/// |
12 |
| -/// [`interleave_pending`]: super::AsyncReadTestExt::interleave_pending |
13 |
| -/// [`interleave_pending_write`]: super::AsyncWriteTestExt::interleave_pending_write |
| 11 | +/// See the `interleave_pending` methods on: |
| 12 | +/// * [`FutureTestExt`](crate::future::FutureTestExt::interleave_pending) |
| 13 | +/// * [`StreamTestExt`](crate::stream::StreamTestExt::interleave_pending) |
| 14 | +/// * [`AsyncReadTestExt`](crate::io::AsyncReadTestExt::interleave_pending) |
| 15 | +/// * [`AsyncWriteTestExt`](crate::io::AsyncWriteTestExt::interleave_pending_write) |
14 | 16 | #[derive(Debug)]
|
15 |
| -pub struct InterleavePending<Io> { |
16 |
| - io: Io, |
| 17 | +pub struct InterleavePending<T> { |
| 18 | + inner: T, |
17 | 19 | pended: bool,
|
18 | 20 | }
|
19 | 21 |
|
20 |
| -impl<Io: Unpin> Unpin for InterleavePending<Io> {} |
| 22 | +impl<T: Unpin> Unpin for InterleavePending<T> {} |
21 | 23 |
|
22 |
| -impl<Io> InterleavePending<Io> { |
23 |
| - unsafe_pinned!(io: Io); |
| 24 | +impl<T> InterleavePending<T> { |
| 25 | + unsafe_pinned!(inner: T); |
24 | 26 | unsafe_unpinned!(pended: bool);
|
25 | 27 |
|
26 |
| - pub(crate) fn new(io: Io) -> Self { |
27 |
| - Self { io, pended: false } |
| 28 | + pub(crate) fn new(inner: T) -> Self { |
| 29 | + Self { |
| 30 | + inner, |
| 31 | + pended: false, |
| 32 | + } |
28 | 33 | }
|
29 | 34 |
|
30 | 35 | /// Acquires a reference to the underlying I/O object that this adaptor is
|
31 | 36 | /// wrapping.
|
32 |
| - pub fn get_ref(&self) -> &Io { |
33 |
| - &self.io |
| 37 | + pub fn get_ref(&self) -> &T { |
| 38 | + &self.inner |
34 | 39 | }
|
35 | 40 |
|
36 | 41 | /// Acquires a mutable reference to the underlying I/O object that this
|
37 | 42 | /// adaptor is wrapping.
|
38 |
| - pub fn get_mut(&mut self) -> &mut Io { |
39 |
| - &mut self.io |
| 43 | + pub fn get_mut(&mut self) -> &mut T { |
| 44 | + &mut self.inner |
40 | 45 | }
|
41 | 46 |
|
42 | 47 | /// Acquires a pinned mutable reference to the underlying I/O object that
|
43 | 48 | /// this adaptor is wrapping.
|
44 |
| - pub fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut Io> { |
| 49 | + pub fn get_pin_mut<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut T> { |
45 | 50 | self.project().0
|
46 | 51 | }
|
47 | 52 |
|
48 | 53 | /// Consumes this adaptor returning the underlying I/O object.
|
49 |
| - pub fn into_inner(self) -> Io { |
50 |
| - self.io |
| 54 | + pub fn into_inner(self) -> T { |
| 55 | + self.inner |
51 | 56 | }
|
52 | 57 |
|
53 |
| - fn project<'a>(self: Pin<&'a mut Self>) -> (Pin<&'a mut Io>, &'a mut bool) { |
| 58 | + fn project<'a>(self: Pin<&'a mut Self>) -> (Pin<&'a mut T>, &'a mut bool) { |
54 | 59 | unsafe {
|
55 | 60 | let this = self.get_unchecked_mut();
|
56 |
| - (Pin::new_unchecked(&mut this.io), &mut this.pended) |
| 61 | + (Pin::new_unchecked(&mut this.inner), &mut this.pended) |
| 62 | + } |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +impl<St: Stream> Stream for InterleavePending<St> { |
| 67 | + type Item = St::Item; |
| 68 | + |
| 69 | + fn poll_next( |
| 70 | + mut self: Pin<&mut Self>, |
| 71 | + cx: &mut Context<'_>, |
| 72 | + ) -> Poll<Option<Self::Item>> { |
| 73 | + if *self.as_mut().pended() { |
| 74 | + let next = self.as_mut().inner().poll_next(cx); |
| 75 | + if next.is_ready() { |
| 76 | + *self.pended() = false; |
| 77 | + } |
| 78 | + next |
| 79 | + } else { |
| 80 | + cx.waker().wake_by_ref(); |
| 81 | + *self.pended() = true; |
| 82 | + Poll::Pending |
57 | 83 | }
|
58 | 84 | }
|
59 | 85 | }
|
@@ -156,6 +182,6 @@ impl<R: AsyncBufRead> AsyncBufRead for InterleavePending<R> {
|
156 | 182 | }
|
157 | 183 |
|
158 | 184 | fn consume(self: Pin<&mut Self>, amount: usize) {
|
159 |
| - self.io().consume(amount) |
| 185 | + self.inner().consume(amount) |
160 | 186 | }
|
161 | 187 | }
|
0 commit comments