Skip to content

Commit

Permalink
Merge pull request #277 from George-Miao/refactor/io-vec-buf
Browse files Browse the repository at this point in the history
refactor: `IoVectoredBuf`
  • Loading branch information
George-Miao authored Aug 2, 2024
2 parents cf93207 + 566addf commit 84ed77b
Show file tree
Hide file tree
Showing 12 changed files with 379 additions and 378 deletions.
290 changes: 0 additions & 290 deletions compio-buf/src/io_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,296 +396,6 @@ unsafe impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
}
}

/// A trait for vectored buffers.
pub trait IoVectoredBuf: Sized + 'static {
/// An iterator for the [`IoSlice`]s of the buffers.
///
/// # Safety
///
/// The return slice will not live longer than self.
/// It is static to provide convenience from writing self-referenced
/// structure.
unsafe fn as_io_slices(&self) -> Vec<IoSlice> {
self.as_dyn_bufs().map(|buf| buf.as_io_slice()).collect()
}

/// Iterate the inner buffers.
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf>;

/// Create an owned iterator to make it easy to pass this vectored buffer as
/// a regular buffer.
///
/// ```
/// use compio_buf::{IoBuf, IoVectoredBuf};
///
/// let bufs = [vec![1u8, 2], vec![3, 4]];
/// let iter = bufs.owned_iter().unwrap();
/// assert_eq!(iter.as_slice(), &[1, 2]);
/// let iter = iter.next().unwrap();
/// assert_eq!(iter.as_slice(), &[3, 4]);
/// let iter = iter.next();
/// assert!(iter.is_err());
/// ```
///
/// The time complexity of the returned iterator depends on the
/// implementation of [`Iterator::nth`] of [`IoVectoredBuf::as_dyn_bufs`].
fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self>;
}

impl<T: IoBuf> IoVectoredBuf for &'static [T] {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
self.iter().map(|buf| buf as &dyn IoBuf)
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoBuf> IoVectoredBuf for &'static mut [T] {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
self.iter().map(|buf| buf as &dyn IoBuf)
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoVectoredBuf + IoIndexedBuf> IoVectoredBuf for &'static T {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
(**self).as_dyn_bufs()
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoVectoredBuf + IoIndexedBuf> IoVectoredBuf for &'static mut T {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
(**self).as_dyn_bufs()
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoBuf, const N: usize> IoVectoredBuf for [T; N] {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
self.iter().map(|buf| buf as &dyn IoBuf)
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoBuf, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoVectoredBuf
for t_alloc!(Vec, T, A)
{
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
self.iter().map(|buf| buf as &dyn IoBuf)
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

#[cfg(feature = "arrayvec")]
impl<T: IoBuf, const N: usize> IoVectoredBuf for arrayvec::ArrayVec<T, N> {
fn as_dyn_bufs(&self) -> impl Iterator<Item = &dyn IoBuf> {
self.iter().map(|buf| buf as &dyn IoBuf)
}

fn owned_iter(self) -> Result<OwnedIter<impl OwnedIterator<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

/// A trait for mutable vectored buffers.
pub trait IoVectoredBufMut: IoVectoredBuf + SetBufInit {
/// An iterator for the [`IoSliceMut`]s of the buffers.
///
/// # Safety
///
/// The return slice will not live longer than self.
/// It is static to provide convenience from writing self-referenced
/// structure.
unsafe fn as_io_slices_mut(&mut self) -> Vec<IoSliceMut> {
self.as_dyn_mut_bufs()
.map(|buf| buf.as_io_slice_mut())
.collect()
}

/// Iterate the inner buffers.
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut>;

/// Create an owned iterator to make it easy to pass this vectored buffer as
/// a regular buffer.
///
/// ```
/// use compio_buf::{IoBuf, IoVectoredBufMut};
///
/// let bufs = [vec![1u8, 2], vec![3, 4]];
/// let iter = bufs.owned_iter_mut().unwrap();
/// assert_eq!(iter.as_slice(), &[1, 2]);
/// let iter = iter.next().unwrap();
/// assert_eq!(iter.as_slice(), &[3, 4]);
/// let iter = iter.next();
/// assert!(iter.is_err());
/// ```
///
/// The time complexity of the returned iterator depends on the
/// implementation of [`Iterator::nth`] of [`IoVectoredBuf::as_dyn_bufs`].
fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self>;
}

impl<T: IoBufMut> IoVectoredBufMut for &'static mut [T] {
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut> {
self.iter_mut().map(|buf| buf as &mut dyn IoBufMut)
}

fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoVectoredBufMut + IoIndexedBufMut> IoVectoredBufMut for &'static mut T {
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut> {
(**self).as_dyn_mut_bufs()
}

fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoBufMut, const N: usize> IoVectoredBufMut for [T; N] {
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut> {
self.iter_mut().map(|buf| buf as &mut dyn IoBufMut)
}

fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoVectoredBufMut
for t_alloc!(Vec, T, A)
{
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut> {
self.iter_mut().map(|buf| buf as &mut dyn IoBufMut)
}

fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

#[cfg(feature = "arrayvec")]
impl<T: IoBufMut, const N: usize> IoVectoredBufMut for arrayvec::ArrayVec<T, N> {
fn as_dyn_mut_bufs(&mut self) -> impl Iterator<Item = &mut dyn IoBufMut> {
self.iter_mut().map(|buf| buf as &mut dyn IoBufMut)
}

fn owned_iter_mut(self) -> Result<OwnedIter<impl OwnedIteratorMut<Inner = Self>>, Self> {
IndexedIter::new(self, 0).map(OwnedIter::new)
}
}

/// A trait for vectored buffers that could be indexed.
pub trait IoIndexedBuf: IoVectoredBuf {
/// Get the buffer with specific index.
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf>;
}

impl<T: IoBuf> IoIndexedBuf for &'static [T] {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
self.get(n).map(|b| b as _)
}
}

impl<T: IoBuf> IoIndexedBuf for &'static mut [T] {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
self.get(n).map(|b| b as _)
}
}

impl<T: IoIndexedBuf> IoIndexedBuf for &'static T {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
(**self).buf_nth(n)
}
}

