veilid_tools/
eventual_value.rs

1use super::*;
2
3use eventual_base::*;
4
5pub struct EventualValue<T: Unpin> {
6    inner: Arc<Mutex<EventualBaseInner<T>>>,
7}
8
9impl<T: Unpin> core::fmt::Debug for EventualValue<T> {
10    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11        f.debug_struct("EventualValue").finish()
12    }
13}
14
15impl<T: Unpin> Clone for EventualValue<T> {
16    fn clone(&self) -> Self {
17        Self {
18            inner: self.inner.clone(),
19        }
20    }
21}
22
23impl<T: Unpin> EventualBase for EventualValue<T> {
24    type ResolvedType = T;
25    fn base_inner(&self) -> MutexGuard<EventualBaseInner<Self::ResolvedType>> {
26        self.inner.lock()
27    }
28}
29
30impl<T: Unpin> Default for EventualValue<T> {
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36impl<T: Unpin> EventualValue<T> {
37    pub fn new() -> Self {
38        Self {
39            inner: Arc::new(Mutex::new(EventualBaseInner::new())),
40        }
41    }
42
43    pub fn instance(&self) -> EventualValueFuture<T> {
44        EventualValueFuture {
45            id: None,
46            eventual: self.clone(),
47        }
48    }
49
50    pub fn resolve(&self, value: T) -> EventualResolvedFuture<Self> {
51        self.resolve_to_value(value)
52    }
53
54    pub fn take_value(&self) -> Option<T> {
55        let mut inner = self.inner.lock();
56        inner.resolved_value_mut().take()
57    }
58}
59
60pub struct EventualValueFuture<T: Unpin> {
61    id: Option<usize>,
62    eventual: EventualValue<T>,
63}
64
65impl<T: Unpin> core::fmt::Debug for EventualValueFuture<T> {
66    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
67        f.debug_struct("EventualValueFuture")
68            .field("id", &self.id)
69            .finish()
70    }
71}
72
73impl<T: Unpin> Future for EventualValueFuture<T> {
74    type Output = EventualValue<T>;
75    fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
76        let this = &mut *self;
77        let out = {
78            let mut inner = this.eventual.base_inner();
79            inner.instance_poll(&mut this.id, cx)
80        };
81        match out {
82            None => task::Poll::<Self::Output>::Pending,
83            Some(wakers) => {
84                // Wake all other instance futures
85                for w in wakers {
86                    w.wake();
87                }
88                task::Poll::<Self::Output>::Ready(this.eventual.clone())
89            }
90        }
91    }
92}
93
94impl<T> Drop for EventualValueFuture<T>
95where
96    T: Unpin,
97{
98    fn drop(&mut self) {
99        if let Some(id) = self.id.take() {
100            let wakers = {
101                let mut inner = self.eventual.base_inner();
102                inner.remove_waker(id)
103            };
104            for w in wakers {
105                w.wake();
106            }
107        }
108    }
109}