use thiserror::Error;
pub mod single;
pub mod multi;
use crate::{barrier::Barrier, ringbuffer::RingBuffer, Sequence};
#[doc(hidden)]
pub trait ProducerBarrier : Barrier {
fn publish(&self, sequence: Sequence);
}
#[derive(Debug, Error, PartialEq)]
#[error("Ring Buffer is full.")]
pub struct RingBufferFull;
#[derive(Debug, Error, PartialEq)]
#[error("Missing free slots in Ring Buffer: {0}")]
pub struct MissingFreeSlots(pub u64);
pub struct MutBatchIter<'a, E> {
ring_buffer: &'a RingBuffer<E>,
current: Sequence, last: Sequence, }
impl<'a, E> MutBatchIter<'a, E> {
fn new(start: Sequence, end: Sequence, ring_buffer: &'a RingBuffer<E>) -> Self {
Self {
ring_buffer,
current: start,
last: end,
}
}
fn remaining(&self) -> usize {
(self.last - self.current + 1) as usize
}
}
impl<'a, E> Iterator for MutBatchIter<'a, E> {
type Item = &'a mut E;
fn next(&mut self) -> Option<Self::Item> {
if self.current > self.last {
None
}
else {
let event_ptr = self.ring_buffer.get(self.current);
let event = unsafe { &mut *event_ptr };
self.current += 1;
Some(event)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.remaining();
(remaining, Some(remaining))
}
}
pub trait Producer<E> {
fn try_publish<F>(&mut self, update: F) -> Result<Sequence, RingBufferFull>
where F: FnOnce(&mut E);
fn try_batch_publish<'a, F>(&'a mut self, n: usize, update: F) -> Result<Sequence, MissingFreeSlots>
where
E: 'a,
F: FnOnce(MutBatchIter<'a, E>);
fn publish<F>(&mut self, update: F)
where F: FnOnce(&mut E);
fn batch_publish<'a, F>(&'a mut self, n: usize, update: F)
where
E: 'a,
F: FnOnce(MutBatchIter<'a, E>);
}