use std::future::Future;
use tokio::{select, sync::mpsc};
pub(crate) mod entity_manager;
#[derive(Debug)]
pub struct PeekableReceiver<T> {
msg: Option<T>,
recv: mpsc::Receiver<T>,
}
#[allow(dead_code)]
impl<T> PeekableReceiver<T> {
pub fn new(recv: mpsc::Receiver<T>) -> Self {
Self { msg: None, recv }
}
pub async fn recv(&mut self) -> Option<T> {
if let Some(msg) = self.msg.take() {
return Some(msg);
}
self.recv.recv().await
}
pub async fn extract<U>(
&mut self,
f: impl Fn(T) -> std::result::Result<U, T>,
timeout: impl Future + Unpin,
) -> Option<U> {
let msg = select! {
x = self.recv() => x?,
_ = timeout => return None,
};
match f(msg) {
Ok(u) => Some(u),
Err(msg) => {
self.msg = Some(msg);
None
}
}
}
pub fn push_back(&mut self, msg: T) -> std::result::Result<(), T> {
if self.msg.is_none() {
self.msg = Some(msg);
Ok(())
} else {
Err(msg)
}
}
}