Skip to main content

veilid_tools/
eventual_value_clone.rs

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