use core::{fmt::Debug, mem::MaybeUninit};
use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend;
use iceoryx2_cal::shm_allocator::PointerOffset;
use crate::{
port::publisher::PublisherSharedState, raw_sample::RawSampleMut, sample_mut::SampleMut,
service::header::publish_subscribe::Header,
};
#[repr(transparent)]
pub struct SampleMutUninit<
Service: crate::service::Service,
Payload: Debug + ZeroCopySend + ?Sized,
UserHeader: ZeroCopySend,
> {
sample: SampleMut<Service, Payload, UserHeader>,
}
unsafe impl<
Service: crate::service::Service,
Payload: Debug + ZeroCopySend + ?Sized,
UserHeader: ZeroCopySend,
> Send for SampleMutUninit<Service, Payload, UserHeader>
where
Service::ArcThreadSafetyPolicy<PublisherSharedState<Service>>: Send + Sync,
{
}
impl<
Service: crate::service::Service,
Payload: Debug + ZeroCopySend + ?Sized,
UserHeader: ZeroCopySend,
> SampleMutUninit<Service, Payload, UserHeader>
{
pub fn header(&self) -> &Header {
self.sample.header()
}
pub fn user_header(&self) -> &UserHeader {
self.sample.user_header()
}
pub fn user_header_mut(&mut self) -> &mut UserHeader {
self.sample.user_header_mut()
}
pub fn payload(&self) -> &Payload {
self.sample.payload()
}
pub fn payload_mut(&mut self) -> &mut Payload {
self.sample.payload_mut()
}
}
impl<Service: crate::service::Service, Payload: Debug + ZeroCopySend, UserHeader: ZeroCopySend>
SampleMutUninit<Service, MaybeUninit<Payload>, UserHeader>
{
pub(crate) fn new(
publisher_shared_state: &Service::ArcThreadSafetyPolicy<PublisherSharedState<Service>>,
ptr: RawSampleMut<Header, UserHeader, MaybeUninit<Payload>>,
offset_to_chunk: PointerOffset,
sample_size: usize,
) -> Self {
Self {
sample: SampleMut {
publisher_shared_state: publisher_shared_state.clone(),
ptr,
offset_to_chunk,
sample_size,
},
}
}
pub fn write_payload(mut self, value: Payload) -> SampleMut<Service, Payload, UserHeader> {
self.payload_mut().write(value);
unsafe { self.assume_init() }
}
pub unsafe fn assume_init(self) -> SampleMut<Service, Payload, UserHeader> {
let initialized_sample = core::mem::transmute_copy(&self.sample);
core::mem::forget(self);
initialized_sample
}
}
impl<Service: crate::service::Service, Payload: Debug + ZeroCopySend, UserHeader: ZeroCopySend>
SampleMutUninit<Service, [MaybeUninit<Payload>], UserHeader>
{
pub(crate) fn new(
publisher_shared_state: &Service::ArcThreadSafetyPolicy<PublisherSharedState<Service>>,
ptr: RawSampleMut<Header, UserHeader, [MaybeUninit<Payload>]>,
offset_to_chunk: PointerOffset,
sample_size: usize,
) -> Self {
Self {
sample: SampleMut {
publisher_shared_state: publisher_shared_state.clone(),
ptr,
offset_to_chunk,
sample_size,
},
}
}
pub unsafe fn assume_init(self) -> SampleMut<Service, [Payload], UserHeader> {
let initialized_sample = core::mem::transmute_copy(&self.sample);
core::mem::forget(self);
initialized_sample
}
pub fn write_from_fn<F: FnMut(usize) -> Payload>(
mut self,
mut initializer: F,
) -> SampleMut<Service, [Payload], UserHeader> {
for (i, element) in self.payload_mut().iter_mut().enumerate() {
element.write(initializer(i));
}
unsafe { self.assume_init() }
}
}
impl<
Service: crate::service::Service,
Payload: Debug + Copy + ZeroCopySend,
UserHeader: ZeroCopySend,
> SampleMutUninit<Service, [MaybeUninit<Payload>], UserHeader>
{
pub fn write_from_slice(
mut self,
value: &[Payload],
) -> SampleMut<Service, [Payload], UserHeader> {
self.payload_mut().copy_from_slice(unsafe {
core::mem::transmute::<&[Payload], &[MaybeUninit<Payload>]>(value)
});
unsafe { self.assume_init() }
}
}