use std::{borrow::Cow,
pin::Pin,
sync::{Arc, Weak}
};
use super::{Error, AsyncMiddleware, AsyncPayload, AsyncIntoPayload, AsyncFromPayload};
macro_rules! impl_payload_smart_slice_traits {
($container:ident) => {
impl<C: Send + Sync, T: AsyncIntoPayload<C>> AsyncIntoPayload<C> for $container<T> {
#[inline]
async fn poll_into_payload<'m, M: AsyncMiddleware<'m>>(&self, ctx: &mut C, next: &mut M) -> Result<(), Error> {
next.poll_into_payload(self.as_ref(), ctx).await
}
}
impl<'a, C: Send + Sync, T: AsyncFromPayload<'a, C>> AsyncFromPayload<'a, C> for $container<T>
where T: ToOwned
{
#[inline]
async fn poll_from_payload<M: AsyncMiddleware<'a>>(ctx: &mut C, next: &mut M) -> Result<Self, Error> {
Ok($container::new(next.poll_from_payload::<C, T>(ctx).await?))
}
}
impl<'a, C: Send + Sync, T: AsyncPayload<'a, C>> AsyncPayload<'a, C> for $container<T>
where T: Clone {}
impl<C: Send + Sync, T: AsyncIntoPayload<C>> AsyncIntoPayload<C> for $container<[T]> {
#[inline]
async fn poll_into_payload<'m, M: AsyncMiddleware<'m>>(&self, ctx: &mut C, next: &mut M) -> Result<(), Error> {
next.poll_into_payload(&self.as_ref(), ctx).await
}
}
impl<'a, C: Send + Sync, T: AsyncFromPayload<'a, C>> AsyncFromPayload<'a, C> for $container<[T]>
where T: Clone + 'a
{
#[inline]
async fn poll_from_payload<M: AsyncMiddleware<'a>>(ctx: &mut C, next: &mut M) -> Result<Self, Error> {
Ok($container::from(next.poll_from_payload::<C, Cow<'a, [T]>>(ctx).await?.into_owned()))
}
}
impl<'a, C: Send + Sync, T: AsyncPayload<'a, C>> AsyncPayload<'a, C> for $container<[T]>
where T: Clone {}
};
}
impl_payload_smart_slice_traits!(Box);
impl_payload_smart_slice_traits!(Arc);
impl<C: Send + Sync, T: AsyncIntoPayload<C>> AsyncIntoPayload<C> for Pin<Box<T>> {
#[inline]
async fn poll_into_payload<'m, M: AsyncMiddleware<'m>>(&self, ctx: &mut C, next: &mut M) -> Result<(), Error> {
next.poll_into_payload(self.as_ref().get_ref(), ctx).await
}
}
impl<'a, C: Send + Sync, T: AsyncFromPayload<'a, C>> AsyncFromPayload<'a, C> for Pin<Box<T>> {
#[inline]
async fn poll_from_payload<M: AsyncMiddleware<'a>>(ctx: &mut C, next: &mut M) -> Result<Self, Error> {
Ok(Pin::from(Box::pin(next.poll_from_payload::<C, T>(ctx).await?)))
}
}
impl<'a, C: Send + Sync, T: AsyncPayload<'a, C>> AsyncPayload<'a, C> for Pin<Box<T>> {}
impl<C: Send + Sync, T: AsyncIntoPayload<C>> AsyncIntoPayload<C> for Weak<T> {
async fn poll_into_payload<'m, M: AsyncMiddleware<'m>>(&self, ctx: &mut C, next: &mut M) -> Result<(), Error> {
if let Some(strong) = self.upgrade() {
next.poll_into_payload(&strong, ctx).await
} else {
Err(Error::WeakUpgrade)
}
}
}
impl<'a, C: Send + Sync, T: AsyncFromPayload<'a, C> + Clone> AsyncFromPayload<'a, C> for Weak<T> {
#[inline]
async fn poll_from_payload<M: AsyncMiddleware<'a>>(ctx: &mut C, next: &mut M) -> Result<Self, Error> {
Ok(Arc::downgrade(&next.poll_from_payload::<C, Arc<T>>(ctx).await?))
}
}
impl<'a, C: Send + Sync, T: AsyncPayload<'a, C> + Clone> AsyncPayload<'a, C> for Weak<T> {}