use crate::{shared::Shared, Message};
use std::sync::{atomic::Ordering, Arc};
#[derive(Debug)]
pub struct Sender<T> {
inner: Arc<Shared<T>>,
}
#[derive(Debug)]
pub struct SendError<T>(Option<T>);
impl<T> Sender<T> {
pub(crate) fn new(inner: Arc<Shared<T>>) -> Self {
Self { inner }
}
#[inline]
pub fn send(&self, keys: Vec<String>, value: T) -> Result<(), SendError<T>> {
if self.inner.recv_dropped() {
return Err(SendError(Some(value)));
}
let msg = Arc::new(Message::new(keys, value));
let _push_result = self.inner.queue.push(msg);
Ok(())
}
}
impl<T> Clone for Sender<T> {
#[inline]
fn clone(&self) -> Self {
let _ = self.inner.send_count.fetch_add(1, Ordering::SeqCst);
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl<T> Drop for Sender<T> {
#[inline]
fn drop(&mut self) {
let prev = self.inner.send_count.fetch_sub(1, Ordering::SeqCst);
if prev == 1 {
let _ = self.inner.condition_available.notify_all();
}
}
}