use core::{
future::{poll_fn, Future},
pin::Pin,
};
use std::io;
use xitca_io::io::{AsyncIo, Interest};
use super::buffer::{BufRead, BufWrite, ReadBuf};
pub struct BufferedIo<'a, St, W, const READ_BUF_LIMIT: usize> {
pub io: &'a mut St,
pub read_buf: ReadBuf<READ_BUF_LIMIT>,
pub write_buf: W,
}
impl<'a, St, W, const READ_BUF_LIMIT: usize> BufferedIo<'a, St, W, READ_BUF_LIMIT>
where
St: AsyncIo,
W: BufWrite,
{
pub fn new(io: &'a mut St, write_buf: W) -> Self {
Self {
io,
read_buf: ReadBuf::new(),
write_buf,
}
}
#[inline]
pub fn try_read(&mut self) -> io::Result<()> {
BufRead::do_io(&mut self.read_buf, self.io)
}
#[inline]
pub fn try_write(&mut self) -> io::Result<()> {
BufWrite::do_io(&mut self.write_buf, self.io)
}
pub async fn read(&mut self) -> io::Result<()> {
self.io.ready(Interest::READABLE).await?;
self.try_read()
}
pub async fn drain_write(&mut self) -> io::Result<()> {
while self.write_buf.want_write_io() {
self.io.ready(Interest::WRITABLE).await?;
self.try_write()?;
}
Ok(())
}
pub fn shutdown(&mut self) -> impl Future<Output = io::Result<()>> + '_ {
poll_fn(|cx| Pin::new(&mut *self.io).poll_shutdown(cx))
}
}