use std::{
io,
task::{Poll, ready},
};
use crate::io::AsyncBufRead;
#[derive(Debug)]
pub struct BufCursor<B> {
io: B,
read: usize,
}
impl<B> BufCursor<B> {
#[inline]
pub fn new(io: B) -> Self {
Self { io, read: 0 }
}
pub fn poll_get<'a>(&'a mut self, len: usize, cx: &mut std::task::Context) -> Poll<io::Result<&'a [u8]>>
where
B: AsyncBufRead,
{
loop {
if self.io.chunk().len() >= self.read + len {
let read = self.read;
self.read += len;
return Poll::Ready(Ok(&self.io.chunk()[read..read + len]))
}
ready!(self.io.poll_read_fill(cx)?);
}
}
#[inline]
pub fn commit(&mut self)
where
B: AsyncBufRead,
{
self.io.consume(self.read);
self.read = 0;
}
}
impl<B: AsyncBufRead> AsyncBufRead for BufCursor<B> {
fn poll_read_fill(&mut self, cx: &mut std::task::Context) -> Poll<io::Result<usize>> {
self.io.poll_read_fill(cx)
}
fn chunk(&self) -> &[u8] {
&self.io.chunk()[self.read..]
}
fn consume(&mut self, cnt: usize) {
self.read += cnt;
}
}