use fallible_iterator::{DoubleEndedFallibleIterator, FallibleIterator, IntoFallibleIterator};
use crate::{
CovariantFallibleLending, DoubleEndedFallibleLender, FallibleLend, FallibleLender,
FallibleLending, IntoFallibleLender, prelude::*,
};
#[inline]
pub fn from_iter<I: FallibleIterator>(iter: I) -> FromIter<I> {
FromIter { iter }
}
#[derive(Clone, Debug)]
#[repr(transparent)]
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct FromIter<I> {
iter: I,
}
impl<I: FallibleIterator> FallibleLending<'_> for FromIter<I> {
type Lend = I::Item;
}
impl<I: FallibleIterator> FallibleLender for FromIter<I> {
type Error = I::Error;
crate::check_covariance_fallible!();
#[inline(always)]
fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
self.iter.next()
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline(always)]
fn nth(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
self.iter.nth(n)
}
#[inline(always)]
fn count(self) -> Result<usize, Self::Error>
where
Self: Sized,
{
self.iter.count()
}
#[inline(always)]
fn fold<B, F>(self, init: B, f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.iter.fold(init, f)
}
}
impl<I: DoubleEndedFallibleIterator> DoubleEndedFallibleLender for FromIter<I> {
#[inline(always)]
fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
self.iter.next_back()
}
#[inline(always)]
fn rfold<B, F>(self, init: B, f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.iter.rfold(init, f)
}
}
impl<I: FallibleIterator> From<I> for FromIter<I> {
#[inline(always)]
fn from(iter: I) -> Self {
from_iter(iter)
}
}
#[inline]
pub fn from_into_iter<I: IntoFallibleIterator>(into_iter: I) -> FromIntoIter<I> {
FromIntoIter { into_iter }
}
#[repr(transparent)]
#[derive(Clone, Debug)]
pub struct FromIntoIter<I> {
into_iter: I,
}
impl<I: IntoFallibleIterator> IntoFallibleLender for FromIntoIter<I> {
type Error = I::Error;
type FallibleLender = FromIter<I::IntoFallibleIter>;
#[inline(always)]
fn into_fallible_lender(self) -> <Self as IntoFallibleLender>::FallibleLender {
self.into_iter.into_fallible_iter().into_fallible_lender()
}
}
impl<I: IntoFallibleIterator> From<I> for FromIntoIter<I> {
#[inline(always)]
fn from(into_iter: I) -> Self {
from_into_iter(into_iter)
}
}
#[inline]
pub fn lend_iter<'a, L, I>(iter: I) -> LendIter<'a, L, I>
where
L: ?Sized + CovariantFallibleLending + 'a,
I: FallibleIterator<Item = FallibleLend<'a, L>>,
{
let _ = L::__check_covariance(crate::CovariantProof::new());
LendIter {
iter,
_marker: core::marker::PhantomData,
}
}
#[derive(Clone, Debug)]
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct LendIter<'a, L: ?Sized, I> {
iter: I,
_marker: core::marker::PhantomData<&'a L>,
}
impl<'a, 'lend, L, I> FallibleLending<'lend> for LendIter<'a, L, I>
where
L: ?Sized + CovariantFallibleLending + 'a,
I: FallibleIterator<Item = FallibleLend<'a, L>>,
{
type Lend = FallibleLend<'lend, L>;
}
impl<'a, L, I> FallibleLender for LendIter<'a, L, I>
where
L: ?Sized + CovariantFallibleLending + 'a,
I: FallibleIterator<Item = FallibleLend<'a, L>>,
{
type Error = I::Error;
crate::unsafe_assume_covariance_fallible!();
#[inline]
fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
let next = self.iter.next()?;
Ok(
unsafe {
core::mem::transmute::<Option<FallibleLend<'a, L>>, Option<FallibleLend<'_, L>>>(
next,
)
},
)
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
#[inline]
fn nth(&mut self, n: usize) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
let nth = self.iter.nth(n)?;
Ok(
unsafe {
core::mem::transmute::<Option<FallibleLend<'a, L>>, Option<FallibleLend<'_, L>>>(
nth,
)
},
)
}
#[inline(always)]
fn count(self) -> Result<usize, Self::Error>
where
Self: Sized,
{
self.iter.count()
}
#[inline]
fn fold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.iter.fold(init, |acc, x| {
f(acc, unsafe {
core::mem::transmute::<FallibleLend<'a, L>, FallibleLend<'_, L>>(x)
})
})
}
}
impl<'a, L, I> DoubleEndedFallibleLender for LendIter<'a, L, I>
where
L: ?Sized + CovariantFallibleLending + 'a,
I: DoubleEndedFallibleIterator<Item = FallibleLend<'a, L>>,
{
#[inline]
fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
let next = self.iter.next_back()?;
Ok(
unsafe {
core::mem::transmute::<Option<FallibleLend<'a, L>>, Option<FallibleLend<'_, L>>>(
next,
)
},
)
}
#[inline]
fn rfold<B, F>(self, init: B, mut f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.iter.rfold(init, |acc, x| {
f(acc, unsafe {
core::mem::transmute::<FallibleLend<'a, L>, FallibleLend<'_, L>>(x)
})
})
}
}