use super::*; use eventual_base::*; pub struct EventualValue { inner: Arc>>, } impl core::fmt::Debug for EventualValue { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("EventualValue").finish() } } impl Clone for EventualValue { fn clone(&self) -> Self { Self { inner: self.inner.clone(), } } } impl EventualBase for EventualValue { type ResolvedType = T; fn base_inner(&self) -> MutexGuard> { self.inner.lock() } } impl Default for EventualValue { fn default() -> Self { Self::new() } } impl EventualValue { pub fn new() -> Self { Self { inner: Arc::new(Mutex::new(EventualBaseInner::new())), } } pub fn instance(&self) -> EventualValueFuture { EventualValueFuture { id: None, eventual: self.clone(), } } pub fn resolve(&self, value: T) -> EventualResolvedFuture { self.resolve_to_value(value) } pub fn take_value(&self) -> Option { let mut inner = self.inner.lock(); inner.resolved_value_mut().take() } } pub struct EventualValueFuture { id: Option, eventual: EventualValue, } impl core::fmt::Debug for EventualValueFuture { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("EventualValueFuture") .field("id", &self.id) .finish() } } impl Future for EventualValueFuture { type Output = EventualValue; fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll { let this = &mut *self; let out = { let mut inner = this.eventual.base_inner(); inner.instance_poll(&mut this.id, cx) }; match out { None => task::Poll::::Pending, Some(wakers) => { // Wake all EventualResolvedFutures for w in wakers { w.wake(); } task::Poll::::Ready(this.eventual.clone()) } } } } impl Drop for EventualValueFuture where T: Unpin, { fn drop(&mut self) { if let Some(id) = self.id.take() { let wakers = { let mut inner = self.eventual.base_inner(); inner.remove_waker(id) }; for w in wakers { w.wake(); } } } }