veilid-tools 0.5.6

A collection of baseline tools for Rust development use by Veilid and Veilid-enabled Rust applications
Documentation
use super::*;

/// An `EventualValue` that resolves exactly once. `resolve` consumes it; if it is
/// dropped without resolving, it resolves to the `drop_value` given at
/// construction (if any), so awaiters never hang.
pub struct SingleShotEventual<T>
where
    T: Unpin,
{
    eventual: EventualValue<T>,
    drop_value: Option<T>,
}

impl<T> Drop for SingleShotEventual<T>
where
    T: Unpin,
{
    fn drop(&mut self) {
        if let Some(drop_value) = self.drop_value.take() {
            self.eventual.resolve(drop_value);
        }
    }
}

impl<T> SingleShotEventual<T>
where
    T: Unpin,
{
    /// Create one that resolves to `drop_value` if dropped before `resolve`.
    pub fn new(drop_value: Option<T>) -> Self {
        Self {
            eventual: EventualValue::new(),
            drop_value,
        }
    }

    /// Resolve to `value`, consuming the eventual. The returned future completes
    /// once all attached instance futures have run.
    ///
    /// Resolves exactly once; consuming `self` prevents a second call and
    /// suppresses the drop-value resolution.
    // Can only call this once, it consumes the eventual
    pub fn resolve(mut self, value: T) -> EventualResolvedFuture<EventualValue<T>> {
        // If we resolve, we don't want to resolve again to the drop value
        self.drop_value = None;
        // Resolve to the specified value
        self.eventual.resolve(value)
    }

    /// Attach an instance future that completes on resolution. The future stays
    /// `Pending` until `resolve` or drop.
    pub fn instance(&self) -> EventualValueFuture<T> {
        self.eventual.instance()
    }
}