veilid_tools/
eventual_value.rs1use 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 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}