From 689b3c65607c3c188fb696a0ac1bc327028f4280 Mon Sep 17 00:00:00 2001 From: Wonwoo Choi Date: Mon, 16 Sep 2019 16:47:17 +0900 Subject: [PATCH] Add io::repeat --- src/io/mod.rs | 2 ++ src/io/repeat.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/io/repeat.rs diff --git a/src/io/mod.rs b/src/io/mod.rs index 5152b03..d272fd6 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -30,6 +30,7 @@ pub use buf_reader::BufReader; pub use copy::copy; pub use empty::{empty, Empty}; pub use read::Read; +pub use repeat::{repeat, Repeat}; pub use seek::Seek; pub use sink::{sink, Sink}; pub use stderr::{stderr, Stderr}; @@ -43,6 +44,7 @@ mod buf_reader; mod copy; mod empty; mod read; +mod repeat; mod seek; mod sink; mod stderr; diff --git a/src/io/repeat.rs b/src/io/repeat.rs new file mode 100644 index 0000000..7f8b3a6 --- /dev/null +++ b/src/io/repeat.rs @@ -0,0 +1,64 @@ +use std::fmt; +use std::pin::Pin; + +use futures_io::{AsyncRead, Initializer}; + +use crate::io; +use crate::task::{Context, Poll}; + +/// Creates an instance of a reader that infinitely repeats one byte. +/// +/// All reads from this reader will succeed by filling the specified buffer with the given byte. +/// +/// ## Examples +/// +/// ```rust +/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { +/// # +/// use async_std::io; +/// use async_std::prelude::*; +/// +/// let mut buffer = [0; 3]; +/// io::repeat(0b101).read_exact(&mut buffer).await?; +/// +/// assert_eq!(buffer, [0b101, 0b101, 0b101]); +/// # +/// # Ok(()) }) } +/// ``` +pub fn repeat(byte: u8) -> Repeat { + Repeat { byte } +} + +/// A reader which yields one byte over and over and over and over and over and... +/// +/// This reader is constructed by the [`repeat`] function. +/// +/// [`repeat`]: fn.repeat.html +pub struct Repeat { + byte: u8, +} + +impl fmt::Debug for Repeat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("Empty { .. }") + } +} + +impl AsyncRead for Repeat { + #[inline] + fn poll_read( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + for b in &mut *buf { + *b = self.byte; + } + Poll::Ready(Ok(buf.len())) + } + + #[inline] + unsafe fn initializer(&self) -> Initializer { + Initializer::nop() + } +}