use core::{
cmp, fmt,
marker::Unpin,
pin::Pin,
task::{self, Poll},
};
use crate::io::Write;
pub struct Cursor<T: AsMut<[u8]>> {
inner: T,
position: usize,
}
impl<T: AsMut<[u8]>> Cursor<T> {
pub fn new(inner: T) -> Cursor<T> {
Cursor { inner, position: 0 }
}
pub fn into_inner(self) -> T {
self.inner
}
pub fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn position(&self) -> usize {
self.position
}
}
impl<T: AsMut<[u8]>> Write for Cursor<T>
where
Self: Unpin,
{
type Error = !;
fn poll_write(
mut self: Pin<&mut Self>,
_cx: &mut task::Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
let len = {
let position = self.position;
let inner = &mut self.inner.as_mut()[position..];
let len = cmp::min(inner.len(), buf.len());
inner[..len].copy_from_slice(&buf[..len]);
len
};
self.position += len;
Poll::Ready(Ok(len))
}
fn poll_flush(
self: Pin<&mut Self>,
_cx: &mut task::Context<'_>,
) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn poll_close(
self: Pin<&mut Self>,
_cx: &mut task::Context<'_>,
) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
}
impl<T: AsMut<[u8]>> fmt::Write for Cursor<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
let inner = &mut self.inner.as_mut()[self.position..];
let len = cmp::min(inner.len(), s.len());
if len != s.len() {
panic!("Overflow writing fmt string");
}
inner[..len].copy_from_slice(s.as_bytes());
self.position += len;
Ok(())
}
}