use std::ops::{Deref, DerefMut};
use std::task::Waker;
#[derive(Default, Debug, Clone)]
pub struct Notify<T> {
inner: T,
waker: Option<Waker>,
}
impl<T> Deref for Notify<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for Notify<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.waker.as_ref().map(|w| w.wake_by_ref());
&mut self.inner
}
}
impl<T> Notify<T> {
pub fn new(inner: T) -> Self {
Self { inner, waker: None }
}
pub fn has_waker(ptr: &Notify<T>) -> bool {
ptr.waker.is_some()
}
pub fn waker(ptr: &mut Notify<T>) -> Option<Waker> {
ptr.waker.as_ref().map(|w| w.clone())
}
#[inline]
pub fn wake(ptr: &mut Notify<T>) {
if let Some(ref w) = ptr.waker {
w.clone().wake();
}
}
#[inline]
pub fn register_waker(ptr: &mut Notify<T>, waker: &Waker) {
if !Notify::has_waker(ptr) {
ptr.waker = Some(waker.clone())
}
}
pub fn clear_waker(ptr: &mut Notify<T>) -> Option<Waker> {
ptr.waker.take()
}
pub fn into_inner(ptr: Notify<T>) -> T {
ptr.inner
}
}