use crate::{
DoubleEndedFallibleLender, FallibleLend, FallibleLender, FallibleLending, Filter,
FusedFallibleLender, try_trait_v2::Try,
};
impl<L: FallibleLender, P> Filter<L, P> {
#[inline(always)]
pub(crate) fn new_fallible(lender: L, predicate: P) -> Filter<L, P> {
let _ = L::__check_covariance(crate::CovariantProof::new());
Filter { lender, predicate }
}
}
impl<'lend, L, P> FallibleLending<'lend> for Filter<L, P>
where
P: FnMut(&FallibleLend<'lend, L>) -> Result<bool, L::Error>,
L: FallibleLender,
{
type Lend = FallibleLend<'lend, L>;
}
impl<L, P> FallibleLender for Filter<L, P>
where
P: FnMut(&FallibleLend<'_, L>) -> Result<bool, L::Error>,
L: FallibleLender,
{
type Error = L::Error;
crate::unsafe_assume_covariance_fallible!();
#[inline(always)]
fn next(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
self.lender.find(&mut self.predicate)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.lender.size_hint();
(0, upper)
}
#[inline]
fn count(self) -> Result<usize, Self::Error>
where
Self: Sized,
{
#[inline]
fn f<
E,
L: for<'all> FallibleLending<'all>,
F: FnMut(&FallibleLend<'_, L>) -> Result<bool, E>,
>(
mut f: F,
) -> impl FnMut(FallibleLend<'_, L>) -> Result<usize, E> {
move |x| (f)(&x).map(|res| res as usize)
}
let lender = self
.lender
.map(unsafe { crate::Covar::__new(f::<_, Self, _>(self.predicate)) });
crate::fallible_adapters::non_fallible_adapter::process(lender, |iter| {
core::iter::Iterator::sum(iter)
})
.map_err(|(_, err)| err)
}
#[inline]
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
R: Try<Output = B>,
{
let predicate = &mut self.predicate;
self.lender.try_fold(init, move |acc, x| {
if (predicate)(&x)? {
f(acc, x)
} else {
Ok(R::from_output(acc))
}
})
}
#[inline]
fn fold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.lender.fold(init, move |acc, x| {
if (self.predicate)(&x)? {
f(acc, x)
} else {
Ok(acc)
}
})
}
}
impl<L, P> DoubleEndedFallibleLender for Filter<L, P>
where
P: FnMut(&FallibleLend<'_, L>) -> Result<bool, L::Error>,
L: DoubleEndedFallibleLender,
{
#[inline(always)]
fn next_back(&mut self) -> Result<Option<FallibleLend<'_, Self>>, Self::Error> {
self.lender.rfind(&mut self.predicate)
}
#[inline]
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> Result<R, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<R, Self::Error>,
R: Try<Output = B>,
{
let predicate = &mut self.predicate;
self.lender.try_rfold(init, move |acc, x| {
if (predicate)(&x)? {
f(acc, x)
} else {
Ok(R::from_output(acc))
}
})
}
#[inline]
fn rfold<B, F>(mut self, init: B, mut f: F) -> Result<B, Self::Error>
where
Self: Sized,
F: FnMut(B, FallibleLend<'_, Self>) -> Result<B, Self::Error>,
{
self.lender.rfold(init, move |acc, x| {
if (self.predicate)(&x)? {
f(acc, x)
} else {
Ok(acc)
}
})
}
}
impl<L, P> FusedFallibleLender for Filter<L, P>
where
P: FnMut(&FallibleLend<'_, L>) -> Result<bool, L::Error>,
L: FusedFallibleLender,
{
}