flowly-core 0.6.0

Flowly is a library of modular and reusable components for building robust pipelines processing audio, video and other.
Documentation
use std::{
    error::Error,
    fmt,
    pin::Pin,
    task::{Context, Poll},
};

use futures::Stream;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Either<L, R = L> {
    Left(L),
    Right(R),
}

impl<L, R> Either<L, R> {
    #[inline]
    pub fn into_left(self) -> L {
        match self {
            Either::Left(left) => left,
            Either::Right(_) => unreachable!(),
        }
    }

    #[inline]
    pub fn into_right(self) -> R {
        match self {
            Either::Left(_) => unreachable!(),
            Either::Right(right) => right,
        }
    }
}

impl<T> Either<T, T> {
    #[inline]
    pub fn into_inner(self) -> T {
        match self {
            Either::Left(left) => left,
            Either::Right(right) => right,
        }
    }
}

impl<L: fmt::Display, R: fmt::Display> fmt::Display for Either<L, R> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Either::Left(l) => write!(f, "{l}"),
            Either::Right(r) => write!(f, "{r}"),
        }
    }
}

impl<L: Error, R: Error> Error for Either<L, R> {}
impl<I, L: Iterator<Item = I>, R: Iterator<Item = I>> Iterator for Either<L, R> {
    type Item = I;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Either::Left(l) => l.next(),
            Either::Right(r) => r.next(),
        }
    }
}

impl<I, L: Future<Output = I>, R: Future<Output = I>> Future for Either<L, R> {
    type Output = I;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        match unsafe { self.get_unchecked_mut() } {
            Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll(cx),
            Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll(cx),
        }
    }
}

impl<I, L: Stream<Item = I>, R: Stream<Item = I>> Stream for Either<L, R> {
    type Item = I;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        match unsafe { self.get_unchecked_mut() } {
            Either::Left(l) => unsafe { Pin::new_unchecked(l) }.poll_next(cx),
            Either::Right(r) => unsafe { Pin::new_unchecked(r) }.poll_next(cx),
        }
    }
}