compio_io/util/
repeat.rs

1use std::mem::MaybeUninit;
2
3use compio_buf::BufResult;
4
5use crate::{AsyncBufRead, AsyncRead, IoResult};
6
7/// A reader that infinitely repeats one byte constructed via [`repeat`].
8///
9/// All reads from this reader will succeed by filling the specified buffer with
10/// the given byte.
11///
12/// # Examples
13///
14/// ```rust
15/// # compio_runtime::Runtime::new().unwrap().block_on(async {
16/// use compio_io::{self, AsyncRead, AsyncReadExt};
17///
18/// let (len, buffer) = compio_io::repeat(42)
19///     .read(Vec::with_capacity(3))
20///     .await
21///     .unwrap();
22///
23/// assert_eq!(buffer.as_slice(), [42, 42, 42]);
24/// assert_eq!(len, 3);
25/// # })
26/// ```
27pub struct Repeat(u8);
28
29impl AsyncRead for Repeat {
30    async fn read<B: compio_buf::IoBufMut>(
31        &mut self,
32        mut buf: B,
33    ) -> compio_buf::BufResult<usize, B> {
34        let slice = buf.as_mut_slice();
35
36        let len = slice.len();
37        slice.fill(MaybeUninit::new(self.0));
38        unsafe { buf.set_buf_init(len) };
39
40        BufResult(Ok(len), buf)
41    }
42}
43
44impl AsyncBufRead for Repeat {
45    async fn fill_buf(&mut self) -> IoResult<&'_ [u8]> {
46        Ok(std::slice::from_ref(&self.0))
47    }
48
49    fn consume(&mut self, _: usize) {}
50}
51
52/// Creates a reader that infinitely repeats one byte.
53///
54/// All reads from this reader will succeed by filling the specified buffer with
55/// the given byte.
56///
57/// # Examples
58///
59/// ```rust
60/// # compio_runtime::Runtime::new().unwrap().block_on(async {
61/// use compio_io::{self, AsyncRead, AsyncReadExt};
62///
63/// let ((), buffer) = compio_io::repeat(42)
64///     .read_exact(Vec::with_capacity(3))
65///     .await
66///     .unwrap();
67///
68/// assert_eq!(buffer.as_slice(), [42, 42, 42]);
69/// # })
70/// ```
71pub fn repeat(byte: u8) -> Repeat {
72    Repeat(byte)
73}