use crate::buffer::{
reader::{
storage::{Chunk, Infallible as _},
Storage,
},
writer,
};
use bytes::{Bytes, BytesMut};
impl Storage for BytesMut {
type Error = core::convert::Infallible;
#[inline]
fn buffered_len(&self) -> usize {
self.len()
}
#[inline]
fn read_chunk(&mut self, watermark: usize) -> Result<Chunk<'_>, Self::Error> {
let len = self.len().min(watermark);
ensure!(len > 0, Ok(Self::new().into()));
if self.capacity() == len {
Ok(core::mem::replace(self, Self::new()).into())
} else {
Ok(self.split_to(len).into())
}
}
#[inline]
fn partial_copy_into<Dest>(&mut self, dest: &mut Dest) -> Result<Chunk<'_>, Self::Error>
where
Dest: writer::Storage + ?Sized,
{
self.read_chunk(dest.remaining_capacity())
}
#[inline]
fn copy_into<Dest>(&mut self, dest: &mut Dest) -> Result<(), Self::Error>
where
Dest: writer::Storage + ?Sized,
{
let watermark = self.len().min(dest.remaining_capacity());
let consumes_self = watermark == self.len();
if Dest::SPECIALIZES_BYTES_MUT || consumes_self {
let Chunk::BytesMut(chunk) = self.infallible_read_chunk(watermark) else {
unsafe { assume!(false) }
};
dest.put_bytes_mut(chunk);
} else if Dest::SPECIALIZES_BYTES {
let Chunk::BytesMut(chunk) = self.infallible_read_chunk(watermark) else {
unsafe { assume!(false) }
};
dest.put_bytes(chunk.freeze());
} else {
dest.put_slice(&self[..watermark]);
bytes::Buf::advance(self, watermark)
}
Ok(())
}
}
impl Storage for Bytes {
type Error = core::convert::Infallible;
#[inline]
fn buffered_len(&self) -> usize {
self.len()
}
#[inline]
fn read_chunk(&mut self, watermark: usize) -> Result<Chunk<'_>, Self::Error> {
let len = self.len().min(watermark);
Ok(self.split_to(len).into())
}
#[inline]
fn partial_copy_into<Dest>(&mut self, dest: &mut Dest) -> Result<Chunk<'_>, Self::Error>
where
Dest: writer::Storage + ?Sized,
{
self.read_chunk(dest.remaining_capacity())
}
#[inline]
fn copy_into<Dest>(&mut self, dest: &mut Dest) -> Result<(), Self::Error>
where
Dest: writer::Storage + ?Sized,
{
let watermark = self.len().min(dest.remaining_capacity());
let consumes_self = watermark == self.len();
if Dest::SPECIALIZES_BYTES || consumes_self {
let Chunk::Bytes(chunk) = self.infallible_read_chunk(watermark) else {
unsafe { assume!(false) }
};
dest.put_bytes(chunk);
} else {
dest.put_slice(&self[..watermark]);
bytes::Buf::advance(self, watermark)
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use writer::Storage as _;
#[test]
fn bytes_into_queue_test() {
let mut reader = Bytes::from_static(b"hello world");
let mut writer: Vec<Bytes> = vec![];
{
let mut writer = writer.with_write_limit(5);
let chunk = reader.partial_copy_into(&mut writer).unwrap();
assert_eq!(&chunk[..], b"hello");
}
assert!(writer.is_empty());
assert_eq!(&reader[..], b" world");
reader.copy_into(&mut writer).unwrap();
assert_eq!(writer.len(), 1);
assert_eq!(&writer.pop().unwrap()[..], b" world");
}
}