use std::time::Duration;
use crate::error::{ReadyTimeoutError, RecvError, SelectTimeoutError, SendError, TrySelectError};
use crate::{Receiver, Sender};
pub struct Select<'a> {
select: crossbeam_channel::Select<'a>,
}
impl<'a> Default for Select<'a> {
fn default() -> Self {
Self::new()
}
}
impl<'a> Select<'a> {
pub fn new() -> Self {
let select = crossbeam_channel::Select::new();
Self { select }
}
pub fn new_biased() -> Self {
let select = crossbeam_channel::Select::new_biased();
Self { select }
}
pub fn send<T>(&mut self, sender: &'a Sender<T>) -> usize {
self.select.send(&sender.tx)
}
pub fn recv<T>(&mut self, receiver: &'a Receiver<T>) -> usize {
self.select.recv(&receiver.rx)
}
pub fn select(&mut self) -> SelectedOperation<'a> {
self.select.select().into()
}
pub fn try_select(&mut self) -> Result<SelectedOperation<'a>, TrySelectError> {
Ok(SelectedOperation::from(self.select.try_select()?))
}
pub fn select_timeout(
&mut self,
timeout: Duration,
) -> Result<SelectedOperation<'a>, SelectTimeoutError> {
Ok(SelectedOperation::from(
self.select.select_timeout(timeout)?,
))
}
pub fn ready(&mut self) -> usize {
self.select.ready()
}
pub fn ready_timeout(&mut self, timeout: Duration) -> Result<usize, ReadyTimeoutError> {
Ok(self.select.ready_timeout(timeout)?)
}
pub fn remove(&mut self, index: usize) {
self.select.remove(index);
}
}
pub struct SelectedOperation<'a>(crossbeam_channel::SelectedOperation<'a>);
impl<'a> From<crossbeam_channel::SelectedOperation<'a>> for SelectedOperation<'a> {
fn from(value: crossbeam_channel::SelectedOperation<'a>) -> Self {
Self(value)
}
}
impl<'a> SelectedOperation<'a> {
pub fn index(&self) -> usize {
self.0.index()
}
pub fn send<T>(self, sender: &'a Sender<T>, msg: T) -> Result<(), SendError<T>> {
let res = self.0.send(&sender.tx, msg);
if res.is_ok() {
sender.signal_recv();
}
Ok(res?)
}
pub fn recv<T>(self, receiver: &'a Receiver<T>) -> Result<T, RecvError> {
let res = self.0.recv(&receiver.rx);
if res.is_ok() {
receiver.signal_send();
}
Ok(res?)
}
}