use super::Stele;
use crate::{
append_alloc::iter::{CopyIterator, RefIterator},
sync::Arc,
};
use alloc::alloc::{Allocator, Global};
use core::ops::Index;
#[derive(Debug)]
pub struct ReadHandle<T, A: Allocator = Global> {
pub(crate) handle: Arc<Stele<T, A>>,
}
unsafe impl<T, A: Allocator> Send for ReadHandle<T, A> where Stele<T, A>: Send + Sync {}
unsafe impl<T, A: Allocator> Sync for ReadHandle<T, A> where Stele<T, A>: Sync {}
impl<T, A: Allocator> ReadHandle<T, A> {
#[must_use]
pub fn read(&self, idx: usize) -> &T {
self.handle.read(idx)
}
#[must_use]
pub fn try_read(&self, idx: usize) -> Option<&T> {
self.handle.try_read(idx)
}
#[must_use]
pub fn len(&self) -> usize {
self.handle.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.handle.is_empty()
}
#[must_use]
pub fn iter(&self) -> RefIterator<'_, T, A> {
self.into_iter()
}
}
impl<T: Copy, A: Allocator> ReadHandle<T, A> {
#[must_use]
pub fn get(&self, idx: usize) -> T {
self.handle.get(idx)
}
}
impl<T, A: Allocator> Clone for ReadHandle<T, A> {
fn clone(&self) -> Self {
Self {
handle: Arc::clone(&self.handle),
}
}
}
impl<'a, T, A: Allocator> IntoIterator for &'a ReadHandle<T, A> {
type Item = &'a T;
type IntoIter = super::iter::RefIterator<'a, T, A>;
fn into_iter(self) -> Self::IntoIter {
RefIterator::new(self)
}
}
impl<T: Copy, A: Allocator> IntoIterator for ReadHandle<T, A> {
type Item = T;
type IntoIter = super::iter::CopyIterator<T, A>;
fn into_iter(self) -> Self::IntoIter {
CopyIterator::new(self)
}
}
impl<T, A: Allocator> Index<usize> for ReadHandle<T, A> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
self.read(index)
}
}
impl<T, A: Allocator> From<&Arc<Stele<T, A>>> for ReadHandle<T, A> {
fn from(h: &Arc<Stele<T, A>>) -> Self {
Self {
handle: Arc::clone(h),
}
}
}
#[cfg(test)]
mod tests {
use crate::Stele;
#[test]
fn reads() {
let (writer, reader) = Stele::new();
assert!(writer.is_empty());
writer.push(42);
assert_eq!(writer.len(), 1);
assert_eq!(reader.read(0), &42);
assert_eq!(reader[0], 42);
assert!(reader.try_read(1).is_none());
let copied = writer.get(0);
assert_eq!(copied, 42);
}
}