use crate::{Encoder, EncoderBuffer};
pub struct Buffer<'a> {
inner: EncoderBuffer<'a>,
#[cfg(feature = "bytes")]
extra: Option<bytes::Bytes>,
}
impl<'a> Buffer<'a> {
#[inline]
pub fn flatten(&mut self) -> &mut EncoderBuffer<'a> {
self.flush();
&mut self.inner
}
}
#[cfg(feature = "bytes")]
impl<'a> Buffer<'a> {
#[inline]
pub fn new(inner: EncoderBuffer<'a>) -> Self {
Self { inner, extra: None }
}
#[inline]
pub fn new_with_extra(inner: EncoderBuffer<'a>, extra: Option<bytes::Bytes>) -> Self {
Self { inner, extra }
}
#[inline]
pub fn into_inner(self) -> (EncoderBuffer<'a>, Option<bytes::Bytes>) {
(self.inner, self.extra)
}
#[inline]
pub fn inner_mut(&mut self) -> (&mut EncoderBuffer<'a>, &Option<bytes::Bytes>) {
(&mut self.inner, &self.extra)
}
#[inline]
pub fn clear(&mut self) {
self.inner.set_position(0);
self.extra = None;
}
#[inline]
fn flush(&mut self) {
if let Some(extra) = self.extra.take() {
self.inner.write_slice(&extra);
}
}
}
#[cfg(not(feature = "bytes"))]
impl<'a> Buffer<'a> {
#[inline]
pub fn new(inner: EncoderBuffer<'a>) -> Self {
Self { inner }
}
#[inline]
pub fn new_with_extra(inner: EncoderBuffer<'a>, extra: Option<&'static [u8]>) -> Self {
debug_assert!(extra.is_none());
Self { inner }
}
#[inline]
pub fn into_inner(self) -> (EncoderBuffer<'a>, Option<&'static [u8]>) {
(self.inner, None)
}
#[inline]
pub fn inner_mut(&mut self) -> (&mut EncoderBuffer<'a>, &Option<&'static [u8]>) {
(&mut self.inner, &None)
}
#[inline]
pub fn clear(&mut self) {
self.inner.set_position(0);
}
#[inline(always)]
fn flush(&mut self) {}
}
impl Encoder for Buffer<'_> {
#[cfg(feature = "bytes")]
const SPECIALIZES_BYTES: bool = true;
#[inline]
fn write_sized<F: FnOnce(&mut [u8])>(&mut self, len: usize, write: F) {
self.flush();
self.inner.write_sized(len, write)
}
#[inline]
fn write_slice(&mut self, slice: &[u8]) {
self.flush();
self.inner.write_slice(slice);
}
#[inline]
#[cfg(feature = "bytes")]
fn write_bytes(&mut self, bytes: bytes::Bytes) {
self.flush();
self.inner.assert_capacity(bytes.len());
self.extra = Some(bytes);
}
#[inline]
fn write_zerocopy<
T: zerocopy::IntoBytes + zerocopy::FromBytes + zerocopy::Unaligned,
F: FnOnce(&mut T),
>(
&mut self,
write: F,
) {
self.flush();
self.inner.write_zerocopy(write);
}
#[inline]
fn write_repeated(&mut self, count: usize, value: u8) {
self.flush();
self.inner.write_repeated(count, value)
}
#[inline]
fn capacity(&self) -> usize {
self.inner.capacity()
}
#[inline]
#[cfg(feature = "bytes")]
fn len(&self) -> usize {
let mut len = self.inner.len();
if let Some(extra) = self.extra.as_ref() {
len += extra.len();
}
len
}
#[inline]
#[cfg(not(feature = "bytes"))]
fn len(&self) -> usize {
self.inner.len()
}
}