messing_with_async/messing_with_async/src/io.rs
2022-02-25 14:25:08 -06:00

83 lines
2.2 KiB
Rust

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<Option<Self::Item>> {
// 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<Result<usize>>;
fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context, bufs: &mut [IoSliceMut<'_>]) -> Poll<Result<usize>> {
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<T: AsyncRead + ?Sized> 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<R: AsyncRead + ?Sized> Future for ReadFuture<'_, '_, R> {
type Output = Result<usize>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
this.reader.as_mut().poll_read(cx, this.buf)
}
}
// TODO: (reading|writing) (files|network|hardware?)