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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#[cfg(not(feature = "nightly"))]
use std::pin::Pin;
#[cfg(not(feature = "nightly"))]
use crate::GeneratorState;
#[cfg(feature = "nightly")]
#[doc(inline)]
pub use std::ops::Generator;
#[cfg(not(feature = "nightly"))]
/// Stable version of `std::generator::Generator`
///
/// The trait implemented by builtin generator types.
///
/// Generators, also commonly referred to as coroutines, are currently an
/// experimental language feature in Rust. Added in [RFC 2033] generators are
/// currently intended to primarily provide a building block for async/await
/// syntax but will likely extend to also providing an ergonomic definition for
/// iterators and other primitives.
///
/// The syntax and semantics for generators is unstable and will require a
/// further RFC for stabilization. At this time, though, the syntax is
/// closure-like:
///
/// ```rust
/// #![feature(generators, generator_trait)]
///
/// use std::ops::{Generator, GeneratorState};
/// use std::pin::Pin;
///
/// fn main() {
/// let mut generator = || {
/// yield 1;
/// return "foo"
/// };
///
/// match Pin::new(&mut generator).resume(()) {
/// GeneratorState::Yielded(1) => {}
/// _ => panic!("unexpected return from resume"),
/// }
/// match Pin::new(&mut generator).resume(()) {
/// GeneratorState::Complete("foo") => {}
/// _ => panic!("unexpected return from resume"),
/// }
/// }
/// ```
///
/// More documentation of generators can be found in the unstable book.
///
/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
pub trait Generator<R = ()> {
/// The type of value this generator yields.
///
/// This associated type corresponds to the `yield` expression and the
/// values which are allowed to be returned each time a generator yields.
/// For example an iterator-as-a-generator would likely have this type as
/// `T`, the type being iterated over.
type Yield;
/// The type of value this generator returns.
///
/// This corresponds to the type returned from a generator either with a
/// `return` statement or implicitly as the last expression of a generator
/// literal. For example futures would use this as `Result<T, E>` as it
/// represents a completed future.
type Return;
/// Resumes the execution of this generator.
///
/// This function will resume execution of the generator or start execution
/// if it hasn't already. This call will return back into the generator's
/// last suspension point, resuming execution from the latest `yield`. The
/// generator will continue executing until it either yields or returns, at
/// which point this function will return.
///
/// # Return value
///
/// The `GeneratorState` enum returned from this function indicates what
/// state the generator is in upon returning. If the `Yielded` variant is
/// returned then the generator has reached a suspension point and a value
/// has been yielded out. Generators in this state are available for
/// resumption at a later point.
///
/// If `Complete` is returned then the generator has completely finished
/// with the value provided. It is invalid for the generator to be resumed
/// again.
///
/// # Panics
///
/// This function may panic if it is called after the `Complete` variant has
/// been returned previously. While generator literals in the language are
/// guaranteed to panic on resuming after `Complete`, this is not guaranteed
/// for all implementations of the `Generator` trait.
fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
}