use std::mem;
pub mod notifier;
use std::task::Waker;
use crate::{
registration::notifier::{Notifier, OpCallback},
typed_op::TypedOp,
};
pub struct RegistrationInner {
pub(crate) notifier: Notifier,
}
pub enum Registration {
Pending(RegistrationInner),
Done(Option<isize>),
}
impl Registration {
pub fn new_waker(waker: Waker) -> Self {
Self::Pending(RegistrationInner { notifier: Notifier::Waker(Some(waker)) })
}
pub fn new_callback<T, F>(callback: F, typed_op: T) -> Self
where
T: TypedOp,
F: FnOnce(T::Result) + Send,
{
Self::Pending(RegistrationInner {
notifier: Notifier::Callback(OpCallback::new::<T, F>(callback, typed_op)),
})
}
pub fn new_callback_boxed<T, F>(callback: F, typed_op: Box<T>) -> Self
where
T: TypedOp,
F: FnOnce(T::Result) + Send,
{
Self::Pending(RegistrationInner {
notifier: Notifier::Callback(OpCallback::new_boxed::<T, F>(
callback, typed_op,
)),
})
}
pub fn set_waker(&mut self, waker: Waker) {
match self {
Self::Done(ret) => {
assert!(ret.is_some());
waker.wake();
}
Self::Pending(RegistrationInner { notifier, .. }) => {
notifier.set_waker(waker);
}
};
}
pub fn set_done(&mut self, res: isize) {
match mem::replace(self, Self::Done(Some(res))) {
Self::Pending(RegistrationInner { notifier }) => {
notifier.call(self);
}
Self::Done { .. } => {
panic!("what");
}
}
}
pub fn try_take_result(&mut self) -> Option<isize> {
match self {
Self::Done(t) => Some(t.take().expect("Already taken")),
Self::Pending(_) => None,
}
}
pub fn result_consumed(&self) -> bool {
matches!(self, Self::Done(None))
}
}