From 689b3c65607c3c188fb696a0ac1bc327028f4280 Mon Sep 17 00:00:00 2001
From: Wonwoo Choi <chwo9843@gmail.com>
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 5152b034..d272fd68 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 00000000..7f8b3a6d
--- /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<io::Result<usize>> {
+        for b in &mut *buf {
+            *b = self.byte;
+        }
+        Poll::Ready(Ok(buf.len()))
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}