use core::convert::{AsRef, Infallible};
use core::fmt::Debug;
use core::marker::PhantomData;
use either::Either;
use crate::prelude::*;
#[derive(Debug, Clone)]
pub struct CloneFromSlice<'a, T>(&'a [T], usize);
pub fn clone_from_slice<'a, T>(slice: &'a [T]) -> CloneFromSlice<'a, T> {
CloneFromSlice(slice, 0)
}
impl<'a, T> CloneFromSlice<'a, T> {
pub fn offset(&self) -> usize {
self.1
}
pub fn produced(&self) -> &[T] {
&self.0[..self.offset()]
}
pub fn remaining(&self) -> &[T] {
&self.0[self.offset()..]
}
pub fn into_inner(self) -> &'a [T] {
self.0
}
}
impl<T> AsRef<[T]> for CloneFromSlice<'_, T> {
fn as_ref(&self) -> &[T] {
self.0
}
}
impl<T: Clone> Producer for CloneFromSlice<'_, T> {
type Item = T;
type Final = ();
type Error = Infallible;
async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
if self.0.len() == self.1 {
Ok(Right(()))
} else {
let item = self.0[self.1].clone();
self.1 += 1;
Ok(Left(item))
}
}
async fn slurp(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<T: Clone> BulkProducer for CloneFromSlice<'_, T> {
async fn expose_items_gracefully<F, R>(
&mut self,
f: F,
) -> Result<Either<R, (F, Self::Final)>, (F, Self::Error)>
where
F: AsyncFnOnce(&[Self::Item]) -> (usize, R),
{
let len = self.0.len() - self.1;
if len == 0 {
Ok(Right((f, ())))
} else {
let (amount, ret) = f(&self.0[self.1..self.1 + len]).await;
assert!(amount <= len);
self.1 += amount;
Ok(Left(ret))
}
}
}
#[derive(Debug, Clone)]
pub struct CloneFromOwnedSlice<S, T>(S, usize, PhantomData<T>);
pub fn clone_from_owned_slice<S, T>(owned_slice: S) -> CloneFromOwnedSlice<S, T> {
CloneFromOwnedSlice(owned_slice, 0, PhantomData)
}
impl<S, T> CloneFromOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
pub fn offset(&self) -> usize {
self.1
}
pub fn produced(&self) -> &[T] {
&self.0.as_ref()[..self.offset()]
}
pub fn remaining(&self) -> &[T] {
&self.0.as_ref()[self.offset()..]
}
pub fn into_inner(self) -> S {
self.0
}
}
impl<S, T> AsRef<[T]> for CloneFromOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
fn as_ref(&self) -> &[T] {
self.0.as_ref()
}
}
impl<S, T: Clone> Producer for CloneFromOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
type Item = T;
type Final = ();
type Error = Infallible;
async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
if self.0.as_ref().len() == self.1 {
Ok(Right(()))
} else {
let item = self.0.as_ref()[self.1].clone();
self.1 += 1;
Ok(Left(item))
}
}
async fn slurp(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<S, T: Clone> BulkProducer for CloneFromOwnedSlice<S, T>
where
S: AsRef<[T]>,
{
async fn expose_items_gracefully<F, R>(
&mut self,
f: F,
) -> Result<Either<R, (F, Self::Final)>, (F, Self::Error)>
where
F: AsyncFnOnce(&[Self::Item]) -> (usize, R),
{
let len = self.0.as_ref().len() - self.1;
if len == 0 {
Ok(Right((f, ())))
} else {
let (amount, ret) = f(&self.0.as_ref()[self.1..self.1 + len]).await;
assert!(amount <= len);
self.1 += amount;
Ok(Left(ret))
}
}
}