use core::marker::PhantomData;
use crate::{Collection, Signature};
pub struct TryPushSignature<T>(PhantomData<T>);
impl<T> Signature for TryPushSignature<T> {
type Error<'input, 'arm>
= T
where
Self: 'arm;
type Input<'a> = T;
type Output<'input, 'arm>
= ()
where
Self: 'arm;
}
pub struct PopSignature<T>(PhantomData<T>);
impl<T> Signature for PopSignature<T> {
type Error<'input, 'arm>
= ()
where
Self: 'arm;
type Input<'a> = ();
type Output<'input, 'arm>
= T
where
Self: 'arm;
}
pub struct Unit;
impl Signature for Unit {
type Error<'input, 'arm>
= ()
where
Self: 'arm;
type Input<'a> = ();
type Output<'input, 'arm>
= ()
where
Self: 'arm;
}
pub trait PushPopCollection {
type Item;
fn push(&self, item: Self::Item) -> Result<(), Self::Item>;
fn pop(&self) -> Option<Self::Item>;
fn len(&self) -> usize;
fn capacity(&self) -> usize;
#[inline]
fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl<Q> Collection for Q
where
Q: PushPopCollection,
{
type OfferSignature = TryPushSignature<Q::Item>;
type PollSignature = PopSignature<Q::Item>;
#[inline]
fn offer<'input, 'arm>(
&'arm self,
item: <Self::OfferSignature as Signature>::Input<'input>,
) -> Result<
<Self::OfferSignature as Signature>::Output<'input, 'arm>,
<Self::OfferSignature as Signature>::Error<'input, 'arm>,
> {
self.push(item)
}
#[inline]
fn poll<'input, 'arm>(
&'arm self,
_input: <Self::PollSignature as Signature>::Input<'input>,
) -> Result<
<Self::PollSignature as Signature>::Output<'input, 'arm>,
<Self::PollSignature as Signature>::Error<'input, 'arm>,
> {
self.pop().ok_or(())
}
#[inline]
fn len(&self) -> usize {
PushPopCollection::len(self)
}
#[inline]
fn capacity(&self) -> usize {
PushPopCollection::capacity(self)
}
#[inline]
fn is_empty(&self) -> bool {
PushPopCollection::is_empty(self)
}
}