#![allow(dead_code)]
use safina_sync::{sync_channel, Receiver, SyncSender};
use std::sync::mpsc::RecvTimeoutError;
use std::time::Duration;
pub struct Token(SyncSender<()>);
impl Token {
#[must_use]
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
let (sender, _receiver) = sync_channel(1);
Self(sender)
}
}
impl Drop for Token {
fn drop(&mut self) {
let _ = self.0.try_send(());
}
}
#[derive(Debug)]
pub struct TimeOut;
pub struct TokenSet(SyncSender<()>, Receiver<()>);
impl TokenSet {
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn new(size: usize) -> Self {
let (sender, receiver) = safina_sync::sync_channel(size);
for _ in 0..size {
sender.try_send(()).unwrap();
}
Self(sender, receiver)
}
#[allow(clippy::missing_panics_doc)]
pub async fn async_wait_token(&mut self) -> Token {
self.1.async_recv().await.unwrap();
Token(self.0.clone())
}
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn wait_token(&self) -> Token {
self.1.recv().unwrap();
Token(self.0.clone())
}
pub fn wait_token_timeout(&self, timeout: Duration) -> Result<Token, TimeOut> {
match self.1.recv_timeout(timeout) {
Ok(_) => Ok(Token(self.0.clone())),
Err(RecvTimeoutError::Timeout) => Err(TimeOut),
Err(RecvTimeoutError::Disconnected) => unreachable!(),
}
}
}