Looking for a crate with premade futures

I'm working on some code in which I want to wrap the results of some polling operations into nice async wrappers. For that, I've spun up a simple struct that looks kind of like this:

enum FutureValueInner<T> {
    Empty,
    Waker(Waker),
    Value(T),
}

struct FutureValue<T>(Arc<Mutex<FutureValueInner<T>>>);

impl<T> FutureValue<T> {
    fn set_value(&self, value: T) {
        let mut inner = self.0.lock().unwrap();

        if let FutureValueInner::Waker(waker) = &*inner {
            waker.wake_by_ref();
        }

        *inner = FutureValueInner::Value(value);
    }
}

impl<T> Future for FutureValue<T> {
    type Output = T;

    fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut inner = self.0.lock().unwrap();

        let old_inner = std::mem::replace(&mut *inner, FutureValueInner::Empty);

        match old_inner {
            FutureValueInner::Empty | FutureValueInner::Waker(_) => {
                *inner = FutureValueInner::Waker(ctx.waker().clone());
                Poll::Pending
            }
            FutureValueInner::Value(value) => Poll::Ready(value),
        }
    }
}

The code is simplified for brevity, but not by much. Does a crate with primitives like this exist? Say simple, ready-made future implementations that solve problems like this and are well-tested.

The utility you shared exists in several different crates under the name "oneshot channel". You can find one in tokio::sync::oneshot and another one under futures::channel::oneshot.

3 Likes

Looks like it! Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.