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>;
}