impl<T: IoIndexedBuf> IoIndexedBuf for &'static mut T {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
(**self).buf_nth(n)
}
}

impl<T: IoBuf, const N: usize> IoIndexedBuf for [T; N] {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
self.get(n).map(|b| b as _)
}
}

impl<T: IoBuf, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoIndexedBuf
for t_alloc!(Vec, T, A)
{
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
self.get(n).map(|b| b as _)
}
}

#[cfg(feature = "arrayvec")]
impl<T: IoBuf, const N: usize> IoIndexedBuf for arrayvec::ArrayVec<T, N> {
fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> {
self.get(n).map(|b| b as _)
}
}

/// A trait for mutable vectored buffers that could be indexed.
pub trait IoIndexedBufMut: IoVectoredBufMut + IoIndexedBuf {
/// Get the mutable buffer with specific index.
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut>;
}

impl<T: IoBufMut> IoIndexedBufMut for &'static mut [T] {
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> {
self.get_mut(n).map(|b| b as _)
}
}

impl<T: IoIndexedBufMut> IoIndexedBufMut for &'static mut T {
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> {
(**self).buf_nth_mut(n)
}
}

impl<T: IoBufMut, const N: usize> IoIndexedBufMut for [T; N] {
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> {
self.get_mut(n).map(|b| b as _)
}
}

impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoIndexedBufMut
for t_alloc!(Vec, T, A)
{
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> {
self.get_mut(n).map(|b| b as _)
}
}

#[cfg(feature = "arrayvec")]
impl<T: IoBufMut, const N: usize> IoIndexedBufMut for arrayvec::ArrayVec<T, N> {
fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> {
self.get_mut(n).map(|b| b as _)
}
}

/// A helper trait for `set_len` like methods.
pub trait SetBufInit {
/// Set the buffer length. If `len` is less than the current length, nothing
Expand Down
Loading

0 comments on commit 84ed77b

Please sign in to comment.