//! Runtime primitives for cell execution.
//!
//! Provides deadline-bounded async execution and step management.
//! These are used by generated code from the `cell!` and `#[bounded_async]` macros.

use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
use core::time::Duration;

use crate::Timeout;

/// Wrap an async operation with a deadline.
///
/// Returns a future that resolves to `Err(Timeout)` if the inner future
/// does not complete within `deadline`. The actual timeout enforcement
/// is provided by the runtime executor — this wrapper records the
/// deadline and delegates cancellation to the executor's timer system.
///
/// Generated by `cell!` macro for `pub async(Duration)` methods and
/// by the `#[bounded_async(Duration)]` attribute.
pub fn with_deadline<F, T, E>(
    _deadline: Duration,
    future: F,
) -> DeadlineFuture<F>
where
    F: Future<Output = Result<T, E>>,
    E: From<Timeout>,
{
    DeadlineFuture {
        inner: future,
        _deadline,
    }
}

/// A future wrapped with a deadline.
///
/// The runtime executor inspects `deadline()` to set up cancellation.
/// If the inner future completes first, its result is returned.
/// If the deadline expires, the executor drops this future and the
/// caller receives `Err(Timeout.into())`.
pub struct DeadlineFuture<F> {
    inner: F,
    _deadline: Duration,
}

impl<F> DeadlineFuture<F> {
    /// The deadline duration for this operation.
    pub fn deadline(&self) -> Duration {
        self._deadline
    }
}

impl<F, T, E> Future for DeadlineFuture<F>
where
    F: Future<Output = Result<T, E>>,
    E: From<Timeout>,
{
    type Output = Result<T, E>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        // Safety: we only project to `inner` which is structurally pinned.
        let inner = unsafe { self.map_unchecked_mut(|s| &mut s.inner) };
        inner.poll(cx)
    }
}

Local Graph