maybe_fut/api/io/
read.rs

1use std::io::IoSliceMut;
2
3/// The [`Read`] trait provides an asynchronous interface for reading bytes from a source.
4///
5/// Implementors of the `Read` trait are called 'readers'.
6pub trait Read {
7    /// Reads data from the stream into the provided buffer.
8    fn read(&mut self, buf: &mut [u8]) -> impl Future<Output = std::io::Result<usize>>;
9
10    fn read_vectored(
11        &mut self,
12        bufs: &mut [IoSliceMut<'_>],
13    ) -> impl Future<Output = std::io::Result<usize>> {
14        async move {
15            let mut total = 0;
16            for buf in bufs.iter_mut() {
17                let n = self.read(buf).await?;
18                total += n;
19            }
20            Ok(total)
21        }
22    }
23
24    fn is_read_vectored(&self) -> bool {
25        false
26    }
27
28    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> impl Future<Output = std::io::Result<usize>> {
29        let mut probe = [0u8; 32];
30
31        async move {
32            let mut total = 0;
33            loop {
34                let n = self.read(&mut probe).await?;
35                if n == 0 {
36                    break;
37                }
38                buf.extend_from_slice(&probe[..n]);
39                total += n;
40            }
41            Ok(total)
42        }
43    }
44
45    fn read_to_string(&mut self) -> impl Future<Output = std::io::Result<String>> {
46        let mut buf = Vec::new();
47        async move {
48            self.read_to_end(&mut buf).await?;
49            String::from_utf8(buf)
50                .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
51        }
52    }
53
54    fn read_exact(&mut self, mut buf: &mut [u8]) -> impl Future<Output = std::io::Result<()>> {
55        async move {
56            while !buf.is_empty() {
57                match self.read(buf).await {
58                    Ok(0) => break,
59                    Ok(n) => {
60                        buf = &mut buf[n..];
61                    }
62                    Err(e) => return Err(e),
63                }
64            }
65            if !buf.is_empty() {
66                Err(std::io::Error::new(
67                    std::io::ErrorKind::UnexpectedEof,
68                    "failed to fill whole buffer",
69                ))
70            } else {
71                Ok(())
72            }
73        }
74    }
75}