use std::task::Waker;
pub enum State<T> {
Empty(Option<Waker>),
Completed(Option<T>),
Consumed,
}
impl<T> State<T> {
pub fn new() -> Self {
Self::Empty(None)
}
pub fn update_waker(&mut self, waker: Waker) {
*self = match self {
State::Empty(_) => State::Empty(Some(waker)),
State::Completed(_) => panic!("Updating the waker of completed state"),
State::Consumed => panic!("Updating the waker of a consumed state"),
};
}
pub fn try_set_result(&mut self, value: T) -> (bool, Option<Waker>) {
let (state, res, wk) = match self {
State::Empty(wk) => (State::Completed(Some(value)), true, wk.take()),
State::Completed(value) => (State::Completed(value.take()), false, None),
State::Consumed => panic!("Setting the result of an already completed state"),
};
*self = state;
(res, wk)
}
pub fn try_consume(&mut self) -> Option<T> {
let (state, res) = match self {
State::Empty(wk) => (State::Empty(wk.take()), None),
State::Completed(value) => (State::Consumed, Some(value.take().unwrap())),
State::Consumed => panic!("Consuming an already consumed state"),
};
*self = state;
res
}
}