use core::{cmp::min, pin::Pin, task::{Context, Poll}};
use crate::io;
#[allow(unused)] use super::AsyncSliceReader;
pub struct AsyncSliceWriter<'b>{
buf: &'b mut [u8],
cur: usize,
}
impl<'b> AsyncSliceWriter<'b> {
pub fn new(buf: &'b mut [u8]) -> Self {
Self { buf, cur: 0 }
}
pub fn bytes_written(&self) -> usize {
self.cur
}
pub fn as_written(&self) -> &[u8] {
&self.buf[..self.cur]
}
fn write_bytes(&mut self, buf: &[u8]) -> usize {
let n = min(self.buf.len() - self.cur, buf.len());
if n > 0 {
self.buf[self.cur..self.cur + n].copy_from_slice(&buf[..n]);
self.cur += n;
}
n
}
}
impl io::AsyncWrite for AsyncSliceWriter<'_> {
fn poll_write(mut self: Pin<&mut Self>, _cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
let n = self.write_bytes(buf);
if n > 0 {
Poll::Ready(Ok(n))
} else {
Poll::Ready(Err(io::error::write_zero()))
}
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Ready(Ok(()))
}
}
impl<'b> From<&'b mut [u8]> for AsyncSliceWriter<'b> {
fn from(buf: &'b mut [u8]) -> Self {
Self{ buf, cur: 0 }
}
}
#[cfg(test)]
mod test {
use futures::{AsyncWriteExt, executor::block_on};
use super::*;
#[test]
fn can_write_to_slice() {
const LEN: usize = 10;
let mut recv = [0u8; LEN];
let mut writer = AsyncSliceWriter::new(&mut recv);
assert!(writer.bytes_written() == 0);
let send = [7u8; LEN];
let result = block_on(writer.write(&send));
assert!(result.is_ok());
assert!(writer.bytes_written() == LEN);
assert!(recv == send)
}
}