summaryrefslogtreecommitdiffstats
path: root/tokio/src/io/util/read_exact.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tokio/src/io/util/read_exact.rs')
-rw-r--r--tokio/src/io/util/read_exact.rs28
1 files changed, 12 insertions, 16 deletions
diff --git a/tokio/src/io/util/read_exact.rs b/tokio/src/io/util/read_exact.rs
index 970074aa..1e8150eb 100644
--- a/tokio/src/io/util/read_exact.rs
+++ b/tokio/src/io/util/read_exact.rs
@@ -1,7 +1,9 @@
use crate::io::{AsyncRead, ReadBuf};
+use pin_project_lite::pin_project;
use std::future::Future;
use std::io;
+use std::marker::PhantomPinned;
use std::marker::Unpin;
use std::pin::Pin;
use std::task::{Context, Poll};
@@ -18,10 +20,11 @@ where
ReadExact {
reader,
buf: ReadBuf::new(buf),
+ _pin: PhantomPinned,
}
}
-cfg_io_util! {
+pin_project! {
/// Creates a future which will read exactly enough bytes to fill `buf`,
/// returning an error if EOF is hit sooner.
///
@@ -31,6 +34,9 @@ cfg_io_util! {
pub struct ReadExact<'a, A: ?Sized> {
reader: &'a mut A,
buf: ReadBuf<'a>,
+ // Make this future `!Unpin` for compatibility with async trait methods.
+ #[pin]
+ _pin: PhantomPinned,
}
}
@@ -44,30 +50,20 @@ where
{
type Output = io::Result<usize>;
- fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
+ let mut me = self.project();
+
loop {
// if our buffer is empty, then we need to read some data to continue.
- let rem = self.buf.remaining();
+ let rem = me.buf.remaining();
if rem != 0 {
- let me = &mut *self;
ready!(Pin::new(&mut *me.reader).poll_read(cx, &mut me.buf))?;
if me.buf.remaining() == rem {
return Err(eof()).into();
}
} else {
- return Poll::Ready(Ok(self.buf.capacity()));
+ return Poll::Ready(Ok(me.buf.capacity()));
}
}
}
}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn assert_unpin() {
- use std::marker::PhantomPinned;
- crate::is_unpin::<ReadExact<'_, PhantomPinned>>();
- }
-}