poll_persist/
lib.rs

1#![warn(missing_docs)]
2
3//! # `poll-persist`
4//! 
5//! This crate provides a wrapper around a [`Future`] that
6//! can be polled multiple times. This is useful when you
7//! want to await a future from multiple threads without
8//! cloning it.
9//! 
10//! [`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html
11
12use std::{future::Future, pin::Pin};
13
14
15/// A persistent future that can be polled multiple times.
16/// 
17/// When resolved, this future will update itself to store the
18/// resolved value. This allows it to be polled multiple times
19/// without cloning. Any resolution after the first will be
20/// completed immediately.
21pub enum PollPersist<T: Future> {
22    /// The future has not been resolved yet.
23    Pending(Pin<Box<T>>),
24    /// The future has been resolved.
25    Ready(T::Output)
26}
27
28impl<T: Future> PollPersist<T> {
29    /// Creates a new `PollPersist` from a future.
30    pub fn new(future: T) -> Self {
31        PollPersist::Pending(Box::pin(future))
32    }
33
34    /// Resolves the future.
35    pub async fn resolve(&mut self) -> &T::Output {
36        match self {
37            PollPersist::Pending(future) => {
38                let output = future.as_mut().await;
39                *self = PollPersist::Ready(output);
40                match self {
41                    PollPersist::Ready(output) => output,
42                    _ => unreachable!()
43                }
44            },
45            PollPersist::Ready(output) => output
46        }
47    }
48}