use crate::async_rx::*;
use crate::async_tx::*;
use crate::blocking_rx::*;
use crate::blocking_tx::*;
use crate::flavor::{
flavor_dispatch, flavor_select_dispatch, queue_dispatch, Flavor, FlavorBounded, FlavorImpl,
FlavorNew, FlavorWrap, Queue,
};
use crate::shared::*;
use crate::{NotCloneable, ReceiverType, SenderType};
use std::mem::MaybeUninit;
pub type List<T> = FlavorWrap<crate::flavor::List<T>, RegistryDummy, RegistrySingle>;
pub type One<T> = FlavorWrap<crate::flavor::OneSpsc<T>, RegistrySingle, RegistrySingle>;
#[allow(clippy::large_enum_variant)]
pub enum Array<T> {
Array(crate::flavor::ArraySpsc<T>),
One(crate::flavor::OneSpsc<T>),
}
impl<T> Array<T> {
#[inline]
pub fn new(size: usize) -> Self {
if size <= 1 {
Self::One(crate::flavor::OneSpsc::new())
} else {
Self::Array(crate::flavor::ArraySpsc::<T>::new(size))
}
}
}
macro_rules! wrap_array {
($self: expr, $method:ident $($arg:expr)*)=>{
match $self {
Self::Array(inner) => inner.$method($($arg)*),
Self::One(inner) => inner.$method($($arg)*),
}
};
}
impl<T> Queue for Array<T> {
type Item = T;
queue_dispatch!(wrap_array);
}
impl<T> FlavorImpl for Array<T> {
flavor_dispatch!(wrap_array);
}
impl<T> FlavorSelect for Array<T> {
flavor_select_dispatch!(wrap_array);
}
impl<T> FlavorBounded for Array<T> {
#[inline(always)]
fn new_with_bound(size: usize) -> Self {
Self::new(size)
}
}
impl<T: 'static> Flavor for Array<T> {
type Send = RegistrySingle;
type Recv = RegistrySingle;
}
#[inline(always)]
pub fn new<F, S, R>() -> (S, R)
where
F: Flavor + FlavorNew,
S: SenderType<Flavor = F> + NotCloneable,
R: ReceiverType<Flavor = F> + NotCloneable,
{
build::<F, S, R>(F::new())
}
#[inline(always)]
pub fn build<F, S, R>(flavor: F) -> (S, R)
where
F: Flavor,
S: SenderType<Flavor = F> + NotCloneable,
R: ReceiverType<Flavor = F> + NotCloneable,
{
let shared = ChannelShared::new(flavor, F::Send::new(), F::Recv::new());
(S::new(shared.clone()), R::new(shared))
}
#[inline]
fn unbounded_new<T, R>() -> (Tx<List<T>>, R)
where
T: Send + 'static,
R: ReceiverType<Flavor = List<T>> + NotCloneable,
{
build::<List<T>, Tx<List<T>>, R>(List::<T>::from_inner(crate::flavor::List::<T>::new()))
}
#[inline]
pub fn unbounded_blocking<T>() -> (Tx<List<T>>, Rx<List<T>>)
where
T: Send + 'static,
{
unbounded_new()
}
#[inline]
pub fn unbounded_async<T>() -> (Tx<List<T>>, AsyncRx<List<T>>)
where
T: Send + 'static,
{
unbounded_new()
}
fn bounded_new<T, S, R>(size: usize) -> (S, R)
where
T: Send + 'static,
S: SenderType<Flavor = Array<T>> + NotCloneable,
R: ReceiverType<Flavor = Array<T>> + NotCloneable,
{
build::<Array<T>, S, R>(Array::<T>::new(size))
}
#[inline]
pub fn bounded_blocking<T>(size: usize) -> (Tx<Array<T>>, Rx<Array<T>>)
where
T: Send + 'static,
{
bounded_new(size)
}
#[inline]
pub fn bounded_async<T>(size: usize) -> (AsyncTx<Array<T>>, AsyncRx<Array<T>>)
where
T: Send + 'static,
{
bounded_new(size)
}
#[inline]
pub fn bounded_blocking_async<T>(size: usize) -> (Tx<Array<T>>, AsyncRx<Array<T>>)
where
T: Send + 'static,
{
bounded_new(size)
}
#[inline]
pub fn bounded_async_blocking<T>(size: usize) -> (AsyncTx<Array<T>>, Rx<Array<T>>)
where
T: Send + 'static,
{
bounded_new(size)
}