future_handles 0.2.0

A library crate to complete futures via handles
Documentation
use std::task::Waker;

/// The completion state.
pub enum State<T> {
    Empty(Option<Waker>),
    Completed(Option<T>),
    Consumed,
}

impl<T> State<T> {
    pub fn new() -> Self {
        Self::Empty(None)
    }

    pub fn update_waker(&mut self, waker: Waker) {
        *self = match self {
            // Empty, set the new waker.
            State::Empty(_) => State::Empty(Some(waker)),
            // Already completed, panic.
            State::Completed(_) => panic!("Updating the waker of completed state"),
            // Already consumed, panic.
            State::Consumed => panic!("Updating the waker of a consumed state"),
        };
    }

    pub fn try_set_result(&mut self, value: T) -> (bool, Option<Waker>) {
        let (state, res, wk) = match self {
            // Set the state as completed and returns the waker, if any.
            State::Empty(wk) => (State::Completed(Some(value)), true, wk.take()),
            // Already completed, nothing to change.
            State::Completed(value) => (State::Completed(value.take()), false, None),
            // State already consumed, panic.
            State::Consumed => panic!("Setting the result of an already completed state"),
        };
        *self = state;
        (res, wk)
    }

    pub fn try_consume(&mut self) -> Option<T> {
        let (state, res) = match self {
            // No result, still empty.
            State::Empty(wk) => (State::Empty(wk.take()), None),
            // Completed, set the state as consumed and return the value.
            State::Completed(value) => (State::Consumed, Some(value.take().unwrap())),
            // State already consumed, panic.
            State::Consumed => panic!("Consuming an already consumed state"),
        };
        *self = state;
        res
    }
}