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