use crate::splittable::{SplittableViewImpl, SplittableViewImplMut};
use core::{
convert::Infallible,
convert::TryInto,
marker::PhantomData,
pin::Pin,
slice,
task::{Context, Poll, Waker},
};
pub struct Slice<'a, T>(&'a [T]);
impl<'a, T> Slice<'a, T> {
pub fn new(slice: &'a [T]) -> Self {
Self(slice)
}
pub fn into_inner(self) -> &'a [T] {
self.0
}
}
unsafe impl<'a, T> SplittableViewImpl for Slice<'a, T> {
type Item = T;
type Error = Infallible;
unsafe fn set_reader_waker(&self, _: impl Fn() + Send + Sync + 'static) {}
unsafe fn set_head(&self, _: u64) {}
unsafe fn compare_set_head(&self, _: u64) {}
fn poll_available(
self: Pin<&Self>,
_cx: &mut Context,
_register_wakeup: impl FnOnce(&Waker),
index: u64,
_len: usize,
) -> Poll<Result<usize, Self::Error>> {
let index: usize = index.try_into().unwrap();
let len = self.0.as_ref().len();
Poll::Ready(Ok(len - index.min(len)))
}
unsafe fn view(&self, index: u64, len: usize) -> &[Self::Item] {
let index = index.try_into().unwrap();
&self.0[index..index + len]
}
}
pub struct SliceMut<'a, T> {
ptr: *mut T,
len: usize,
phantom_data: PhantomData<&'a mut [T]>,
}
impl<'a, T> SliceMut<'a, T> {
pub fn new(slice: &'a mut [T]) -> Self {
let ptr = slice.as_mut_ptr();
let len = slice.len();
Self {
ptr,
len,
phantom_data: PhantomData,
}
}
pub fn into_inner(self) -> &'a mut [T] {
unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
}
}
unsafe impl<'a, T> SplittableViewImpl for SliceMut<'a, T> {
type Item = T;
type Error = Infallible;
unsafe fn set_reader_waker(&self, _: impl Fn() + Send + Sync + 'static) {}
unsafe fn set_head(&self, _: u64) {}
unsafe fn compare_set_head(&self, _: u64) {}
fn poll_available(
self: Pin<&Self>,
_cx: &mut Context,
_register_wakeup: impl FnOnce(&Waker),
index: u64,
_len: usize,
) -> Poll<Result<usize, Self::Error>> {
let index: usize = index.try_into().unwrap();
Poll::Ready(Ok(self.len - index.min(self.len)))
}
unsafe fn view(&self, index: u64, len: usize) -> &[Self::Item] {
slice::from_raw_parts(self.ptr.add(index.try_into().unwrap()) as *const T, len)
}
}
unsafe impl<'a, T> SplittableViewImplMut for SliceMut<'a, T> {
unsafe fn view_mut(&self, index: u64, len: usize) -> &mut [Self::Item] {
slice::from_raw_parts_mut(self.ptr.add(index.try_into().unwrap()), len)
}
}