Asynchronously read from the input stream. This method is the same as [`AsyncRead::read`], but doesn't require a `&mut self`.
(&self, buf: &mut [u8])
| 49 | /// Asynchronously read from the input stream. |
| 50 | /// This method is the same as [`AsyncRead::read`], but doesn't require a `&mut self`. |
| 51 | pub async fn read(&self, buf: &mut [u8]) -> std::io::Result<usize> { |
| 52 | let read = loop { |
| 53 | self.ready().await; |
| 54 | // Ideally, the ABI would be able to read directly into buf. |
| 55 | // However, with the default generated bindings, it returns a |
| 56 | // newly allocated vec, which we need to copy into buf. |
| 57 | match self.stream.read(buf.len() as u64) { |
| 58 | // A read of 0 bytes from WASI's `read` doesn't mean |
| 59 | // end-of-stream as it does in Rust. However, `self.ready()` |
| 60 | // cannot guarantee that at least one byte is ready for |
| 61 | // reading, so in this case we try again. |
| 62 | Ok(r) if r.is_empty() => continue, |
| 63 | Ok(r) => break r, |
| 64 | // 0 bytes from Rust's `read` means end-of-stream. |
| 65 | Err(StreamError::Closed) => return Ok(0), |
| 66 | Err(StreamError::LastOperationFailed(err)) => { |
| 67 | return Err(std::io::Error::other(err.to_debug_string())); |
| 68 | } |
| 69 | } |
| 70 | }; |
| 71 | let len = read.len(); |
| 72 | buf[0..len].copy_from_slice(&read); |
| 73 | Ok(len) |
| 74 | } |
| 75 | |
| 76 | /// Move the entire contents of an input stream directly into an output |
| 77 | /// stream, until the input stream has closed. This operation is optimized |