fastbuf 0.44.0

single-thread-oriented very fast byte buffer
Documentation
use crate::{declare_const_impl, declare_const_trait};
use core::ops::{Deref, DerefMut};
use std::alloc::Allocator;

declare_const_trait! {
    pub trait ChunkBuilder<(A: Allocator)>: const(), () {
        fn new_in(alloc: A) -> Self;
        fn new_zeroed() -> Self;
        fn new() -> Self;
    }
}

declare_const_trait! {
    pub trait Chunk<(T)>: const (), () {
        fn as_slice(&self) -> &[T];
        fn as_mut_slice(&mut self) -> &mut [T];
        fn as_ptr(&self) -> *const T;
        fn as_mut_ptr(&mut self) -> *mut T;
    }
}

declare_const_trait! {
    pub trait Buf<(T)>: const (ReadBuf<T>, WriteBuf<T>), () {
        fn clear(&mut self);
    }
}

declare_const_trait! {
    pub trait WriteBuf<(T)>: const (), (Chunk<T>) {
        fn write(&mut self, data: &[T]);
        fn try_write(&mut self, data: &[T]) -> Result<(), WriteBufferError>;
        fn try_write_fast<const LEN: usize>(&mut self, data: &[T; LEN]) -> Result<(), WriteBufferError>;
        fn remaining_space(&self) -> usize;
        fn filled_pos(&self) -> usize;
        unsafe fn set_filled_pos(&mut self, filled_pos: usize);
        fn capacity(&self) -> usize;
    }
}

declare_const_trait! {
    pub trait ReadBuf<(T)>: const (), (Chunk<T>) {
        fn read(&mut self, len: usize) -> &[T];
        unsafe fn get_continuous(&self, len: usize) -> &[T];
        unsafe fn get_continuous_mut(&mut self, len: usize) -> &mut [T];
        fn remaining(&self) -> usize;
        fn advance(&mut self, len: usize);
        fn pos(&self) -> usize;
        unsafe fn set_pos(&mut self, pos: usize);
    }
}

pub trait ReadToBuf<T> {
    #[cfg(feature = "const-trait")]
    fn read_to_buf(&mut self, buf: &mut impl const Buf<T>) -> Result<(), ()>;
    #[cfg(not(feature = "const-trait"))]
    fn read_to_buf(&mut self, buf: &mut impl Buf<T>) -> Result<(), ()>;
}

#[derive(Debug)]
pub enum WriteBufferError {
    BufferFull,
}

declare_const_impl! {
    (impl<T, S: Buf<T>> Buf<T> for &mut S),
    (impl<T, S: const Buf<T> + const Chunk<T>> const Buf<T> for &mut S) {
        fn clear(&mut self) {
            self.deref_mut().clear()
        }
    }
}

declare_const_impl! {
    (impl<T, S: ReadBuf<T>> ReadBuf<T> for &mut S),
    (impl<T, S: const ReadBuf<T> + const Chunk<T>> const ReadBuf<T> for &mut S) {
        fn read(&mut self, len: usize) -> &[T] {
            self.deref_mut().read(len)
        }

        unsafe fn get_continuous(&self, len: usize) -> &[T] {
            self.deref().get_continuous(len)
        }

        unsafe fn get_continuous_mut(&mut self, len: usize) -> &mut [T] {
            self.deref_mut().get_continuous_mut(len)
        }

        fn remaining(&self) -> usize {
            self.deref().remaining()
        }

        fn advance(&mut self, len: usize) {
            self.deref_mut().advance(len)
        }

        fn pos(&self) -> usize {
            self.deref().pos()
        }

        unsafe fn set_pos(&mut self, pos: usize) {
            self.deref_mut().set_pos(pos)
        }
    }
}

declare_const_impl! {
    (impl<T, S: WriteBuf<T>> WriteBuf<T> for &mut S),
    (impl<T, S: const WriteBuf<T> + const Chunk<T>> const WriteBuf<T> for &mut S) {
        fn write(&mut self, data: &[T]) {
            self.deref_mut().write(data)
        }

        fn try_write(&mut self, data: &[T]) -> Result<(), WriteBufferError> {
            self.deref_mut().try_write(data)
        }

        fn try_write_fast<const LEN: usize>(&mut self, data: &[T; LEN]) -> Result<(), WriteBufferError> {
            self.deref_mut().try_write_fast::<LEN>(data)
        }

        fn remaining_space(&self) -> usize {
            self.deref().remaining_space()
        }

        fn filled_pos(&self) -> usize {
            self.deref().filled_pos()
        }

        unsafe fn set_filled_pos(&mut self, filled_pos: usize) {
            self.deref_mut().set_filled_pos(filled_pos)
        }

        fn capacity(&self) -> usize {
            self.deref().capacity()
        }
    }
}

declare_const_impl! {
    (impl<T, S: Chunk<T>> Chunk<T> for &mut S),
    (impl<T, S: const Chunk<T>> const Chunk<T> for &mut S) {
        fn as_slice(&self) ->  &[T] {
            self.deref().as_slice()
        }

        fn as_mut_slice(&mut self) ->  &mut [T] {
            self.deref_mut().as_mut_slice()
        }

        fn as_ptr(&self) ->  *const T {
            self.deref().as_ptr()
        }

        fn as_mut_ptr(&mut self) ->  *mut T {
            self.deref_mut().as_mut_ptr()
        }
    }
}