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 #[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) -> EventualValueFuture<T> {
46 EventualValueFuture {
47 id: None,
48 eventual: self.clone(),
49 }
50 }
51
52 pub fn resolve(&self, value: T) -> EventualResolvedFuture<Self> {
53 self.resolve_to_value(value)
54 }
55
56 #[must_use]
57 pub fn take_value(&self) -> Option<T> {
58 let mut inner = self.inner.lock();
59 inner.resolved_value_mut().take()
60 }
61}
62
63pub struct EventualValueFuture<T: Unpin> {
64 id: Option<usize>,
65 eventual: EventualValue<T>,
66}
67
68impl<T: Unpin> core::fmt::Debug for EventualValueFuture<T> {
69 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70 f.debug_struct("EventualValueFuture")
71 .field("id", &self.id)
72 .finish()
73 }
74}
75
76impl<T: Unpin> Future for EventualValueFuture<T> {
77 type Output = EventualValue<T>;
78 fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
79 let this = &mut *self;
80 let out = {
81 let mut inner = this.eventual.base_inner();
82 inner.instance_poll(&mut this.id, cx)
83 };
84 match out {
85 None => task::Poll::<Self::Output>::Pending,
86 Some(wakers) => {
87 for w in wakers {
89 w.wake();
90 }
91 task::Poll::<Self::Output>::Ready(this.eventual.clone())
92 }
93 }
94 }
95}
96
97impl<T> Drop for EventualValueFuture<T>
98where
99 T: Unpin,
100{
101 fn drop(&mut self) {
102 if let Some(id) = self.id.take() {
103 let wakers = {
104 let mut inner = self.eventual.base_inner();
105 inner.remove_waker(id)
106 };
107 for w in wakers {
108 w.wake();
109 }
110 }
111 }
112}