1 | use crate::io::{AsyncRead, ReadBuf}; |
2 | |
3 | use std::io; |
4 | use std::pin::Pin; |
5 | use std::task::{Context, Poll}; |
6 | |
7 | cfg_io_util! { |
8 | /// An async reader which yields one byte over and over and over and over and |
9 | /// over and... |
10 | /// |
11 | /// This struct is generally created by calling [`repeat`][repeat]. Please |
12 | /// see the documentation of `repeat()` for more details. |
13 | /// |
14 | /// This is an asynchronous version of [`std::io::Repeat`][std]. |
15 | /// |
16 | /// [repeat]: fn@repeat |
17 | /// [std]: std::io::Repeat |
18 | #[derive (Debug)] |
19 | pub struct Repeat { |
20 | byte: u8, |
21 | } |
22 | |
23 | /// Creates an instance of an async reader that infinitely repeats one byte. |
24 | /// |
25 | /// All reads from this reader will succeed by filling the specified buffer with |
26 | /// the given byte. |
27 | /// |
28 | /// This is an asynchronous version of [`std::io::repeat`][std]. |
29 | /// |
30 | /// [std]: std::io::repeat |
31 | /// |
32 | /// # Examples |
33 | /// |
34 | /// ``` |
35 | /// use tokio::io::{self, AsyncReadExt}; |
36 | /// |
37 | /// #[tokio::main] |
38 | /// async fn main() { |
39 | /// let mut buffer = [0; 3]; |
40 | /// io::repeat(0b101).read_exact(&mut buffer).await.unwrap(); |
41 | /// assert_eq!(buffer, [0b101, 0b101, 0b101]); |
42 | /// } |
43 | /// ``` |
44 | pub fn repeat(byte: u8) -> Repeat { |
45 | Repeat { byte } |
46 | } |
47 | } |
48 | |
49 | impl AsyncRead for Repeat { |
50 | #[inline ] |
51 | fn poll_read( |
52 | self: Pin<&mut Self>, |
53 | _: &mut Context<'_>, |
54 | buf: &mut ReadBuf<'_>, |
55 | ) -> Poll<io::Result<()>> { |
56 | // TODO: could be faster, but should we unsafe it? |
57 | while buf.remaining() != 0 { |
58 | buf.put_slice(&[self.byte]); |
59 | } |
60 | Poll::Ready(Ok(())) |
61 | } |
62 | } |
63 | |
64 | #[cfg (test)] |
65 | mod tests { |
66 | use super::*; |
67 | |
68 | #[test ] |
69 | fn assert_unpin() { |
70 | crate::is_unpin::<Repeat>(); |
71 | } |
72 | } |
73 | |