jenner 0.2.0

Tools for working with generators to work with both iterators and streams
Documentation
use std::{ops::GeneratorState, pin::Pin};

use crate::{Finally, SyncGenerator};

#[doc(hidden)]
pub trait IntoSyncGenerator {
    type Yield;
    type Return;
    type SyncGenerator: SyncGenerator<Self::Yield, Self::Return>;
    fn into_sync_generator(self) -> Self::SyncGenerator;
}

impl<S> IntoSyncGenerator for S
where
    S: Iterator,
{
    type Yield = S::Item;
    type Return = ();
    type SyncGenerator = IterGenerator<Self>;

    fn into_sync_generator(self) -> Self::SyncGenerator {
        IterGenerator { iter: self }
    }
}

#[doc(hidden)]
pub struct IterGenerator<I> {
    iter: I,
}

impl<I> Unpin for IterGenerator<I> {}

impl<I> Iterator for IterGenerator<I>
where
    I: Iterator,
{
    type Item = I::Item;

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next()
    }
}

impl<I> Finally for IterGenerator<I>
where
    I: Iterator,
{
    type Output = ();
    fn finally(self) -> Self::Output {}
}

impl<S> SyncGenerator<S::Item, ()> for IterGenerator<S>
where
    S: Iterator,
{
    fn resume(mut self: Pin<&mut Self>) -> GeneratorState<S::Item, ()> {
        match self.iter.next() {
            Some(r) => GeneratorState::Yielded(r),
            None => GeneratorState::Complete(()),
        }
    }
}