From 53a94c025dbbf9905941eba041def73e9e0c91f8 Mon Sep 17 00:00:00 2001 From: tmiasko <51362316+tmiasko@users.noreply.github.com> Date: Wed, 7 Aug 2019 21:57:37 +0200 Subject: [PATCH] io: implement AsyncBufRead for &[u8] and Cursor (#1397) * `impl AsyncRead for &[u8]` * `impl AsyncBufRead for &[u8]` * `impl + Unpin> AsyncRead for Cursor` * `impl + Unpin> AsyncBufRead for Cursor` --- tokio-io/src/async_buf_read.rs | 26 ++++++++++++++++++++++ tokio-io/src/async_read.rs | 28 +++++++++++++++++++++++ tokio-io/tests/lines.rs | 37 ++----------------------------- tokio-io/tests/read_exact.rs | 28 ++--------------------- tokio-io/tests/read_line.rs | 38 +++----------------------------- tokio-io/tests/read_to_end.rs | 29 ++---------------------- tokio-io/tests/read_to_string.rs | 29 ++---------------------- tokio-io/tests/read_until.rs | 37 ++----------------------------- 8 files changed, 67 insertions(+), 185 deletions(-) diff --git a/tokio-io/src/async_buf_read.rs b/tokio-io/src/async_buf_read.rs index 9c2c55db8..d0c4952d8 100644 --- a/tokio-io/src/async_buf_read.rs +++ b/tokio-io/src/async_buf_read.rs @@ -92,3 +92,29 @@ where self.get_mut().as_mut().consume(amt) } } + +impl AsyncBufRead for &[u8] { + fn poll_fill_buf<'a>( + self: Pin<&'a mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(*self)) + } + + fn consume(mut self: Pin<&mut Self>, amt: usize) { + *self = &self[amt..]; + } +} + +impl + Unpin> AsyncBufRead for io::Cursor { + fn poll_fill_buf<'a>( + self: Pin<&'a mut Self>, + _cx: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(io::BufRead::fill_buf(self.get_mut())) + } + + fn consume(self: Pin<&mut Self>, amt: usize) { + io::BufRead::consume(self.get_mut(), amt) + } +} diff --git a/tokio-io/src/async_read.rs b/tokio-io/src/async_read.rs index 1a59692f4..2fbac2adb 100644 --- a/tokio-io/src/async_read.rs +++ b/tokio-io/src/async_read.rs @@ -155,3 +155,31 @@ where self.get_mut().as_mut().poll_read(cx, buf) } } + +impl AsyncRead for &[u8] { + unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool { + false + } + + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(io::Read::read(self.get_mut(), buf)) + } +} + +impl + Unpin> AsyncRead for io::Cursor { + unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool { + false + } + + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(io::Read::read(self.get_mut(), buf)) + } +} diff --git a/tokio-io/tests/lines.rs b/tokio-io/tests/lines.rs index 63600db2e..940989731 100644 --- a/tokio-io/tests/lines.rs +++ b/tokio-io/tests/lines.rs @@ -2,45 +2,12 @@ #![feature(async_await)] use futures_util::StreamExt; -use tokio_io::{AsyncBufRead, AsyncBufReadExt, AsyncRead}; +use tokio_io::AsyncBufReadExt; use tokio_test::assert_ok; -use std::io; -use std::pin::Pin; -use std::task::{Context, Poll}; - #[tokio::test] async fn lines() { - struct Rd { - val: &'static [u8], - } - - impl AsyncRead for Rd { - fn poll_read( - self: Pin<&mut Self>, - _: &mut Context<'_>, - _: &mut [u8], - ) -> Poll> { - unimplemented!() - } - } - - impl AsyncBufRead for Rd { - fn poll_fill_buf<'a>( - self: Pin<&'a mut Self>, - _: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(self.val)) - } - - fn consume(mut self: Pin<&mut Self>, amt: usize) { - self.val = &self.val[amt..]; - } - } - - let rd = Rd { - val: b"hello\r\nworld\n\n", - }; + let rd: &[u8] = b"hello\r\nworld\n\n"; let mut st = rd.lines(); let b = assert_ok!(st.next().await.unwrap()); diff --git a/tokio-io/tests/read_exact.rs b/tokio-io/tests/read_exact.rs index 617c929af..2a23073ba 100644 --- a/tokio-io/tests/read_exact.rs +++ b/tokio-io/tests/read_exact.rs @@ -1,37 +1,13 @@ #![deny(warnings, rust_2018_idioms)] #![feature(async_await)] -use tokio_io::{AsyncRead, AsyncReadExt}; +use tokio_io::AsyncReadExt; use tokio_test::assert_ok; -use std::io; -use std::pin::Pin; -use std::task::{Context, Poll}; - #[tokio::test] async fn read_exact() { - struct Rd { - val: &'static [u8; 11], - } - - impl AsyncRead for Rd { - fn poll_read( - mut self: Pin<&mut Self>, - _cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - let me = &mut *self; - let len = buf.len(); - - buf[..].copy_from_slice(&me.val[..len]); - Poll::Ready(Ok(buf.len())) - } - } - let mut buf = Box::new([0; 8]); - let mut rd = Rd { - val: b"hello world", - }; + let mut rd: &[u8] = b"hello world"; let n = assert_ok!(rd.read_exact(&mut buf[..]).await); assert_eq!(n, 8); diff --git a/tokio-io/tests/read_line.rs b/tokio-io/tests/read_line.rs index e8312c065..13d0e5c40 100644 --- a/tokio-io/tests/read_line.rs +++ b/tokio-io/tests/read_line.rs @@ -1,46 +1,14 @@ #![deny(warnings, rust_2018_idioms)] #![feature(async_await)] -use tokio_io::{AsyncBufRead, AsyncBufReadExt, AsyncRead}; +use std::io::Cursor; +use tokio_io::AsyncBufReadExt; use tokio_test::assert_ok; -use std::io; -use std::pin::Pin; -use std::task::{Context, Poll}; - #[tokio::test] async fn read_line() { - struct Rd { - val: &'static [u8], - } - - impl AsyncRead for Rd { - fn poll_read( - self: Pin<&mut Self>, - _: &mut Context<'_>, - _: &mut [u8], - ) -> Poll> { - unimplemented!() - } - } - - impl AsyncBufRead for Rd { - fn poll_fill_buf<'a>( - self: Pin<&'a mut Self>, - _: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(self.val)) - } - - fn consume(mut self: Pin<&mut Self>, amt: usize) { - self.val = &self.val[amt..]; - } - } - let mut buf = String::new(); - let mut rd = Rd { - val: b"hello\nworld\n\n", - }; + let mut rd = Cursor::new(b"hello\nworld\n\n"); let n = assert_ok!(rd.read_line(&mut buf).await); assert_eq!(n, 6); diff --git a/tokio-io/tests/read_to_end.rs b/tokio-io/tests/read_to_end.rs index c74860916..e46c4935c 100644 --- a/tokio-io/tests/read_to_end.rs +++ b/tokio-io/tests/read_to_end.rs @@ -1,38 +1,13 @@ #![deny(warnings, rust_2018_idioms)] #![feature(async_await)] -use tokio_io::{AsyncRead, AsyncReadExt}; +use tokio_io::AsyncReadExt; use tokio_test::assert_ok; -use std::pin::Pin; -use std::task::{Context, Poll}; -use std::{cmp, io}; - #[tokio::test] async fn read_to_end() { - struct Rd { - val: &'static [u8], - } - - impl AsyncRead for Rd { - fn poll_read( - mut self: Pin<&mut Self>, - _cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - let me = &mut *self; - let len = cmp::min(buf.len(), me.val.len()); - - buf[..len].copy_from_slice(&me.val[..len]); - me.val = &me.val[len..]; - Poll::Ready(Ok(len)) - } - } - let mut buf = vec![]; - let mut rd = Rd { - val: b"hello world", - }; + let mut rd: &[u8] = b"hello world"; let n = assert_ok!(rd.read_to_end(&mut buf).await); assert_eq!(n, 11); diff --git a/tokio-io/tests/read_to_string.rs b/tokio-io/tests/read_to_string.rs index bf49bfb3f..2a75a5c13 100644 --- a/tokio-io/tests/read_to_string.rs +++ b/tokio-io/tests/read_to_string.rs @@ -1,38 +1,13 @@ #![deny(warnings, rust_2018_idioms)] #![feature(async_await)] -use tokio_io::{AsyncRead, AsyncReadExt}; +use tokio_io::AsyncReadExt; use tokio_test::assert_ok; -use std::pin::Pin; -use std::task::{Context, Poll}; -use std::{cmp, io}; - #[tokio::test] async fn read_to_string() { - struct Rd { - val: &'static [u8], - } - - impl AsyncRead for Rd { - fn poll_read( - mut self: Pin<&mut Self>, - _cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - let me = &mut *self; - let len = cmp::min(buf.len(), me.val.len()); - - buf[..len].copy_from_slice(&me.val[..len]); - me.val = &me.val[len..]; - Poll::Ready(Ok(len)) - } - } - let mut buf = String::new(); - let mut rd = Rd { - val: b"hello world", - }; + let mut rd: &[u8] = b"hello world"; let n = assert_ok!(rd.read_to_string(&mut buf).await); assert_eq!(n, 11); diff --git a/tokio-io/tests/read_until.rs b/tokio-io/tests/read_until.rs index 087e5e250..9f7522c65 100644 --- a/tokio-io/tests/read_until.rs +++ b/tokio-io/tests/read_until.rs @@ -1,46 +1,13 @@ #![deny(warnings, rust_2018_idioms)] #![feature(async_await)] -use tokio_io::{AsyncBufRead, AsyncBufReadExt, AsyncRead}; +use tokio_io::AsyncBufReadExt; use tokio_test::assert_ok; -use std::io; -use std::pin::Pin; -use std::task::{Context, Poll}; - #[tokio::test] async fn read_until() { - struct Rd { - val: &'static [u8], - } - - impl AsyncRead for Rd { - fn poll_read( - self: Pin<&mut Self>, - _: &mut Context<'_>, - _: &mut [u8], - ) -> Poll> { - unimplemented!() - } - } - - impl AsyncBufRead for Rd { - fn poll_fill_buf<'a>( - self: Pin<&'a mut Self>, - _: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(self.val)) - } - - fn consume(mut self: Pin<&mut Self>, amt: usize) { - self.val = &self.val[amt..]; - } - } - let mut buf = vec![]; - let mut rd = Rd { - val: b"hello world", - }; + let mut rd: &[u8] = b"hello world"; let n = assert_ok!(rd.read_until(b' ', &mut buf).await); assert_eq!(n, 6);