use std::cell::Cell;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
use crate::queue::{Receiver, Sender};
#[derive(Debug, thiserror::Error)]
pub enum SenderError {
#[error("You can't send the value to a shard that doesn't exist.")]
WrongShard,
}
pub struct Shard<T> {
pub(crate) receiver: Cell<Option<Receiver<T>>>,
pub(crate) senders: Vec<Sender<T>>,
pub(crate) max_shard: Arc<AtomicUsize>,
#[allow(dead_code)]
pub(crate) shard_id: usize,
}
impl<T> Shard<T> {
pub fn receiver(&self) -> Option<Receiver<T>> {
self.receiver.take()
}
pub fn send_to(&self, val: T, shard: usize) -> Result<(), SenderError> {
let max_shard =
self.max_shard.load(std::sync::atomic::Ordering::Acquire);
if shard >= max_shard {
return Err(SenderError::WrongShard);
}
let sender = self
.senders
.get(shard)
.expect("the sender should have been here but he is not.");
sender.send(val);
Ok(())
}
pub fn send_to_unchecked(&self, val: T, shard: usize) {
let sender = self
.senders
.get(shard)
.expect("the sender should have been here but he is not.");
sender.send(val);
}
}