use super::State;
use futures::channel::oneshot;
use std::collections::VecDeque;
pub struct Queue<T> {
state: State<VecDeque<(T, Option<oneshot::Sender<()>>)>>, }
impl<T> Queue<T> {
pub fn push(&mut self, item: T) -> Result<(), T> {
match self.state.lock_mut() {
Some(mut state) => state.push_back((item, None)),
None => return Err(item),
};
Ok(())
}
pub async fn pop(&mut self) -> Option<T> {
loop {
{
let queue = self.state.lock();
if !queue.is_empty() {
if let Some((item, notifier)) = {
let mut state_mut = queue.into_mut()?;
state_mut.pop_front()
} {
if let Some(tx) = notifier {
let _ = tx.send(()); }
return Some(item);
}
}
}
let queue = self.state.lock();
queue.modified()?.await;
}
}
pub fn close(self) -> Vec<T> {
let res = match self.state.lock_mut() {
Some(mut queue) => queue.drain(..).map(|(item, _)| item).collect(),
_ => Vec::new(),
};
drop(self.state);
res
}
pub async fn push_and_wait_until_popped(&mut self, item: T) -> Result<(), ()> {
let (tx, rx) = oneshot::channel();
match self.state.lock_mut() {
Some(mut state) => state.push_back((item, Some(tx))),
None => return Err(()), }
rx.await.map_err(|_| ())
}
pub fn split(self) -> (Self, Self) {
let state = self.state.split();
(Self { state: state.0 }, Self { state: state.1 })
}
}
impl<T> Clone for Queue<T> {
fn clone(&self) -> Self {
Self {
state: self.state.clone(),
}
}
}
impl<T> Default for Queue<T> {
fn default() -> Self {
Self {
state: State::new(Default::default()),
}
}
}