#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
use core::pin::Pin;
#[cfg(any(feature = "futures-core", feature = "futures-sink"))]
use core::task::{Context, Poll};
#[cfg(feature = "futures-core")]
use futures_core::{FusedFuture, FusedStream, Future, Stream};
#[cfg(feature = "futures-sink")]
use futures_sink::Sink;
use pin_project::pin_project;
#[cfg(feature = "route-sink")]
use route_sink::{FlushRoute, ReadyRoute, ReadySome};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[pin_project]
pub struct WithExtra<T, Ex> {
#[pin]
inner: T,
extra: Ex,
}
impl<T, Ex> WithExtra<T, Ex> {
#[must_use]
pub const fn new(inner: T, extra: Ex) -> Self {
Self { inner, extra }
}
#[must_use]
pub fn into_inner(self) -> (T, Ex) {
(self.inner, self.extra)
}
#[must_use]
pub fn as_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
self.project().inner
}
}
impl<T, Ex> From<(T, Ex)> for WithExtra<T, Ex> {
fn from((inner, extra): (T, Ex)) -> Self {
Self::new(inner, extra)
}
}
impl<T, Ex> From<WithExtra<T, Ex>> for (T, Ex) {
fn from(value: WithExtra<T, Ex>) -> Self {
value.into_inner()
}
}
impl<T, Ex: Default> From<T> for WithExtra<T, Ex> {
fn from(inner: T) -> Self {
Self::new(inner, Ex::default())
}
}
impl<T, Ex> AsRef<T> for WithExtra<T, Ex> {
fn as_ref(&self) -> &T {
&self.inner
}
}
impl<T, Ex> AsMut<T> for WithExtra<T, Ex> {
fn as_mut(&mut self) -> &mut T {
&mut self.inner
}
}
#[cfg(feature = "futures-core")]
impl<T: Future, Ex> Future for WithExtra<T, Ex> {
type Output = T::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.project().inner.poll(cx)
}
}
#[cfg(feature = "futures-core")]
impl<T: FusedFuture, Ex> FusedFuture for WithExtra<T, Ex> {
fn is_terminated(&self) -> bool {
self.inner.is_terminated()
}
}
#[cfg(feature = "futures-core")]
impl<T: Stream, Ex> Stream for WithExtra<T, Ex> {
type Item = T::Item;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.project().inner.poll_next(cx)
}
}
#[cfg(feature = "futures-core")]
impl<T: FusedStream, Ex> FusedStream for WithExtra<T, Ex> {
fn is_terminated(&self) -> bool {
self.inner.is_terminated()
}
}
#[cfg(feature = "futures-sink")]
impl<Item, T: Sink<Item>, Ex> Sink<Item> for WithExtra<T, Ex> {
type Error = T::Error;
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_ready(cx)
}
fn start_send(self: Pin<&mut Self>, item: Item) -> Result<(), Self::Error> {
self.project().inner.start_send(item)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_close(cx)
}
}
#[cfg(feature = "route-sink")]
impl<Route, Msg, T: FlushRoute<Route, Msg>, Ex> FlushRoute<Route, Msg> for WithExtra<T, Ex> {
fn poll_flush_route(
self: Pin<&mut Self>,
route: &Route,
cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_flush_route(route, cx)
}
fn poll_close_route(
self: Pin<&mut Self>,
route: &Route,
cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_close_route(route, cx)
}
}
#[cfg(feature = "route-sink")]
impl<Route, Msg, T: ReadyRoute<Route, Msg>, Ex> ReadyRoute<Route, Msg> for WithExtra<T, Ex> {
fn poll_ready_route(
self: Pin<&mut Self>,
route: &Route,
cx: &mut Context<'_>,
) -> Poll<Result<(), Self::Error>> {
self.project().inner.poll_ready_route(route, cx)
}
}
#[cfg(feature = "route-sink")]
impl<Route, Msg, T: ReadySome<Route, Msg>, Ex> ReadySome<Route, Msg> for WithExtra<T, Ex> {
fn poll_ready_some(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Route, Self::Error>> {
self.project().inner.poll_ready_some(cx)
}
}