use std::marker::PhantomData;
use crate::ty;
use crate::{Arguments, BodyBuf, Signature, Storable};
use super::{StoreArray, StoreVariant};
#[must_use = "Must call `finish` after writing all related fields"]
pub struct StoreStruct<'a, T> {
buf: &'a mut BodyBuf,
_marker: PhantomData<T>,
}
impl<'a, T> StoreStruct<'a, T> {
pub(crate) fn new(buf: &'a mut BodyBuf) -> Self {
buf.align_mut::<u64>();
Self::inner(buf)
}
pub(crate) fn inner(buf: &'a mut BodyBuf) -> Self {
Self {
buf,
_marker: PhantomData,
}
}
#[inline]
pub fn store(self, value: <T::First as ty::Marker>::Return<'_>) -> StoreStruct<'a, T::Remaining>
where
T: ty::Fields,
T::First: ty::Marker,
for<'b> <T::First as ty::Marker>::Return<'b>: Storable,
{
value.store_to(self.buf);
StoreStruct::inner(self.buf)
}
#[inline]
pub fn fields(self, arguments: T)
where
T: Arguments,
{
arguments.buf_to(self.buf);
}
#[inline]
pub fn store_array<W, U>(self, writer: W) -> StoreStruct<'a, T::Remaining>
where
W: FnOnce(&mut StoreArray<'_, U>),
T: ty::Fields<First = ty::Array<U>>,
U: ty::Aligned,
{
let mut w = StoreArray::new(self.buf);
writer(&mut w);
w.finish();
StoreStruct::inner(self.buf)
}
#[inline]
pub fn store_struct<W>(self, writer: W) -> StoreStruct<'a, T::Remaining>
where
W: FnOnce(StoreStruct<'_, T::First>),
T: ty::Fields,
T::First: ty::Fields,
{
writer(StoreStruct::new(self.buf));
StoreStruct::inner(self.buf)
}
#[inline]
pub fn store_variant<W>(self, signature: &Signature, writer: W) -> StoreStruct<'a, T::Remaining>
where
W: FnOnce(StoreVariant<'_>),
T: ty::Fields<First = ty::Variant>,
{
writer(StoreVariant::new(self.buf, signature));
StoreStruct::inner(self.buf)
}
}
impl StoreStruct<'_, ()> {
pub fn finish(self) {}
}