aboutsummaryrefslogtreecommitdiff
path: root/src/io/util/fill_buf.rs
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-08-17 08:33:38 -0700
committerJoel Galenson <jgalenson@google.com>2021-08-17 08:40:48 -0700
commit642961436a727d51930e5839e3dbfee04ba4af95 (patch)
tree9da006d6d1c0e4667e8d848673b13cc7d2bb62ca /src/io/util/fill_buf.rs
parent1c33108b3901dd464f81acf08b5268ec294b3876 (diff)
downloadtokio-642961436a727d51930e5839e3dbfee04ba4af95.tar.gz
Upgrade rust/crates/tokio to 1.10.0
Test: make Change-Id: I4ec984178af20297aae0ed51f0b1c6410876a51b
Diffstat (limited to 'src/io/util/fill_buf.rs')
-rw-r--r--src/io/util/fill_buf.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/io/util/fill_buf.rs b/src/io/util/fill_buf.rs
new file mode 100644
index 0000000..98ae2ea
--- /dev/null
+++ b/src/io/util/fill_buf.rs
@@ -0,0 +1,52 @@
+use crate::io::AsyncBufRead;
+
+use pin_project_lite::pin_project;
+use std::future::Future;
+use std::io;
+use std::marker::PhantomPinned;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+pin_project! {
+ /// Future for the [`fill_buf`](crate::io::AsyncBufReadExt::fill_buf) method.
+ #[derive(Debug)]
+ #[must_use = "futures do nothing unless you `.await` or poll them"]
+ pub struct FillBuf<'a, R: ?Sized> {
+ reader: Option<&'a mut R>,
+ #[pin]
+ _pin: PhantomPinned,
+ }
+}
+
+pub(crate) fn fill_buf<R>(reader: &mut R) -> FillBuf<'_, R>
+where
+ R: AsyncBufRead + ?Sized + Unpin,
+{
+ FillBuf {
+ reader: Some(reader),
+ _pin: PhantomPinned,
+ }
+}
+
+impl<'a, R: AsyncBufRead + ?Sized + Unpin> Future for FillBuf<'a, R> {
+ type Output = io::Result<&'a [u8]>;
+
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ let me = self.project();
+
+ // Due to a limitation in the borrow-checker, we cannot return the value
+ // directly on Ready. Once Rust starts using the polonius borrow checker,
+ // this can be simplified.
+ let reader = me.reader.take().expect("Polled after completion.");
+ match Pin::new(&mut *reader).poll_fill_buf(cx) {
+ Poll::Ready(_) => match Pin::new(reader).poll_fill_buf(cx) {
+ Poll::Ready(slice) => Poll::Ready(slice),
+ Poll::Pending => panic!("poll_fill_buf returned Pending while having data"),
+ },
+ Poll::Pending => {
+ *me.reader = Some(reader);
+ Poll::Pending
+ }
+ }
+ }
+}