1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
use std::pin::Pin; /// A trait implemented for coroutines. /// /// A `Coroutine` is a generalization of a `Generator`. A `Generator` constrains /// the resume argument type to `()`, but in a `Coroutine` it can be anything. pub trait Coroutine { /// The type of value this generator yields. type Yield; /// The type of value this generator accepts as a resume argument. type Resume; /// The type of value this generator returns upon completion. type Return; /// Resumes the execution of this generator. /// /// The argument will be passed into the coroutine as a resume argument. fn resume_with( self: Pin<&mut Self>, arg: Self::Resume, ) -> GeneratorState<Self::Yield, Self::Return>; } /// A trait implemented for generator types. /// /// This is modeled after the stdlib's nightly-only [`std::ops::Generator`]. pub trait Generator { /// The type of value this generator yields. type Yield; /// The type of value this generator returns upon completion. type Return; /// Resumes the execution of this generator. fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return>; } impl<C: Coroutine<Resume = ()>> Generator for C { type Yield = <Self as Coroutine>::Yield; type Return = <Self as Coroutine>::Return; fn resume(self: Pin<&mut Self>) -> GeneratorState<Self::Yield, Self::Return> { self.resume_with(()) } } /// The result of a generator resumption. /// /// This is modeled after the stdlib's nightly-only /// [`std::ops::GeneratorState`]. #[derive(PartialEq, Debug)] #[allow(clippy::module_name_repetitions)] pub enum GeneratorState<Y, R> { /// The generator suspended with a value. Yielded(Y), /// The generator completed with a return value. Complete(R), }