use std::{pin::Pin, task::{Context, Poll}, future::Future}; // use crate::stream::Stream; // pub struct FileReader { // } // impl Stream for FileReader { // type Item; // fn poll_next(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll> { // let file: File = todo!(); // file // todo!() // } // } pub use std::io::{Result, Error, IoSliceMut}; pub trait AsyncRead { fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll>; fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context, bufs: &mut [IoSliceMut<'_>]) -> Poll> { if let Some(buf) = bufs.iter_mut().find(|v| !v.is_empty()) { self.poll_read(cx, buf) } else { self.poll_read(cx, &mut []) } } fn is_read_vectored(&self) -> bool { false } } pub trait AsyncReadExt: AsyncRead { /// Creates a future which will read some data from the [`AsyncRead`] into `buf`. /// /// ``` /// # use messing_with_async::{async_main, io::{AsyncReadExt, AsyncRead}}; /// # use std::pin::Pin; /// # async_main!(async_main); /// # async fn async_main() { /// let mut reader: Pin<&mut dyn AsyncRead> = todo!(); /// let mut buf = [0; 8]; /// reader.read_fut(&mut buf).await; /// assert_eq!(buf, [1, 2, 3, 0, 0, 0, 0, 0]); /// # } /// # main(); /// ``` fn read_fut<'a, 'b>(self: Pin<&'a mut Self>, buf: &'b mut [u8]) -> ReadFuture<'a, 'b, Self> { ReadFuture::new(self, buf) } } impl AsyncReadExt for T {} pub struct ReadFuture<'a, 'b, R: AsyncRead + ?Sized> { reader: Pin<&'a mut R>, buf: &'b mut [u8] } impl<'a, 'b, R: AsyncRead + ?Sized> ReadFuture<'a, 'b, R> { pub fn new(reader: Pin<&'a mut R>, buf: &'b mut [u8]) -> Self { Self { reader, buf } } } impl Future for ReadFuture<'_, '_, R> { type Output = Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.get_mut(); this.reader.as_mut().poll_read(cx, this.buf) } } // TODO: (reading|writing) (files|network|hardware?)