use super::Arc;
use core::{cell::Cell, ops::RangeBounds};
use crate::{buffer::Buffer, sink::Sink};
#[inline]
pub fn create_buffer<T: Copy, const N: usize>() -> (BufWriter<T, N>, BufReader<T, N>) {
let buf = Arc::new(Buffer::new());
(
BufWriter {
buf: buf.clone(),
_marker: core::marker::PhantomData,
},
BufReader { buf },
)
}
pub struct BufWriter<T, const N: usize> {
buf: Arc<Buffer<T, N>>,
_marker: core::marker::PhantomData<Cell<()>>,
}
impl<T: Copy, const N: usize> BufWriter<T, N> {
#[inline]
pub fn write(&self, value: T) {
self.buf.write(value);
}
}
#[derive(Clone)]
pub struct BufReader<T, const N: usize> {
buf: Arc<Buffer<T, N>>,
}
impl<T: Copy, const N: usize> BufReader<T, N> {
#[inline]
pub fn is_empty(&self) -> bool {
self.buf.is_empty()
}
#[inline]
pub fn get(&self, n: usize) -> Option<T> {
self.buf.get(n)
}
#[inline]
pub fn get_latest(&self) -> Option<T> {
self.get(0)
}
#[inline]
pub fn read(&self, n: usize) -> Option<T> {
self.buf.read(n)
}
#[inline]
pub fn read_latest(&self) -> T {
self.read(0).unwrap()
}
#[inline]
#[must_use]
pub fn get_range<S, R>(&self, range: R, buf: &mut S) -> Option<()>
where
S: Sink<Item = T> + ?Sized,
R: RangeBounds<usize>,
{
self.buf.get_range(range, buf)
}
#[inline]
#[must_use]
pub fn read_range<S, R>(&self, range: R, buf: &mut S) -> Option<()>
where
S: Sink<Item = T> + ?Sized,
R: RangeBounds<usize>,
{
self.buf.read_range(range, buf)
}
}