use pool::state;
use crate::{
buffer,
buffer::{pool, pool::owners, write::consume::Error},
};
#[must_use = "commit publishes the admitted source"]
pub struct Append<'a, I, T> {
pub(in crate::buffer::pool) target: &'a mut T,
pub(in crate::buffer::pool) input: owners::Measured<I>,
}
unsafe impl<'a, I: owners::Input, T: pool::raw::Write> buffer::raw::Copy for Append<'a, I, T> {
type Output = &'a mut T;
fn parts(&mut self) -> (impl buffer::raw::SliceExt, *mut u8, usize) {
let writer = unsafe { self.target.writer() };
(self.input.input(), writer.entry().data(), writer.len())
}
unsafe fn publish(self) -> Self::Output {
let writer = unsafe { self.target.writer() };
writer.len += self.input.len() as u32;
self.target
}
}
impl<'a, I, L, M> Append<'a, I, pool::Cursor<L, M>> {
pub(in crate::buffer::pool) fn try_input(
target: &'a mut pool::Cursor<L, M>,
input: owners::Measured<I>,
) -> Result<Self, Error>
where
I: owners::Input,
{
Error::check(input.len(), target.spare_len())?;
target.compact_for(input.len());
Ok(Self { target, input })
}
}
impl<L, M> Append<'_, &[u8], pool::Cursor<L, M>> {
pub fn commit(self) {
buffer::raw::Copy::copy(self);
}
}
impl<'a, 'source, L, M> Append<'a, &'source [u8], pool::Cursor<L, M>> {
pub(in crate::buffer::pool) fn prefix(
target: &'a mut pool::Cursor<L, M>,
src: &'source [u8],
) -> Self {
let len = src.len().min(target.spare_len());
let input = owners::Measured::slice(&src[..len]);
target.compact_for(len);
Self { target, input }
}
}
const _: () = {
assert!(size_of::<Append<'_, &[u8], pool::Cursor>>() == 4 * size_of::<usize>());
assert!(
size_of::<Append<'_, &[u8], pool::Cursor<pool::Layout, pool::Borrowed<'_>>>>()
== 4 * size_of::<usize>()
);
};
impl<'a, I, L, M> Append<'a, I, pool::Span<owners::Plain<L>, M, state::Uninit>> {
pub(in crate::buffer::pool) fn try_lease(
target: &'a mut pool::Span<owners::Plain<L>, M, state::Uninit>,
input: owners::Measured<I>,
) -> Result<Self, Error>
where
I: owners::Input,
{
let spare = target.capacity().get() as usize - target.len();
Error::check(input.len(), spare)?;
Ok(Self { target, input })
}
pub fn as_slice(&self) -> &[u8] {
self.target.as_slice()
}
pub fn input(&self) -> &I {
self.input.input()
}
}
impl<'a, L, M> Append<'a, &[u8], pool::Span<owners::Plain<L>, M, state::Uninit>> {
pub fn commit(self) -> &'a mut pool::Span<owners::Plain<L>, M, state::Uninit> {
buffer::raw::Copy::copy(self)
}
}
impl<'a, 'source, L, M, const P: usize, const N: usize>
Append<'a, ([u8; P], [&'source [u8]; N]), pool::Span<owners::Plain<L>, M, state::Uninit>>
{
pub fn try_prefixed(
target: &'a mut pool::Span<owners::Plain<L>, M, state::Uninit>,
prefix: [u8; P],
sources: [&'source [u8]; N],
) -> Result<Self, Error> {
let input = owners::Input::try_measure((prefix, sources))?;
Self::try_lease(target, input)
}
pub fn commit(self) -> Sources<'a, 'source, L, M, N> {
let sources = self.input.input().1;
(buffer::raw::Copy::copy(self), sources)
}
}
const _: () = {
assert!(size_of::<Append<'_, &[u8], pool::Span>>() == 4 * size_of::<usize>());
assert!(size_of::<Append<'_, ([u8; 8], [&[u8]; 4]), pool::Span>>() == 11 * size_of::<usize>());
};
type Sources<'a, 'source, L, M, const N: usize> = (
&'a mut pool::Span<owners::Plain<L>, M, state::Uninit>,
[&'source [u8]; N],
);