use pin_project_lite::pin_project;
use super ::{task, Future, Pin, Poll};
pub (crate ) trait Started: Future {
fn started(&self ) -> bool;
}
pub (crate ) fn lazy<F, R>(func: F) -> Lazy<F, R>
where
F: FnOnce() -> R,
R: Future + Unpin,
{
Lazy {
inner: Inner::Init { func },
}
}
// FIXME: allow() required due to `impl Trait` leaking types to this lint
pin_project! {
#[ allow(missing_debug_implementations)]
pub (crate ) struct Lazy<F, R> {
#[ pin]
inner: Inner<F, R>,
}
}
pin_project! {
#[ project = InnerProj]
#[ project_replace = InnerProjReplace]
enum Inner<F, R> {
Init { func: F },
Fut { #[ pin] fut: R },
Empty,
}
}
impl <F, R> Started for Lazy<F, R>
where
F: FnOnce() -> R,
R: Future,
{
fn started(&self ) -> bool {
match self .inner {
Inner::Init { .. } => false ,
Inner::Fut { .. } | Inner::Empty => true ,
}
}
}
impl <F, R> Future for Lazy<F, R>
where
F: FnOnce() -> R,
R: Future,
{
type Output = R::Output;
fn poll(self : Pin<&mut Self >, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
let mut this = self .project();
if let InnerProj::Fut { fut } = this.inner.as_mut().project() {
return fut.poll(cx);
}
match this.inner.as_mut().project_replace(Inner::Empty) {
InnerProjReplace::Init { func } => {
this.inner.set(Inner::Fut { fut: func() });
if let InnerProj::Fut { fut } = this.inner.project() {
return fut.poll(cx);
}
unreachable!()
}
_ => unreachable!("lazy state wrong" ),
}
}
}
Messung V0.5 in Prozent C=99 H=100 G=99
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-18)
¤
*© Formatika GbR, Deutschland