use core::ops::Deref;
use core::mem::drop;
use alloc::vec::Vec;
use crate::fifo::BlockSize;
use super::subscription::Subscribers;
use super::non_blocking::{Producer, Consumer};
use super::future::{RecvOne, RecvArray, FillMany, FillExact};
pub struct Sender<T> {
producer: Option<Producer<T>>,
subscribers: Subscribers,
}
impl<T> Clone for Sender<T> {
fn clone(&self) -> Self {
Self {
producer: self.producer.clone(),
subscribers: self.subscribers.clone(),
}
}
}
impl<T> Sender<T> {
#[doc(hidden)]
pub fn send_iter_2<I>(&self, into_iter: I) -> usize
where
I: IntoIterator,
I::IntoIter: ExactSizeIterator<Item = T>,
{
let producer = self.producer.as_ref();
producer.unwrap().send_iter(into_iter);
self.subscribers.notify_all()
}
pub fn send_iter<I>(&self, into_iter: I)
where
I: IntoIterator,
I::IntoIter: ExactSizeIterator<Item = T>,
{
self.send_iter_2(into_iter);
}
pub fn send(&self, item: T) {
self.send_iter_2(core::iter::once(item));
}
}
impl<T> Drop for Sender<T> {
fn drop(&mut self) {
drop(self.producer.take());
self.subscribers.notify_all();
}
}
#[derive(Clone)]
pub struct Receiver<T> {
consumer: Consumer<T>,
subscribers: Subscribers,
pub(super) last_wake_count: Option<usize>,
}
impl<T> Deref for Receiver<T> {
type Target = Consumer<T>;
fn deref(&self) -> &Consumer<T> {
&self.consumer
}
}
impl<T> Receiver<T> {
pub(super) fn subscribers(&self) -> &Subscribers {
&self.subscribers
}
}
impl<T: Unpin> Receiver<T> {
pub fn no_senders(&self) -> bool {
self.consumer.no_producers()
}
pub fn recv(&mut self) -> RecvOne<'_, T> {
self.into_recv()
}
pub fn recv_many<'a>(&'a mut self, vec: &'a mut Vec<T>) -> FillMany<'a, T> {
self.into_fill(vec)
}
pub fn recv_exact<'a>(&'a mut self, slice: &'a mut [T]) -> FillExact<'a, T> {
self.into_fill(slice)
}
pub fn recv_array<const N: usize>(&mut self) -> RecvArray<'_, N, T> {
self.into_recv()
}
}
impl<const L: usize, const F: usize> BlockSize<L, F> {
pub fn channel<T: 'static>() -> (Sender<T>, Receiver<T>) {
let (producer, consumer) = Self::non_blocking();
let subscribers = Subscribers::default();
let sender = Sender {
producer: Some(producer),
subscribers: subscribers.clone(),
};
let receiver = Receiver {
consumer,
last_wake_count: None,
subscribers: subscribers.clone(),
};
(sender, receiver)
}
}