use core::ops::Deref;
use musli::error::Error;
use crate::error::BufferError;
#[cfg(not(feature = "alloc"))]
use crate::fixed_bytes::FixedBytes;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
pub const MAX_FIXED_BYTES_LEN: usize = 128;
pub trait Writer {
type Error: Error;
type Mut<'this>: Writer<Error = Self::Error>
where
Self: 'this;
fn borrow_mut(&mut self) -> Self::Mut<'_>;
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), Self::Error>;
#[inline]
fn write_byte(&mut self, b: u8) -> Result<(), Self::Error> {
self.write_bytes(&[b])
}
#[inline]
fn write_array<const N: usize>(&mut self, array: [u8; N]) -> Result<(), Self::Error> {
self.write_bytes(&array)
}
}
impl<W> Writer for &mut W
where
W: ?Sized + Writer,
{
type Error = W::Error;
type Mut<'this> = W::Mut<'this> where Self: 'this;
#[inline]
fn borrow_mut(&mut self) -> Self::Mut<'_> {
(**self).borrow_mut()
}
#[inline]
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
(*self).write_bytes(bytes)
}
#[inline]
fn write_byte(&mut self, b: u8) -> Result<(), Self::Error> {
(*self).write_byte(b)
}
#[inline]
fn write_array<const N: usize>(&mut self, array: [u8; N]) -> Result<(), Self::Error> {
(*self).write_array(array)
}
}
#[derive(Default)]
pub struct Buffer {
#[cfg(feature = "alloc")]
buf: Vec<u8>,
#[cfg(not(feature = "alloc"))]
buf: FixedBytes<MAX_FIXED_BYTES_LEN, BufferError>,
}
impl Buffer {
#[cfg(feature = "alloc")]
pub fn with_capacity(capacity: usize) -> Self {
Self {
buf: Vec::with_capacity(capacity),
}
}
pub const fn new() -> Self {
Self {
#[cfg(feature = "alloc")]
buf: Vec::new(),
#[cfg(not(feature = "alloc"))]
buf: FixedBytes::new(),
}
}
pub fn as_slice(&self) -> &[u8] {
self.buf.as_slice()
}
#[cfg(feature = "alloc")]
pub fn into_vec(self) -> Vec<u8> {
self.buf
}
}
impl Deref for Buffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl Writer for Buffer {
type Error = BufferError;
type Mut<'this> = &'this mut Self where Self: 'this;
#[inline]
fn borrow_mut(&mut self) -> Self::Mut<'_> {
self
}
#[inline]
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.buf.extend_from_slice(bytes);
Ok(())
}
#[inline]
fn write_byte(&mut self, b: u8) -> Result<(), Self::Error> {
self.buf.push(b);
Ok(())
}
#[inline]
fn write_array<const N: usize>(&mut self, array: [u8; N]) -> Result<(), Self::Error> {
self.buf.extend_from_slice(&array[..]);
Ok(())
}
}
#[cfg(feature = "alloc")]
impl Writer for Vec<u8> {
type Error = BufferError;
type Mut<'this> = &'this mut Self where Self: 'this;
#[inline]
fn borrow_mut(&mut self) -> Self::Mut<'_> {
self
}
#[inline]
fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.extend_from_slice(bytes);
Ok(())
}
#[inline]
fn write_byte(&mut self, b: u8) -> Result<(), Self::Error> {
self.push(b);
Ok(())
}
#[inline]
fn write_array<const N: usize>(&mut self, array: [u8; N]) -> Result<(), Self::Error> {
self.extend_from_slice(&array[..]);
Ok(())
}
}