use futures::sink::Sink; use pin_project_lite::pin_project; pin_project! { #[project = EitherSinkInner] pub enum EitherSink { A { #[pin] inner: A }, B { #[pin] inner: B } } } /// A simple enum that delegates implementation to one of /// the two possible sinks contained within. impl EitherSink { pub fn a(val: A) -> Self { EitherSink::A { inner: val } } pub fn b(val: B) -> Self { EitherSink::B { inner: val } } } impl Sink for EitherSink where A: Sink, B: Sink, { type Error = Error; fn poll_ready( self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { match self.project() { EitherSinkInner::A { inner } => inner.poll_ready(cx), EitherSinkInner::B { inner } => inner.poll_ready(cx), } } fn start_send(self: std::pin::Pin<&mut Self>, item: Item) -> Result<(), Self::Error> { match self.project() { EitherSinkInner::A { inner } => inner.start_send(item), EitherSinkInner::B { inner } => inner.start_send(item), } } fn poll_flush( self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { match self.project() { EitherSinkInner::A { inner } => inner.poll_flush(cx), EitherSinkInner::B { inner } => inner.poll_flush(cx), } } fn poll_close( self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll> { match self.project() { EitherSinkInner::A { inner } => inner.poll_close(cx), EitherSinkInner::B { inner } => inner.poll_close(cx), } } }