use core::{fmt, marker::PhantomData};
use crate::{FusedLender, prelude::*};
#[inline]
pub fn repeat_with<'a, L, F>(f: F) -> RepeatWith<'a, L, F>
where
L: ?Sized + CovariantLending + 'a,
F: FnMut() -> Lend<'a, L>,
{
let _ = L::__check_covariance(crate::CovariantProof::new());
RepeatWith {
f,
_marker: PhantomData,
}
}
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct RepeatWith<'a, L: ?Sized, F> {
f: F,
_marker: core::marker::PhantomData<&'a L>,
}
impl<L: ?Sized, F: Clone> Clone for RepeatWith<'_, L, F> {
#[inline]
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}
impl<L: ?Sized, F> fmt::Debug for RepeatWith<'_, L, F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RepeatWith").finish_non_exhaustive()
}
}
impl<'lend, 'a, L, F> Lending<'lend> for RepeatWith<'a, L, F>
where
L: ?Sized + CovariantLending + 'a,
F: FnMut() -> Lend<'a, L>,
{
type Lend = Lend<'lend, L>;
}
impl<'a, L, F> Lender for RepeatWith<'a, L, F>
where
L: ?Sized + CovariantLending + 'a,
F: FnMut() -> Lend<'a, L>,
{
crate::unsafe_assume_covariance!();
#[inline]
fn next(&mut self) -> Option<Lend<'_, Self>> {
Some(unsafe { core::mem::transmute::<Lend<'a, L>, Lend<'_, L>>((self.f)()) })
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
(usize::MAX, None)
}
#[inline]
fn advance_by(&mut self, n: usize) -> Result<(), core::num::NonZeroUsize> {
for _ in 0..n {
(self.f)();
}
Ok(())
}
}
impl<'a, L, F> DoubleEndedLender for RepeatWith<'a, L, F>
where
L: ?Sized + CovariantLending + 'a,
F: FnMut() -> Lend<'a, L>,
{
#[inline(always)]
fn next_back(&mut self) -> Option<Lend<'_, Self>> {
self.next()
}
#[inline]
fn advance_back_by(&mut self, n: usize) -> Result<(), core::num::NonZeroUsize> {
for _ in 0..n {
(self.f)();
}
Ok(())
}
}
impl<'a, L, F> FusedLender for RepeatWith<'a, L, F>
where
L: ?Sized + CovariantLending + 'a,
F: FnMut() -> Lend<'a, L>,
{
}