use core::fmt;
use crate::{
CovariantLending, DoubleEndedLender, ExactSizeLender, FusedLender, Lend, Lender, Lending,
};
#[inline]
pub fn once<'a, L: ?Sized + CovariantLending>(value: Lend<'a, L>) -> Once<'a, L> {
let _ = L::__check_covariance(crate::CovariantProof::new());
Once { inner: Some(value) }
}
#[must_use = "lenders are lazy and do nothing unless consumed"]
pub struct Once<'a, L>
where
L: ?Sized + CovariantLending,
{
inner: Option<Lend<'a, L>>,
}
impl<'a, L> Clone for Once<'a, L>
where
L: ?Sized + CovariantLending,
Lend<'a, L>: Clone,
{
#[inline]
fn clone(&self) -> Self {
Once {
inner: self.inner.clone(),
}
}
}
impl<'a, L> fmt::Debug for Once<'a, L>
where
L: ?Sized + CovariantLending,
Lend<'a, L>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Once").field("inner", &self.inner).finish()
}
}
impl<'lend, L> Lending<'lend> for Once<'_, L>
where
L: ?Sized + CovariantLending,
{
type Lend = Lend<'lend, L>;
}
impl<'a, L> Lender for Once<'a, L>
where
L: ?Sized + CovariantLending,
{
crate::unsafe_assume_covariance!();
#[inline]
fn next(&mut self) -> Option<Lend<'_, Self>> {
self.inner
.take()
.map(|v| unsafe { core::mem::transmute::<Lend<'a, Self>, Lend<'_, Self>>(v) })
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.inner.is_some() {
(1, Some(1))
} else {
(0, Some(0))
}
}
}
impl<L> DoubleEndedLender for Once<'_, L>
where
L: ?Sized + CovariantLending,
{
#[inline(always)]
fn next_back(&mut self) -> Option<Lend<'_, Self>> {
self.next()
}
}
impl<L> ExactSizeLender for Once<'_, L> where L: ?Sized + CovariantLending {}
impl<L> FusedLender for Once<'_, L> where L: ?Sized + CovariantLending {}