use core::convert::AsRef;
use core::fmt::Debug;
use core::marker::PhantomData;
use crate::prelude::*;
#[derive(Debug)]
pub struct MoveIntoSlice<'a, T>(&'a mut [T], usize);
pub fn move_into_slice<'a, T>(slice: &'a mut [T]) -> MoveIntoSlice<'a, T> {
MoveIntoSlice(slice, 0)
}
impl<'a, T> MoveIntoSlice<'a, T> {
pub fn offset(&self) -> usize {
self.1
}
pub fn consumed(&self) -> &[T] {
&self.0[..self.offset()]
}
pub fn consumed_mut(&mut self) -> &mut [T] {
let offset = self.offset();
&mut self.0[..offset]
}
pub fn remaining(&self) -> &[T] {
&self.0[self.offset()..]
}
pub fn remaining_mut(&mut self) -> &mut [T] {
let offset = self.offset();
&mut self.0[offset..]
}
pub fn into_inner(self) -> &'a mut [T] {
self.0
}
}
impl<T> AsRef<[T]> for MoveIntoSlice<'_, T> {
fn as_ref(&self) -> &[T] {
self.0
}
}
impl<T> AsMut<[T]> for MoveIntoSlice<'_, T> {
fn as_mut(&mut self) -> &mut [T] {
self.0
}
}
impl<T> Consumer for MoveIntoSlice<'_, T> {
type Item = T;
type Final = Infallible;
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.0.len() == self.1 {
Err(())
} else {
self.0[self.1] = item;
self.1 += 1;
Ok(())
}
}
Right(_) => unreachable!(),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<T> BulkConsumer for MoveIntoSlice<'_, T> {
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
let len = self.0.len() - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
#[derive(Debug)]
pub struct MoveIntoOwnedSlice<S, T>(S, usize, PhantomData<T>);
pub fn move_into_owned_slice<S, T>(slice: S) -> MoveIntoOwnedSlice<S, T> {
MoveIntoOwnedSlice(slice, 0, PhantomData)
}
impl<S, T> MoveIntoOwnedSlice<S, T> {
pub fn into_inner(self) -> S {
self.0
}
pub fn offset(&self) -> usize {
self.1
}
}
impl<S, T> MoveIntoOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
pub fn consumed(&self) -> &[T] {
&self.0.as_ref()[..self.offset()]
}
pub fn remaining(&self) -> &[T] {
&self.0.as_ref()[self.offset()..]
}
}
impl<S, T> MoveIntoOwnedSlice<S, T>
where
S: AsMut<[T]>,
{
pub fn consumed_mut(&mut self) -> &mut [T] {
let offset = self.offset();
&mut self.0.as_mut()[..offset]
}
pub fn remaining_mut(&mut self) -> &mut [T] {
let offset = self.offset();
&mut self.0.as_mut()[offset..]
}
}
impl<S, T> AsRef<[T]> for MoveIntoOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
fn as_ref(&self) -> &[T] {
self.0.as_ref()
}
}
impl<S, T> AsMut<[T]> for MoveIntoOwnedSlice<S, T>
where
S: AsMut<[T]>,
{
fn as_mut(&mut self) -> &mut [T] {
self.0.as_mut()
}
}
impl<S, T> Consumer for MoveIntoOwnedSlice<S, T>
where
S: AsMut<[T]>,
{
type Item = T;
type Final = Infallible;
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.0.as_mut().len() == self.1 {
Err(())
} else {
self.0.as_mut()[self.1] = item;
self.1 += 1;
Ok(())
}
}
Right(_) => unreachable!(),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<S, T> BulkConsumer for MoveIntoOwnedSlice<S, T>
where
S: AsMut<[T]>,
{
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
let len = self.0.as_mut().len() - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0.as_mut()[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}